diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 1228 |
1 files changed, 778 insertions, 450 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c694a20..2c5516a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -33,7 +33,6 @@ #include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering. #include "clang/Lex/ModuleLoader.h" // TODO: Sema shouldn't depend on Lex #include "clang/Lex/Preprocessor.h" // Included for isCodeCompletionEnabled() -#include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/DelayedDiagnostic.h" @@ -111,6 +110,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { case tok::kw_wchar_t: case tok::kw_bool: case tok::kw___underlying_type: + case tok::kw___auto_type: return true; case tok::annot_typename: @@ -795,7 +795,7 @@ Corrected: } // In C, we first see whether there is a tag type by the same name, in - // which case it's likely that the user just forget to write "enum", + // which case it's likely that the user just forgot to write "enum", // "struct", or "union". if (!getLangOpts().CPlusPlus && !SecondTry && isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { @@ -813,9 +813,8 @@ Corrected: unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; - NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); - NamedDecl *UnderlyingFirstDecl - = FirstDecl? FirstDecl->getUnderlyingDecl() : nullptr; + NamedDecl *FirstDecl = Corrected.getFoundDecl(); + NamedDecl *UnderlyingFirstDecl = Corrected.getCorrectionDecl(); if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) { UnqualifiedDiag = diag::err_no_template_suggest; @@ -1022,7 +1021,7 @@ Corrected: if (FirstDecl->isCXXClassMember()) return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, - nullptr); + nullptr, S); bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); return BuildDeclarationNameExpr(SS, Result, ADL); @@ -1089,7 +1088,9 @@ Sema::SkippedDefinitionContext Sema::ActOnTagStartSkippedDefinition(Scope *S, auto Result = static_cast<SkippedDefinitionContext>(CurContext); CurContext = cast<TagDecl>(D)->getDefinition(); assert(CurContext && "skipping definition of undefined tag"); - S->setEntity(CurContext); + // Start lookups from the parent of the current context; we don't want to look + // into the pre-existing complete definition. + S->setEntity(CurContext->getLookupParent()); return Result; } @@ -1733,20 +1734,18 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, if (Error) { if (ForRedeclaration) Diag(Loc, diag::warn_implicit_decl_requires_sysheader) - << getHeaderName(Error) - << Context.BuiltinInfo.GetName(ID); + << getHeaderName(Error) << Context.BuiltinInfo.getName(ID); return nullptr; } if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(ID)) { Diag(Loc, diag::ext_implicit_lib_function_decl) - << Context.BuiltinInfo.GetName(ID) - << R; + << Context.BuiltinInfo.getName(ID) << R; if (Context.BuiltinInfo.getHeaderName(ID) && !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc)) Diag(Loc, diag::note_include_header_or_declare) << Context.BuiltinInfo.getHeaderName(ID) - << Context.BuiltinInfo.GetName(ID); + << Context.BuiltinInfo.getName(ID); } DeclContext *Parent = Context.getTranslationUnitDecl(); @@ -1796,37 +1795,6 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, return New; } -/// \brief Filter out any previous declarations that the given declaration -/// should not consider because they are not permitted to conflict, e.g., -/// because they come from hidden sub-modules and do not refer to the same -/// entity. -static void filterNonConflictingPreviousDecls(Sema &S, - NamedDecl *decl, - LookupResult &previous){ - // This is only interesting when modules are enabled. - if ((!S.getLangOpts().Modules && !S.getLangOpts().ModulesLocalVisibility) || - !S.getLangOpts().ModulesHideInternalLinkage) - return; - - // Empty sets are uninteresting. - if (previous.empty()) - return; - - LookupResult::Filter filter = previous.makeFilter(); - while (filter.hasNext()) { - NamedDecl *old = filter.next(); - - // Non-hidden declarations are never ignored. - if (S.isVisible(old)) - continue; - - if (!old->isExternallyVisible()) - filter.erase(); - } - - filter.done(); -} - /// Typedef declarations don't have linkage, but they still denote the same /// entity if their types are the same. /// FIXME: This is notionally doing the same thing as ASTReaderDecl's @@ -1859,13 +1827,13 @@ static void filterNonConflictingPreviousTypedefDecls(Sema &S, // If both declarations give a tag declaration a typedef name for linkage // purposes, then they declare the same entity. - if (OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) && + if (S.getLangOpts().CPlusPlus && + OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) && Decl->getAnonDeclWithTypedefName()) continue; } - if (!Old->isExternallyVisible()) - Filter.erase(); + Filter.erase(); } Filter.done(); @@ -1910,7 +1878,8 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) { /// how to resolve this situation, merging decls or emitting /// diagnostics as appropriate. If there was an error, set New to be invalid. /// -void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { +void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, + LookupResult &OldDecls) { // If the new decl is known invalid already, don't bother doing any // merging checks. if (New->isInvalidDecl()) return; @@ -1991,6 +1960,19 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { // Make the old tag definition visible. makeMergedDefinitionVisible(Hidden, NewTag->getLocation()); + + // If this was an unscoped enumeration, yank all of its enumerators + // out of the scope. + if (isa<EnumDecl>(NewTag)) { + Scope *EnumScope = getNonFieldDeclScope(S); + for (auto *D : NewTag->decls()) { + auto *ED = cast<EnumConstantDecl>(D); + assert(EnumScope->isDeclScope(ED)); + EnumScope->RemoveDecl(ED); + IdResolver.RemoveDecl(ED); + ED->getLexicalDeclContext()->removeDecl(ED); + } + } } } @@ -2206,14 +2188,15 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { } static bool mergeDeclAttribute(Sema &S, NamedDecl *D, - const InheritableAttr *Attr, bool Override) { + const InheritableAttr *Attr, + Sema::AvailabilityMergeKind AMK) { InheritableAttr *NewAttr = nullptr; unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr)) NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(), AA->getUnavailable(), - AA->getMessage(), Override, + AA->getMessage(), AMK, AttrSpellingListIndex); else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), @@ -2246,11 +2229,22 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.mergeMinSizeAttr(D, MA->getRange(), AttrSpellingListIndex); else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr)) NewAttr = S.mergeOptimizeNoneAttr(D, OA->getRange(), AttrSpellingListIndex); + else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr)) + NewAttr = S.mergeInternalLinkageAttr( + D, InternalLinkageA->getRange(), + &S.Context.Idents.get(InternalLinkageA->getSpelling()), + AttrSpellingListIndex); + else if (const auto *CommonA = dyn_cast<CommonAttr>(Attr)) + NewAttr = S.mergeCommonAttr(D, CommonA->getRange(), + &S.Context.Idents.get(CommonA->getSpelling()), + AttrSpellingListIndex); else if (isa<AlignedAttr>(Attr)) // AlignedAttrs are handled separately, because we need to handle all // such attributes on a declaration at the same time. NewAttr = nullptr; - else if (isa<DeprecatedAttr>(Attr) && Override) + else if ((isa<DeprecatedAttr>(Attr) || isa<UnavailableAttr>(Attr)) && + (AMK == Sema::AMK_Override || + AMK == Sema::AMK_ProtocolImplementation)) NewAttr = nullptr; else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); @@ -2303,9 +2297,17 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { const Attr *NewAttribute = NewAttributes[I]; if (isa<AliasAttr>(NewAttribute)) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) - S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def)); - else { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) { + Sema::SkipBodyInfo SkipBody; + S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def), &SkipBody); + + // If we're skipping this definition, drop the "alias" attribute. + if (SkipBody.ShouldSkip) { + NewAttributes.erase(NewAttributes.begin() + I); + --E; + continue; + } + } else { VarDecl *VD = cast<VarDecl>(New); unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition() == VarDecl::TentativeDefinition @@ -2376,9 +2378,24 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (!Old->hasAttrs() && !New->hasAttrs()) return; - // attributes declared post-definition are currently ignored + // Attributes declared post-definition are currently ignored. checkNewAttributesAfterDef(*this, New, Old); + if (AsmLabelAttr *NewA = New->getAttr<AsmLabelAttr>()) { + if (AsmLabelAttr *OldA = Old->getAttr<AsmLabelAttr>()) { + if (OldA->getLabel() != NewA->getLabel()) { + // This redeclaration changes __asm__ label. + Diag(New->getLocation(), diag::err_different_asm_label); + Diag(OldA->getLocation(), diag::note_previous_declaration); + } + } else if (Old->isUsed()) { + // This redeclaration adds an __asm__ label to a declaration that has + // already been ODR-used. + Diag(New->getLocation(), diag::err_late_asm_label_name) + << isa<FunctionDecl>(Old) << New->getAttr<AsmLabelAttr>()->getRange(); + } + } + if (!Old->hasAttrs()) return; @@ -2389,8 +2406,8 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (!foundAny) New->setAttrs(AttrVec()); for (auto *I : Old->specific_attrs<InheritableAttr>()) { - bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. + AvailabilityMergeKind LocalAMK = AMK_None; if (isa<DeprecatedAttr>(I) || isa<UnavailableAttr>(I) || isa<AvailabilityAttr>(I)) { @@ -2399,10 +2416,9 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, continue; case AMK_Redeclaration: - break; - case AMK_Override: - Override = true; + case AMK_ProtocolImplementation: + LocalAMK = AMK; break; } } @@ -2411,7 +2427,7 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (isa<UsedAttr>(I)) continue; - if (mergeDeclAttribute(*this, New, I, Override)) + if (mergeDeclAttribute(*this, New, I, LocalAMK)) foundAny = true; } @@ -2619,6 +2635,21 @@ static bool checkUsingShadowRedecl(Sema &S, UsingShadowDecl *OldS, return false; } +static bool hasIdenticalPassObjectSizeAttrs(const FunctionDecl *A, + const FunctionDecl *B) { + assert(A->getNumParams() == B->getNumParams()); + + auto AttrEq = [](const ParmVarDecl *A, const ParmVarDecl *B) { + const auto *AttrA = A->getAttr<PassObjectSizeAttr>(); + const auto *AttrB = B->getAttr<PassObjectSizeAttr>(); + if (AttrA == AttrB) + return true; + return AttrA && AttrB && AttrA->getType() == AttrB->getType(); + }; + + return std::equal(A->param_begin(), A->param_end(), B->param_begin(), AttrEq); +} + /// MergeFunctionDecl - We just parsed a function 'New' from /// declarator D which has the same name and scope as a previous /// declaration 'Old'. Figure out how to resolve this situation, @@ -2685,6 +2716,13 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, } } + if (New->hasAttr<InternalLinkageAttr>() && + !Old->hasAttr<InternalLinkageAttr>()) { + Diag(New->getLocation(), diag::err_internal_linkage_redeclaration) + << New->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_definition); + New->dropAttr<InternalLinkageAttr>(); + } // If a function is first declared with a calling convention, but is later // declared or defined without one, all following decls assume the calling @@ -2790,7 +2828,17 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Old->isInlined() && !Old->hasAttr<GNUInlineAttr>()) { UndefinedButUsed.erase(Old->getCanonicalDecl()); } - + + // If pass_object_size params don't match up perfectly, this isn't a valid + // redeclaration. + if (Old->getNumParams() > 0 && Old->getNumParams() == New->getNumParams() && + !hasIdenticalPassObjectSizeAttrs(Old, New)) { + Diag(New->getLocation(), diag::err_different_pass_object_size_params) + << New->getDeclName(); + Diag(OldLocation, PrevDiag) << Old << Old->getType(); + return true; + } + if (getLangOpts().CPlusPlus) { // (C++98 13.1p2): // Certain function declarations cannot be overloaded: @@ -3115,7 +3163,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, // remain visible, a single bogus local redeclaration (which is // actually only a warning) could break all the downstream code. if (!New->getLexicalDeclContext()->isFunctionOrMethod()) - New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); + New->getIdentifier()->revertBuiltin(); return false; } @@ -3179,8 +3227,11 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, // Merge the attributes, including deprecated/unavailable AvailabilityMergeKind MergeKind = - isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration - : AMK_Override; + isa<ObjCProtocolDecl>(oldMethod->getDeclContext()) + ? AMK_ProtocolImplementation + : isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration + : AMK_Override; + mergeDeclAttributes(newMethod, oldMethod, MergeKind); // Merge attributes from the parameters. @@ -3331,6 +3382,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (New->isInvalidDecl()) return; + if (!shouldLinkPossiblyHiddenDecl(Previous, New)) + return; + VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate(); // Verify the old decl was also a variable or variable template. @@ -3362,15 +3416,12 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { return New->setInvalidDecl(); } - if (!shouldLinkPossiblyHiddenDecl(Old, New)) - return; - // Ensure the template parameters are compatible. if (NewTemplate && !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), /*Complain=*/true, TPL_TemplateMatch)) - return; + return New->setInvalidDecl(); // C++ [class.mem]p1: // A member shall not be declared twice in the member-specification [...] @@ -3395,6 +3446,14 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { New->dropAttr<WeakImportAttr>(); } + if (New->hasAttr<InternalLinkageAttr>() && + !Old->hasAttr<InternalLinkageAttr>()) { + Diag(New->getLocation(), diag::err_internal_linkage_redeclaration) + << New->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_definition); + New->dropAttr<InternalLinkageAttr>(); + } + // Merge the types. VarDecl *MostRecent = Old->getMostRecentDecl(); if (MostRecent != Old) { @@ -3583,11 +3642,11 @@ void Sema::handleTagNumbering(const TagDecl *Tag, Scope *TagScope) { void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, TypedefNameDecl *NewTD) { - // Do nothing if the tag is not anonymous or already has an - // associated typedef (from an earlier typedef in this decl group). - if (TagFromDeclSpec->getIdentifier()) + if (TagFromDeclSpec->isInvalidDecl()) return; - if (TagFromDeclSpec->getTypedefNameForAnonDecl()) + + // Do nothing if the tag already has a name for linkage purposes. + if (TagFromDeclSpec->hasNameForLinkage()) return; // A well-formed anonymous tag must always be a TUK_Definition. @@ -3595,8 +3654,11 @@ void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, // The type must match the tag exactly; no qualifiers allowed. if (!Context.hasSameType(NewTD->getUnderlyingType(), - Context.getTagDeclType(TagFromDeclSpec))) + Context.getTagDeclType(TagFromDeclSpec))) { + if (getLangOpts().CPlusPlus) + Context.addTypedefNameForUnnamedTagDecl(TagFromDeclSpec, NewTD); return; + } // If we've already computed linkage for the anonymous tag, then // adding a typedef name for the anonymous decl can change that @@ -3695,6 +3757,14 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return TagD; } + if (DS.isConceptSpecified()) { + // C++ Concepts TS [dcl.spec.concept]p1: A concept definition refers to + // either a function concept and its definition or a variable concept and + // its initializer. + Diag(DS.getConceptSpecLoc(), diag::err_concept_wrong_decl_kind); + return TagD; + } + DiagnoseFunctionSpecifiers(DS); if (DS.isFriendSpecified()) { @@ -3709,10 +3779,15 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, bool IsExplicitSpecialization = !TemplateParams.empty() && TemplateParams.back()->size() == 0; if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && - !IsExplicitInstantiation && !IsExplicitSpecialization) { + !IsExplicitInstantiation && !IsExplicitSpecialization && + !isa<ClassTemplatePartialSpecializationDecl>(Tag)) { // Per C++ [dcl.type.elab]p1, a class declaration cannot have a // nested-name-specifier unless it is an explicit instantiation // or an explicit specialization. + // + // FIXME: We allow class template partial specializations here too, per the + // obvious intent of DR1819. + // // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either. Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange(); @@ -3882,7 +3957,7 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef, DeclContext *Owner, DeclarationName Name, SourceLocation NameLoc, - unsigned diagnostic) { + bool IsUnion) { LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName, Sema::ForRedeclaration); if (!SemaRef.LookupName(R, S)) return false; @@ -3897,7 +3972,8 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef, if (!SemaRef.isDeclInScope(PrevDecl, Owner, S)) return false; - SemaRef.Diag(NameLoc, diagnostic) << Name; + SemaRef.Diag(NameLoc, diag::err_anonymous_record_member_redecl) + << IsUnion << Name; SemaRef.Diag(PrevDecl->getLocation(), diag::note_previous_declaration); return true; @@ -3925,10 +4001,6 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, AccessSpecifier AS, SmallVectorImpl<NamedDecl *> &Chaining, bool MSAnonStruct) { - unsigned diagKind - = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl - : diag::err_anonymous_struct_member_redecl; - bool Invalid = false; // Look every FieldDecl and IndirectFieldDecl with a name. @@ -3937,7 +4009,8 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, cast<NamedDecl>(D)->getDeclName()) { ValueDecl *VD = cast<ValueDecl>(D); if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, VD->getDeclName(), - VD->getLocation(), diagKind)) { + VD->getLocation(), + AnonRecord->isUnion())) { // C++ [class.union]p2: // The names of the members of an anonymous union shall be // distinct from the names of any other entity in the @@ -4131,7 +4204,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, assert(FD->getAccess() != AS_none); if (FD->getAccess() != AS_public) { Diag(FD->getLocation(), diag::err_anonymous_record_nonpublic_member) - << (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected); + << Record->isUnion() << (FD->getAccess() == AS_protected); Invalid = true; } @@ -4155,11 +4228,11 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // Visual C++ allows type definition in anonymous struct or union. if (getLangOpts().MicrosoftExt) Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type) - << (int)Record->isUnion(); + << Record->isUnion(); else { // This is a nested type declaration. Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type) - << (int)Record->isUnion(); + << Record->isUnion(); Invalid = true; } } else { @@ -4168,7 +4241,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // not part of standard C++. Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_anonymous_type) - << (int)Record->isUnion(); + << Record->isUnion(); } } else if (isa<AccessSpecDecl>(Mem)) { // Any access specifier is fine. @@ -4189,10 +4262,9 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (getLangOpts().MicrosoftExt && DK == diag::err_anonymous_record_with_type) Diag(Mem->getLocation(), diag::ext_anonymous_record_with_type) - << (int)Record->isUnion(); + << Record->isUnion(); else { - Diag(Mem->getLocation(), DK) - << (int)Record->isUnion(); + Diag(Mem->getLocation(), DK) << Record->isUnion(); Invalid = true; } } @@ -4209,7 +4281,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (!Record->isUnion() && !Owner->isRecord()) { Diag(Record->getLocation(), diag::err_anonymous_struct_not_member) - << (int)getLangOpts().CPlusPlus; + << getLangOpts().CPlusPlus; Invalid = true; } @@ -4885,6 +4957,23 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (getLangOpts().CPlusPlus) CheckExtraCXXDefaultArguments(D); + if (D.getDeclSpec().isConceptSpecified()) { + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template or variable + // template, declared in namespace scope + if (!TemplateParamLists.size()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag:: err_concept_wrong_decl_kind); + return nullptr; + } + + if (!DC->getRedeclContext()->isFileContext()) { + Diag(D.getIdentifierLoc(), + diag::err_concept_decls_may_only_appear_in_namespace_scope); + return nullptr; + } + } + NamedDecl *New; bool AddToScope = true; @@ -5102,6 +5191,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (D.getDeclSpec().isConstexprSpecified()) Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) << 1; + if (D.getDeclSpec().isConceptSpecified()) + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_concept_wrong_decl_kind); if (D.getName().Kind != UnqualifiedId::IK_Identifier) { Diag(D.getName().StartLocation, diag::err_typedef_not_identifier) @@ -5174,7 +5266,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD, filterNonConflictingPreviousTypedefDecls(*this, NewTD, Previous); if (!Previous.empty()) { Redeclaration = true; - MergeTypedefNameDecl(NewTD, Previous); + MergeTypedefNameDecl(S, NewTD, Previous); } // If this is the C FILE type, notify the AST context. @@ -5343,14 +5435,26 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { } } - // dll attributes require external linkage. if (const InheritableAttr *Attr = getDLLAttr(&ND)) { - if (!ND.isExternallyVisible()) { + // dll attributes require external linkage. Static locals may have external + // linkage but still cannot be explicitly imported or exported. + auto *VD = dyn_cast<VarDecl>(&ND); + if (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())) { S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern) << &ND << Attr; ND.setInvalidDecl(); } } + + // Virtual functions cannot be marked as 'notail'. + if (auto *Attr = ND.getAttr<NotTailCalledAttr>()) + if (auto *MD = dyn_cast<CXXMethodDecl>(&ND)) + if (MD->isVirtual()) { + S.Diag(ND.getLocation(), + diag::err_invalid_attribute_on_virtual_function) + << Attr; + ND.dropAttr<NotTailCalledAttr>(); + } } static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, @@ -5501,6 +5605,12 @@ static bool isIncompleteDeclExternC(Sema &S, const T *D) { // In C++, the overloadable attribute negates the effects of extern "C". if (!D->isInExternCContext() || D->template hasAttr<OverloadableAttr>()) return false; + + // So do CUDA's host/device attributes if overloading is enabled. + if (S.getLangOpts().CUDA && S.getLangOpts().CUDATargetOverloads && + (D->template hasAttr<CUDADeviceAttr>() || + D->template hasAttr<CUDAHostAttr>())) + return false; } return D->isExternC(); } @@ -5574,15 +5684,12 @@ bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) { return true; } -/// \brief Returns true if given declaration is TU-scoped and externally -/// visible. -static bool isDeclTUScopedExternallyVisible(const Decl *D) { - if (auto *FD = dyn_cast<FunctionDecl>(D)) - return (FD->getDeclContext()->isTranslationUnit() || FD->isExternC()) && - FD->hasExternalFormalLinkage(); - else if (auto *VD = dyn_cast<VarDecl>(D)) - return (VD->getDeclContext()->isTranslationUnit() || VD->isExternC()) && - VD->hasExternalFormalLinkage(); +/// \brief Returns true if given declaration has external C language linkage. +static bool isDeclExternC(const Decl *D) { + if (const auto *FD = dyn_cast<FunctionDecl>(D)) + return FD->isExternC(); + if (const auto *VD = dyn_cast<VarDecl>(D)) + return VD->isExternC(); llvm_unreachable("Unknown type of decl!"); } @@ -5646,7 +5753,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Suppress the warning in system macros, it's used in macros in some // popular C system headers, such as in glibc's htonl() macro. Diag(D.getDeclSpec().getStorageClassSpecLoc(), - diag::warn_deprecated_register) + getLangOpts().CPlusPlus1z ? diag::ext_register_storage_class + : diag::warn_deprecated_register) << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); } @@ -5670,12 +5778,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (getLangOpts().OpenCL) { - // Set up the special work-group-local storage class for variables in the - // OpenCL __local address space. - if (R.getAddressSpace() == LangAS::opencl_local) { - SC = SC_OpenCLWorkGroupLocal; - } - // OpenCL v1.2 s6.9.b p4: // The sampler type cannot be used with the __local and __global address // space qualifiers. @@ -5712,7 +5814,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, R, TInfo, SC); - + + if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType()) + ParsingInitForAutoVars.insert(NewVD); + if (D.isInvalidType()) NewVD->setInvalidDecl(); } else { @@ -5742,8 +5847,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, break; case SC_PrivateExtern: llvm_unreachable("C storage class in c++!"); - case SC_OpenCLWorkGroupLocal: - llvm_unreachable("OpenCL storage class in c++!"); } } @@ -5860,11 +5963,31 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, unsigned VDTemplateParamLists = TemplateParams ? 1 : 0; if (TemplateParamLists.size() > VDTemplateParamLists) NewVD->setTemplateParameterListsInfo( - Context, TemplateParamLists.size() - VDTemplateParamLists, - TemplateParamLists.data()); + Context, TemplateParamLists.drop_back(VDTemplateParamLists)); if (D.getDeclSpec().isConstexprSpecified()) NewVD->setConstexpr(true); + + if (D.getDeclSpec().isConceptSpecified()) { + NewVD->setConcept(true); + + // C++ Concepts TS [dcl.spec.concept]p2: A concept definition shall not + // be declared with the thread_local, inline, friend, or constexpr + // specifiers, [...] + if (D.getDeclSpec().getThreadStorageClassSpec() == TSCS_thread_local) { + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_concept_decl_invalid_specifiers) + << 0 << 0; + NewVD->setInvalidDecl(true); + } + + if (D.getDeclSpec().isConstexprSpecified()) { + Diag(D.getDeclSpec().getConstexprSpecLoc(), + diag::err_concept_decl_invalid_specifiers) + << 0 << 3; + NewVD->setInvalidDecl(true); + } + } } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -5990,19 +6113,31 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, break; case SC_Register: // Local Named register - if (!Context.getTargetInfo().isValidGCCRegisterName(Label)) + if (!Context.getTargetInfo().isValidGCCRegisterName(Label) && + DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl())) Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label; break; case SC_Static: case SC_Extern: case SC_PrivateExtern: - case SC_OpenCLWorkGroupLocal: break; } } else if (SC == SC_Register) { // Global Named register - if (!Context.getTargetInfo().isValidGCCRegisterName(Label)) - Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label; + if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) { + const auto &TI = Context.getTargetInfo(); + bool HasSizeMismatch; + + if (!TI.isValidGCCRegisterName(Label)) + Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label; + else if (!TI.validateGlobalRegisterVariable(Label, + Context.getTypeSize(R), + HasSizeMismatch)) + Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label; + else if (HasSizeMismatch) + Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label; + } + if (!R->isIntegralType(Context) && !R->isPointerType()) { Diag(D.getLocStart(), diag::err_asm_bad_register_type); NewVD->setInvalidDecl(true); @@ -6011,13 +6146,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context, Label, 0)); - } else if (!ExtnameUndeclaredIdentifiers.empty() && - isDeclTUScopedExternallyVisible(NewVD)) { + } else if (!ExtnameUndeclaredIdentifiers.empty()) { llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier()); if (I != ExtnameUndeclaredIdentifiers.end()) { - NewVD->addAttr(I->second); - ExtnameUndeclaredIdentifiers.erase(I); + if (isDeclExternC(NewVD)) { + NewVD->addAttr(I->second); + ExtnameUndeclaredIdentifiers.erase(I); + } else + Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied) + << /*Variable*/1 << NewVD; } } @@ -6118,6 +6256,22 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + // Special handling of variable named 'main'. + if (Name.isIdentifier() && Name.getAsIdentifierInfo()->isStr("main") && + NewVD->getDeclContext()->getRedeclContext()->isTranslationUnit() && + !getLangOpts().Freestanding && !NewVD->getDescribedVarTemplate()) { + + // C++ [basic.start.main]p3 + // A program that declares a variable main at global scope is ill-formed. + if (getLangOpts().CPlusPlus) + Diag(D.getLocStart(), diag::err_main_global_variable); + + // In C, and external-linkage variable named main results in undefined + // behavior. + else if (NewVD->hasExternalFormalLinkage()) + Diag(D.getLocStart(), diag::warn_main_redefined); + } + if (D.isRedeclaration() && !Previous.empty()) { checkDLLAttributeRedeclaration( *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD, @@ -6370,31 +6524,79 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { // This includes arrays of objects with address space qualifiers, but not // automatic variables that point to other address spaces. // ISO/IEC TR 18037 S5.1.2 - if (NewVD->hasLocalStorage() && T.getAddressSpace() != 0) { + if (!getLangOpts().OpenCL + && NewVD->hasLocalStorage() && T.getAddressSpace() != 0) { Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl); NewVD->setInvalidDecl(); return; } - // OpenCL v1.2 s6.5 - All program scope variables must be declared in the - // __constant address space. - if (getLangOpts().OpenCL && NewVD->isFileVarDecl() - && T.getAddressSpace() != LangAS::opencl_constant - && !T->isSamplerT()){ - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space); - NewVD->setInvalidDecl(); - return; - } - // OpenCL v1.2 s6.8 -- The static qualifier is valid only in program // scope. - if ((getLangOpts().OpenCLVersion >= 120) - && NewVD->isStaticLocal()) { + if (getLangOpts().OpenCLVersion == 120 && + !getOpenCLOptions().cl_clang_storage_class_specifiers && + NewVD->isStaticLocal()) { Diag(NewVD->getLocation(), diag::err_static_function_scope); NewVD->setInvalidDecl(); return; } + // OpenCL v1.2 s6.5 - All program scope variables must be declared in the + // __constant address space. + // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // variables inside a function can also be declared in the global + // address space. + if (getLangOpts().OpenCL) { + if (NewVD->isFileVarDecl()) { + if (!T->isSamplerT() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "global or constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "constant"; + NewVD->setInvalidDecl(); + return; + } + } else { + // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // variables inside a function can also be declared in the global + // address space. + if (NewVD->isStaticLocal() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "global or constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "constant"; + NewVD->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.2 and s6.5.3 no local or constant variables + // in functions. + if (T.getAddressSpace() == LangAS::opencl_constant || + T.getAddressSpace() == LangAS::opencl_local) { + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && !FD->hasAttr<OpenCLKernelAttr>()) { + if (T.getAddressSpace() == LangAS::opencl_constant) + Diag(NewVD->getLocation(), diag::err_opencl_non_kernel_variable) + << "constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_non_kernel_variable) + << "local"; + NewVD->setInvalidDecl(); + return; + } + } + } + } + if (NewVD->hasLocalStorage() && T.isObjCGCWeak() && !NewVD->hasAttr<BlocksAttr>()) { if (getLangOpts().getGC() != LangOptions::NonGC) @@ -6506,9 +6708,6 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { checkForConflictWithNonVisibleExternC(*this, NewVD, Previous)) Previous.setShadowed(); - // Filter out any non-conflicting previous declarations. - filterNonConflictingPreviousDecls(*this, NewVD, Previous); - if (!Previous.empty()) { MergeVarDecl(NewVD, Previous); return true; @@ -6516,50 +6715,45 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { return false; } -/// \brief Data used with FindOverriddenMethod -struct FindOverriddenMethodData { +namespace { +struct FindOverriddenMethod { Sema *S; CXXMethodDecl *Method; -}; -/// \brief Member lookup function that determines whether a given C++ -/// method overrides a method in a base class, to be used with -/// CXXRecordDecl::lookupInBases(). -static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - void *UserData) { - RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl(); + /// Member lookup function that determines whether a given C++ + /// method overrides a method in a base class, to be used with + /// CXXRecordDecl::lookupInBases(). + bool operator()(const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + RecordDecl *BaseRecord = + Specifier->getType()->getAs<RecordType>()->getDecl(); - FindOverriddenMethodData *Data - = reinterpret_cast<FindOverriddenMethodData*>(UserData); - - DeclarationName Name = Data->Method->getDeclName(); - - // FIXME: Do we care about other names here too? - if (Name.getNameKind() == DeclarationName::CXXDestructorName) { - // We really want to find the base class destructor here. - QualType T = Data->S->Context.getTypeDeclType(BaseRecord); - CanQualType CT = Data->S->Context.getCanonicalType(T); - - Name = Data->S->Context.DeclarationNames.getCXXDestructorName(CT); - } - - for (Path.Decls = BaseRecord->lookup(Name); - !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - NamedDecl *D = Path.Decls.front(); - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, false)) - return true; + DeclarationName Name = Method->getDeclName(); + + // FIXME: Do we care about other names here too? + if (Name.getNameKind() == DeclarationName::CXXDestructorName) { + // We really want to find the base class destructor here. + QualType T = S->Context.getTypeDeclType(BaseRecord); + CanQualType CT = S->Context.getCanonicalType(T); + + Name = S->Context.DeclarationNames.getCXXDestructorName(CT); } + + for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); + Path.Decls = Path.Decls.slice(1)) { + NamedDecl *D = Path.Decls.front(); + if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + if (MD->isVirtual() && !S->IsOverload(Method, MD, false)) + return true; + } + } + + return false; } - - return false; -} +}; + +enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted }; +} // end anonymous namespace -namespace { - enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted }; -} /// \brief Report an error regarding overriding, along with any relevant /// overriden methods. /// @@ -6587,13 +6781,13 @@ static void ReportOverrides(Sema& S, unsigned DiagID, const CXXMethodDecl *MD, bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { // Look for methods in base classes that this method might override. CXXBasePaths Paths; - FindOverriddenMethodData Data; - Data.Method = MD; - Data.S = this; + FindOverriddenMethod FOM; + FOM.Method = MD; + FOM.S = this; bool hasDeletedOverridenMethods = false; bool hasNonDeletedOverridenMethods = false; bool AddedAny = false; - if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) { + if (DC->lookupInBases(FOM, Paths)) { for (auto *I : Paths.found_decls()) { if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(I)) { MD->addOverriddenMethod(OldMD->getCanonicalDecl()); @@ -7200,7 +7394,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << DeclSpec::getSpecifierName(TSCS); if (D.isFirstDeclarationOfMember()) - adjustMemberFunctionCC(R, D.isStaticMember()); + adjustMemberFunctionCC(R, D.isStaticMember(), D.isCtorOrDtor(), + D.getIdentifierLoc()); bool isFriend = false; FunctionTemplateDecl *FunctionTemplate = nullptr; @@ -7236,6 +7431,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool isVirtual = D.getDeclSpec().isVirtualSpecified(); bool isExplicit = D.getDeclSpec().isExplicitSpecified(); bool isConstexpr = D.getDeclSpec().isConstexprSpecified(); + bool isConcept = D.getDeclSpec().isConceptSpecified(); isFriend = D.getDeclSpec().isFriendSpecified(); if (isFriend && !isInline && D.isFunctionDefinition()) { // C++ [class.friend]p5 @@ -7309,17 +7505,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // For source fidelity, store the other template param lists. if (TemplateParamLists.size() > 1) { NewFD->setTemplateParameterListsInfo(Context, - TemplateParamLists.size() - 1, - TemplateParamLists.data()); + TemplateParamLists.drop_back(1)); } } else { // This is a function template specialization. isFunctionTemplateSpecialization = true; // For source fidelity, store all the template param lists. if (TemplateParamLists.size() > 0) - NewFD->setTemplateParameterListsInfo(Context, - TemplateParamLists.size(), - TemplateParamLists.data()); + NewFD->setTemplateParameterListsInfo(Context, TemplateParamLists); // C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);". if (isFriend) { @@ -7349,9 +7542,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // this is NOT (an explicit specialization of) a template. if (TemplateParamLists.size() > 0) // For source fidelity, store all the template param lists. - NewFD->setTemplateParameterListsInfo(Context, - TemplateParamLists.size(), - TemplateParamLists.data()); + NewFD->setTemplateParameterListsInfo(Context, TemplateParamLists); } if (Invalid) { @@ -7452,6 +7643,67 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor); } + if (isConcept) { + // C++ Concepts TS [dcl.spec.concept]p1: The concept specifier shall be + // applied only to the definition of a function template [...] + if (!D.isFunctionDefinition()) { + Diag(D.getDeclSpec().getConceptSpecLoc(), + diag::err_function_concept_not_defined); + NewFD->setInvalidDecl(); + } + + // C++ Concepts TS [dcl.spec.concept]p1: [...] A function concept shall + // have no exception-specification and is treated as if it were specified + // with noexcept(true) (15.4). [...] + if (const FunctionProtoType *FPT = R->getAs<FunctionProtoType>()) { + if (FPT->hasExceptionSpec()) { + SourceRange Range; + if (D.isFunctionDeclarator()) + Range = D.getFunctionTypeInfo().getExceptionSpecRange(); + Diag(NewFD->getLocation(), diag::err_function_concept_exception_spec) + << FixItHint::CreateRemoval(Range); + NewFD->setInvalidDecl(); + } else { + Context.adjustExceptionSpec(NewFD, EST_BasicNoexcept); + } + + // C++ Concepts TS [dcl.spec.concept]p5: A function concept has the + // following restrictions: + // - The declaration's parameter list shall be equivalent to an empty + // parameter list. + if (FPT->getNumParams() > 0 || FPT->isVariadic()) + Diag(NewFD->getLocation(), diag::err_function_concept_with_params); + } + + // C++ Concepts TS [dcl.spec.concept]p2: Every concept definition is + // implicity defined to be a constexpr declaration (implicitly inline) + NewFD->setImplicitlyInline(); + + // C++ Concepts TS [dcl.spec.concept]p2: A concept definition shall not + // be declared with the thread_local, inline, friend, or constexpr + // specifiers, [...] + if (isInline) { + Diag(D.getDeclSpec().getInlineSpecLoc(), + diag::err_concept_decl_invalid_specifiers) + << 1 << 1; + NewFD->setInvalidDecl(true); + } + + if (isFriend) { + Diag(D.getDeclSpec().getFriendSpecLoc(), + diag::err_concept_decl_invalid_specifiers) + << 1 << 2; + NewFD->setInvalidDecl(true); + } + + if (isConstexpr) { + Diag(D.getDeclSpec().getConstexprSpecLoc(), + diag::err_concept_decl_invalid_specifiers) + << 1 << 3; + NewFD->setInvalidDecl(true); + } + } + // If __module_private__ was specified, mark the function accordingly. if (D.getDeclSpec().isModulePrivateSpecified()) { if (isFunctionTemplateSpecialization) { @@ -7539,13 +7791,16 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, StringLiteral *SE = cast<StringLiteral>(E); NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context, SE->getString(), 0)); - } else if (!ExtnameUndeclaredIdentifiers.empty() && - isDeclTUScopedExternallyVisible(NewFD)) { + } else if (!ExtnameUndeclaredIdentifiers.empty()) { llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier()); if (I != ExtnameUndeclaredIdentifiers.end()) { - NewFD->addAttr(I->second); - ExtnameUndeclaredIdentifiers.erase(I); + if (isDeclExternC(NewFD)) { + NewFD->addAttr(I->second); + ExtnameUndeclaredIdentifiers.erase(I); + } else + Diag(NewFD->getLocation(), diag::warn_redefine_extname_not_applied) + << /*Variable*/0 << NewFD; } } @@ -8061,9 +8316,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, bool MergeTypeWithPrevious = !getLangOpts().CPlusPlus && !Previous.isShadowed(); - // Filter out any non-conflicting previous declarations. - filterNonConflictingPreviousDecls(*this, NewFD, Previous); - bool Redeclaration = false; NamedDecl *OldDecl = nullptr; @@ -8075,7 +8327,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // there's no more work to do here; we'll just add the new // function to the scope. if (!AllowOverloadingOfFunction(Previous, Context)) { - NamedDecl *Candidate = Previous.getFoundDecl(); + NamedDecl *Candidate = Previous.getRepresentativeDecl(); if (shouldLinkPossiblyHiddenDecl(Candidate, NewFD)) { Redeclaration = true; OldDecl = Candidate; @@ -8117,7 +8369,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // Check for a previous extern "C" declaration with this name. if (!Redeclaration && checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) { - filterNonConflictingPreviousDecls(*this, NewFD, Previous); if (!Previous.empty()) { // This is an extern "C" declaration with the same name as a previous // declaration, and thus redeclares that entity... @@ -8294,7 +8545,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (!T.isNull() && !Context.hasSameType(T, NewFD->getType())) { // The type of this function differs from the type of the builtin, // so forget about the builtin entirely. - Context.BuiltinInfo.ForgetBuiltin(BuiltinID, Context.Idents); + Context.BuiltinInfo.forgetBuiltin(BuiltinID, Context.Idents); } } @@ -8577,9 +8828,8 @@ namespace { // Convert FieldDecls to their index number. llvm::SmallVector<unsigned, 4> UsedFieldIndex; - for (auto I = Fields.rbegin(), E = Fields.rend(); I != E; ++I) { - UsedFieldIndex.push_back((*I)->getFieldIndex()); - } + for (const FieldDecl *I : llvm::reverse(Fields)) + UsedFieldIndex.push_back(I->getFieldIndex()); // See if a warning is needed by checking the first difference in index // numbers. If field being used has index less than the field being @@ -8832,6 +9082,96 @@ namespace { } } +QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, + DeclarationName Name, QualType Type, + TypeSourceInfo *TSI, + SourceRange Range, bool DirectInit, + Expr *Init) { + bool IsInitCapture = !VDecl; + assert((!VDecl || !VDecl->isInitCapture()) && + "init captures are expected to be deduced prior to initialization"); + + ArrayRef<Expr *> DeduceInits = Init; + if (DirectInit) { + if (auto *PL = dyn_cast<ParenListExpr>(Init)) + DeduceInits = PL->exprs(); + else if (auto *IL = dyn_cast<InitListExpr>(Init)) + DeduceInits = IL->inits(); + } + + // Deduction only works if we have exactly one source expression. + if (DeduceInits.empty()) { + // It isn't possible to write this directly, but it is possible to + // end up in this situation with "auto x(some_pack...);" + Diag(Init->getLocStart(), IsInitCapture + ? diag::err_init_capture_no_expression + : diag::err_auto_var_init_no_expression) + << Name << Type << Range; + return QualType(); + } + + if (DeduceInits.size() > 1) { + Diag(DeduceInits[1]->getLocStart(), + IsInitCapture ? diag::err_init_capture_multiple_expressions + : diag::err_auto_var_init_multiple_expressions) + << Name << Type << Range; + return QualType(); + } + + Expr *DeduceInit = DeduceInits[0]; + if (DirectInit && isa<InitListExpr>(DeduceInit)) { + Diag(Init->getLocStart(), IsInitCapture + ? diag::err_init_capture_paren_braces + : diag::err_auto_var_init_paren_braces) + << isa<InitListExpr>(Init) << Name << Type << Range; + return QualType(); + } + + // Expressions default to 'id' when we're in a debugger. + bool DefaultedAnyToId = false; + if (getLangOpts().DebuggerCastResultToId && + Init->getType() == Context.UnknownAnyTy && !IsInitCapture) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + return QualType(); + } + Init = Result.get(); + DefaultedAnyToId = true; + } + + QualType DeducedType; + if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) { + if (!IsInitCapture) + DiagnoseAutoDeductionFailure(VDecl, DeduceInit); + else if (isa<InitListExpr>(Init)) + Diag(Range.getBegin(), + diag::err_init_capture_deduction_failure_from_init_list) + << Name + << (DeduceInit->getType().isNull() ? TSI->getType() + : DeduceInit->getType()) + << DeduceInit->getSourceRange(); + else + Diag(Range.getBegin(), diag::err_init_capture_deduction_failure) + << Name << TSI->getType() + << (DeduceInit->getType().isNull() ? TSI->getType() + : DeduceInit->getType()) + << DeduceInit->getSourceRange(); + } + + // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using + // 'id' instead of a specific object type prevents most of our usual + // checks. + // We only want to warn outside of template instantiations, though: + // inside a template, the 'id' could have come from a parameter. + if (ActiveTemplateInstantiations.empty() && !DefaultedAnyToId && + !IsInitCapture && !DeducedType.isNull() && DeducedType->isObjCIdType()) { + SourceLocation Loc = TSI->getTypeLoc().getBeginLoc(); + Diag(Loc, diag::warn_auto_var_is_id) << Name << Range; + } + + return DeducedType; +} + /// AddInitializerToDecl - Adds the initializer Init to the /// declaration dcl. If DirectInit is true, this is C++ direct /// initialization rather than copy initialization. @@ -8859,79 +9199,27 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, RealDecl->setInvalidDecl(); return; } - ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) { // Attempt typo correction early so that the type of the init expression can - // be deduced based on the chosen correction:if the original init contains a + // be deduced based on the chosen correction if the original init contains a // TypoExpr. ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl); if (!Res.isUsable()) { RealDecl->setInvalidDecl(); return; } + Init = Res.get(); - if (Res.get() != Init) { - Init = Res.get(); - if (CXXDirectInit) - CXXDirectInit = dyn_cast<ParenListExpr>(Init); - } - - Expr *DeduceInit = Init; - // Initializer could be a C++ direct-initializer. Deduction only works if it - // contains exactly one expression. - if (CXXDirectInit) { - if (CXXDirectInit->getNumExprs() == 0) { - // It isn't possible to write this directly, but it is possible to - // end up in this situation with "auto x(some_pack...);" - Diag(CXXDirectInit->getLocStart(), - VDecl->isInitCapture() ? diag::err_init_capture_no_expression - : diag::err_auto_var_init_no_expression) - << VDecl->getDeclName() << VDecl->getType() - << VDecl->getSourceRange(); - RealDecl->setInvalidDecl(); - return; - } else if (CXXDirectInit->getNumExprs() > 1) { - Diag(CXXDirectInit->getExpr(1)->getLocStart(), - VDecl->isInitCapture() - ? diag::err_init_capture_multiple_expressions - : diag::err_auto_var_init_multiple_expressions) - << VDecl->getDeclName() << VDecl->getType() - << VDecl->getSourceRange(); - RealDecl->setInvalidDecl(); - return; - } else { - DeduceInit = CXXDirectInit->getExpr(0); - if (isa<InitListExpr>(DeduceInit)) - Diag(CXXDirectInit->getLocStart(), - diag::err_auto_var_init_paren_braces) - << VDecl->getDeclName() << VDecl->getType() - << VDecl->getSourceRange(); - } - } - - // Expressions default to 'id' when we're in a debugger. - bool DefaultedToAuto = false; - if (getLangOpts().DebuggerCastResultToId && - Init->getType() == Context.UnknownAnyTy) { - ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); - if (Result.isInvalid()) { - VDecl->setInvalidDecl(); - return; - } - Init = Result.get(); - DefaultedToAuto = true; - } - - QualType DeducedType; - if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) == - DAR_Failed) - DiagnoseAutoDeductionFailure(VDecl, DeduceInit); + QualType DeducedType = deduceVarTypeFromInitializer( + VDecl, VDecl->getDeclName(), VDecl->getType(), + VDecl->getTypeSourceInfo(), VDecl->getSourceRange(), DirectInit, Init); if (DeducedType.isNull()) { RealDecl->setInvalidDecl(); return; } + VDecl->setType(DeducedType); assert(VDecl->isLinkageValid()); @@ -8939,38 +9227,18 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) VDecl->setInvalidDecl(); - // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using - // 'id' instead of a specific object type prevents most of our usual checks. - // We only want to warn outside of template instantiations, though: - // inside a template, the 'id' could have come from a parameter. - if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto && - DeducedType->isObjCIdType()) { - SourceLocation Loc = - VDecl->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); - Diag(Loc, diag::warn_auto_var_is_id) - << VDecl->getDeclName() << DeduceInit->getSourceRange(); - } - // If this is a redeclaration, check that the type we just deduced matches // the previously declared type. if (VarDecl *Old = VDecl->getPreviousDecl()) { // We never need to merge the type, because we cannot form an incomplete // array of auto, nor deduce such a type. - MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/false); + MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false); } // Check the deduced type is valid for a variable declaration. CheckVariableDeclarationType(VDecl); if (VDecl->isInvalidDecl()) return; - - // If all looks well, warn if this is a case that will change meaning when - // we implement N3922. - if (DirectInit && !CXXDirectInit && isa<InitListExpr>(Init)) { - Diag(Init->getLocStart(), - diag::warn_auto_var_direct_list_init) - << FixItHint::CreateInsertion(Init->getLocStart(), "="); - } } // dllimport cannot be used on variable definitions. @@ -9059,7 +9327,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // OpenCL 1.1 6.5.2: "Variables allocated in the __local address space inside // a kernel function cannot be initialized." - if (VDecl->getStorageClass() == SC_OpenCLWorkGroupLocal) { + if (VDecl->getType().getAddressSpace() == LangAS::opencl_local) { Diag(VDecl->getLocation(), diag::err_local_cant_init); VDecl->setInvalidDecl(); return; @@ -9082,17 +9350,18 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } // Perform the initialization. + ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); if (!VDecl->isInvalidDecl()) { InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); - InitializationKind Kind - = DirectInit ? - CXXDirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(), - Init->getLocStart(), - Init->getLocEnd()) - : InitializationKind::CreateDirectList( - VDecl->getLocation()) - : InitializationKind::CreateCopy(VDecl->getLocation(), - Init->getLocStart()); + InitializationKind Kind = + DirectInit + ? CXXDirectInit + ? InitializationKind::CreateDirect(VDecl->getLocation(), + Init->getLocStart(), + Init->getLocEnd()) + : InitializationKind::CreateDirectList(VDecl->getLocation()) + : InitializationKind::CreateCopy(VDecl->getLocation(), + Init->getLocStart()); MultiExprArg Args = Init; if (CXXDirectInit) @@ -9156,7 +9425,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Init->getLocStart())) - getCurFunction()->markSafeWeakUse(Init); + getCurFunction()->markSafeWeakUse(Init); } // The initialization is usually a full-expression. @@ -9409,6 +9678,15 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } + // C++ Concepts TS [dcl.spec.concept]p1: [...] A variable template + // definition having the concept specifier is called a variable concept. A + // concept definition refers to [...] a variable concept and its initializer. + if (Var->isConcept()) { + Diag(Var->getLocation(), diag::err_var_concept_not_initialized); + Var->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.3: variables declared in the constant address space must // be initialized. if (!Var->isInvalidDecl() && @@ -9621,8 +9899,6 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { case SC_Register: Error = 4; break; - case SC_OpenCLWorkGroupLocal: - llvm_unreachable("Unexpected storage class"); } if (Error != -1) { Diag(VD->getOuterLocStart(), diag::err_for_range_storage_class) @@ -9665,9 +9941,9 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { if (var->isInvalidDecl()) return; - // In ARC, don't allow jumps past the implicit initialization of a + // In Objective-C, don't allow jumps past the implicit initialization of a // local retaining variable. - if (getLangOpts().ObjCAutoRefCount && + if (getLangOpts().ObjC1 && var->hasLocalStorage()) { switch (var->getType().getObjCLifetime()) { case Qualifiers::OCL_None: @@ -9913,9 +10189,17 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { // dllimport/dllexport variables cannot be thread local, their TLS index // isn't exported with the variable. if (DLLAttr && VD->getTLSKind()) { - Diag(VD->getLocation(), diag::err_attribute_dll_thread_local) << VD - << DLLAttr; - VD->setInvalidDecl(); + auto *F = dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod()); + if (F && getDLLAttr(F)) { + assert(VD->isStaticLocal()); + // But if this is a static local in a dlimport/dllexport function, the + // function will never be inlined, which means the var would never be + // imported, so having it marked import/export is safe. + } else { + Diag(VD->getLocation(), diag::err_attribute_dll_thread_local) << VD + << DLLAttr; + VD->setInvalidDecl(); + } } if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) { @@ -9988,8 +10272,9 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) { handleTagNumbering(Tag, S); - if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) - Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); + if (FirstDeclaratorInGroup && !Tag->hasNameForLinkage() && + getLangOpts().CPlusPlus) + Context.addDeclaratorForUnnamedTagDecl(Tag, FirstDeclaratorInGroup); } } @@ -10028,7 +10313,7 @@ Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group, } else if (DeducedCanon != UCanon) { Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(), diag::err_auto_different_deductions) - << (AT->isDecltypeAuto() ? 1 : 0) + << (unsigned)AT->getKeyword() << Deduced << DeducedDecl->getDeclName() << U << D->getDeclName() << DeducedDecl->getInit()->getSourceRange() @@ -10118,6 +10403,8 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { if (DS.isConstexprSpecified()) Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr) << 0; + if (DS.isConceptSpecified()) + Diag(DS.getConceptSpecLoc(), diag::err_concept_wrong_decl_kind); DiagnoseFunctionSpecifiers(DS); @@ -10370,14 +10657,17 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, } } -Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { +Decl * +Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D, + MultiTemplateParamsArg TemplateParameterLists, + SkipBodyInfo *SkipBody) { assert(getCurFunctionDecl() == nullptr && "Function parsing confused"); assert(D.isFunctionDeclarator() && "Not a function declarator!"); Scope *ParentScope = FnBodyScope->getParent(); D.setFunctionDefinitionKind(FDK_Definition); - Decl *DP = HandleDeclarator(ParentScope, D, MultiTemplateParamsArg()); - return ActOnStartOfFunctionDef(FnBodyScope, DP); + Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists); + return ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody); } void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) { @@ -10441,7 +10731,8 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, void Sema::CheckForFunctionRedefinition(FunctionDecl *FD, - const FunctionDecl *EffectiveDefinition) { + const FunctionDecl *EffectiveDefinition, + SkipBodyInfo *SkipBody) { // Don't complain if we're in GNU89 mode and the previous definition // was an extern inline function. const FunctionDecl *Definition = EffectiveDefinition; @@ -10453,17 +10744,20 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, return; // If we don't have a visible definition of the function, and it's inline or - // a template, it's OK to form another definition of it. - // - // FIXME: Should we skip the body of the function and use the old definition - // in this case? That may be necessary for functions that return local types - // through a deduced return type, or instantiate templates with local types. - if (!hasVisibleDefinition(Definition) && + // a template, skip the new definition. + if (SkipBody && !hasVisibleDefinition(Definition) && (Definition->getFormalLinkage() == InternalLinkage || Definition->isInlined() || Definition->getDescribedFunctionTemplate() || - Definition->getNumTemplateParameterLists())) + Definition->getNumTemplateParameterLists())) { + SkipBody->ShouldSkip = true; + if (auto *TD = Definition->getDescribedFunctionTemplate()) + makeMergedDefinitionVisible(TD, FD->getLocation()); + else + makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition), + FD->getLocation()); return; + } if (getLangOpts().GNUMode && Definition->isInlineSpecified() && Definition->getStorageClass() == SC_Extern) @@ -10524,7 +10818,8 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, } } -Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { +Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, + SkipBodyInfo *SkipBody) { // Clear the last template instantiation error context. LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation(); @@ -10536,6 +10831,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { FD = FunTmpl->getTemplatedDecl(); else FD = cast<FunctionDecl>(D); + + // See if this is a redefinition. + if (!FD->isLateTemplateParsed()) { + CheckForFunctionRedefinition(FD, nullptr, SkipBody); + + // If we're skipping the body, we're done. Don't enter the scope. + if (SkipBody && SkipBody->ShouldSkip) + return D; + } + // If we are instantiating a generic lambda call operator, push // a LambdaScopeInfo onto the function stack. But use the information // that's already been calculated (ActOnLambdaExpr) to prime the current @@ -10555,10 +10860,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // Enter a new function scope PushFunctionScope(); - // See if this is a redefinition. - if (!FD->isLateTemplateParsed()) - CheckForFunctionRedefinition(FD); - // Builtin functions cannot be defined. if (unsigned BuiltinID = FD->getBuiltinID()) { if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) && @@ -10734,6 +11035,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr; + if (getLangOpts().Coroutines && !getCurFunction()->CoroutineStmts.empty()) + CheckCompletedCoroutineBody(FD, Body); + if (FD) { FD->setBody(Body); @@ -11073,7 +11377,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, - /*ESpecLoc=*/NoLoc, + /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, @@ -11159,6 +11463,18 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation())); if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr<ConstAttr>()) FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); + if (getLangOpts().CUDA && getLangOpts().CUDATargetOverloads && + Context.BuiltinInfo.isTSBuiltin(BuiltinID) && + !FD->hasAttr<CUDADeviceAttr>() && !FD->hasAttr<CUDAHostAttr>()) { + // Assign appropriate attribute depending on CUDA compilation + // mode and the target builtin belongs to. E.g. during host + // compilation, aux builtins are __device__, the rest are __host__. + if (getLangOpts().CUDAIsDevice != + Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) + FD->addAttr(CUDADeviceAttr::CreateImplicit(Context, FD->getLocation())); + else + FD->addAttr(CUDAHostAttr::CreateImplicit(Context, FD->getLocation())); + } } IdentifierInfo *Name = FD->getIdentifier(); @@ -11269,9 +11585,9 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) { /// Check whether this is a valid redeclaration of a previous enumeration. /// \return true if the redeclaration was invalid. -bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, - QualType EnumUnderlyingTy, - const EnumDecl *Prev) { +bool Sema::CheckEnumRedeclaration( + SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy, + bool EnumUnderlyingIsImplicit, const EnumDecl *Prev) { bool IsFixed = !EnumUnderlyingTy.isNull(); if (IsScoped != Prev->isScoped()) { @@ -11293,6 +11609,10 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, << Prev->getIntegerTypeRange(); return true; } + } else if (IsFixed && !Prev->isFixed() && EnumUnderlyingIsImplicit) { + ; + } else if (!IsFixed && Prev->isFixed() && !Prev->getIntegerTypeSourceInfo()) { + ; } else if (IsFixed != Prev->isFixed()) { Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch) << Prev->isFixed(); @@ -11459,7 +11779,6 @@ static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S, std::reverse(Namespaces.begin(), Namespaces.end()); for (auto *II : Namespaces) OS << II->getName() << "::"; - OS.flush(); return FixItHint::CreateInsertion(NameLoc, Insertion); } @@ -11563,6 +11882,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // this early, because it's needed to detect if this is an incompatible // redeclaration. llvm::PointerUnion<const Type*, TypeSourceInfo*> EnumUnderlying; + bool EnumUnderlyingIsImplicit = false; if (Kind == TTK_Enum) { if (UnderlyingType.isInvalid() || (!UnderlyingType.get() && ScopedEnum)) @@ -11584,9 +11904,13 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, UPPC_FixedUnderlyingType)) EnumUnderlying = Context.IntTy.getTypePtr(); - } else if (getLangOpts().MSVCCompat) - // Microsoft enums are always of int type. - EnumUnderlying = Context.IntTy.getTypePtr(); + } else if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { + if (getLangOpts().MSVCCompat || TUK == TUK_Definition) { + // Microsoft enums are always of int type. + EnumUnderlying = Context.IntTy.getTypePtr(); + EnumUnderlyingIsImplicit = true; + } + } } DeclContext *SearchDC = CurContext; @@ -11816,9 +12140,16 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // In C++, we need to do a redeclaration lookup to properly // diagnose some problems. + // FIXME: redeclaration lookup is also used (with and without C++) to find a + // hidden declaration so that we don't get ambiguity errors when using a + // type declared by an elaborated-type-specifier. In C that is not correct + // and we should instead merge compatible types found by lookup. if (getLangOpts().CPlusPlus) { Previous.setRedeclarationKind(ForRedeclaration); LookupQualifiedName(Previous, SearchDC); + } else { + Previous.setRedeclarationKind(ForRedeclaration); + LookupName(Previous, S); } } @@ -11932,7 +12263,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // returning the previous declaration, unless this is a definition, // in which case we want the caller to bail out. if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc, - ScopedEnum, EnumUnderlyingTy, PrevEnum)) + ScopedEnum, EnumUnderlyingTy, + EnumUnderlyingIsImplicit, PrevEnum)) return TUK == TUK_Declaration ? PrevTagDecl : nullptr; } @@ -12203,9 +12535,7 @@ CreateNewDecl: New->setQualifierInfo(SS.getWithLocInContext(Context)); if (TemplateParameterLists.size() > 0) { - New->setTemplateParameterListsInfo(Context, - TemplateParameterLists.size(), - TemplateParameterLists.data()); + New->setTemplateParameterListsInfo(Context, TemplateParameterLists); } } else @@ -12504,26 +12834,41 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, } if (!FieldTy->isDependentType()) { - uint64_t TypeSize = Context.getTypeSize(FieldTy); - if (Value.getZExtValue() > TypeSize) { - if (!getLangOpts().CPlusPlus || IsMsStruct || - Context.getTargetInfo().getCXXABI().isMicrosoft()) { - if (FieldName) - return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) - << FieldName << (unsigned)Value.getZExtValue() - << (unsigned)TypeSize; - - return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size) - << (unsigned)Value.getZExtValue() << (unsigned)TypeSize; - } - + uint64_t TypeStorageSize = Context.getTypeSize(FieldTy); + uint64_t TypeWidth = Context.getIntWidth(FieldTy); + bool BitfieldIsOverwide = Value.ugt(TypeWidth); + + // Over-wide bitfields are an error in C or when using the MSVC bitfield + // ABI. + bool CStdConstraintViolation = + BitfieldIsOverwide && !getLangOpts().CPlusPlus; + bool MSBitfieldViolation = + Value.ugt(TypeStorageSize) && + (IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft()); + if (CStdConstraintViolation || MSBitfieldViolation) { + unsigned DiagWidth = + CStdConstraintViolation ? TypeWidth : TypeStorageSize; + if (FieldName) + return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width) + << FieldName << (unsigned)Value.getZExtValue() + << !CStdConstraintViolation << DiagWidth; + + return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width) + << (unsigned)Value.getZExtValue() << !CStdConstraintViolation + << DiagWidth; + } + + // Warn on types where the user might conceivably expect to get all + // specified bits as value bits: that's all integral types other than + // 'bool'. + if (BitfieldIsOverwide && !FieldTy->isBooleanType()) { if (FieldName) - Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_size) - << FieldName << (unsigned)Value.getZExtValue() - << (unsigned)TypeSize; + Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) + << FieldName << (unsigned)Value.getZExtValue() + << (unsigned)TypeWidth; else - Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_size) - << (unsigned)Value.getZExtValue() << (unsigned)TypeSize; + Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_width) + << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth; } } @@ -12866,9 +13211,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { SourceLocation Loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(Loc)) { if (!FD->hasAttr<UnavailableAttr>()) - FD->addAttr(UnavailableAttr::CreateImplicit(Context, - "this system field has retaining ownership", - Loc)); + FD->addAttr(UnavailableAttr::CreateImplicit(Context, "", + UnavailableAttr::IR_ARCFieldWithOwnership, Loc)); return false; } } @@ -12876,7 +13220,7 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { Diag(FD->getLocation(), getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member : diag::err_illegal_union_or_anon_struct_member) - << (int)FD->getParent()->isUnion() << FD->getDeclName() << member; + << FD->getParent()->isUnion() << FD->getDeclName() << member; DiagnoseNontrivial(RDecl, member); return !getLangOpts().CPlusPlus11; } @@ -13237,9 +13581,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, SourceLocation loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(loc)) { if (!FD->hasAttr<UnavailableAttr>()) { - FD->addAttr(UnavailableAttr::CreateImplicit(Context, - "this system field has retaining ownership", - loc)); + FD->addAttr(UnavailableAttr::CreateImplicit(Context, "", + UnavailableAttr::IR_ARCFieldWithOwnership, loc)); } } else { Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) @@ -13687,10 +14030,12 @@ Sema::SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, NamedDecl *PrevDecl = LookupSingleName(S, II, IILoc, LookupOrdinaryName, ForRedeclaration); auto *PrevECD = dyn_cast_or_null<EnumConstantDecl>(PrevDecl); + if (!PrevECD) + return SkipBodyInfo(); + + EnumDecl *PrevED = cast<EnumDecl>(PrevECD->getDeclContext()); NamedDecl *Hidden; - if (PrevECD && - !hasVisibleDefinition(cast<NamedDecl>(PrevECD->getDeclContext()), - &Hidden)) { + if (!PrevED->getDeclName() && !hasVisibleDefinition(PrevED, &Hidden)) { SkipBodyInfo Skip; Skip.Previous = Hidden; return Skip; @@ -13722,12 +14067,27 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, PrevDecl = nullptr; } + // C++ [class.mem]p15: + // If T is the name of a class, then each of the following shall have a name + // different from T: + // - every enumerator of every member of class T that is an unscoped + // enumerated type + if (!TheEnumDecl->isScoped()) + DiagnoseClassNameShadow(TheEnumDecl->getDeclContext(), + DeclarationNameInfo(Id, IdLoc)); + + EnumConstantDecl *New = + CheckEnumConstant(TheEnumDecl, LastEnumConst, IdLoc, Id, Val); + if (!New) + return nullptr; + if (PrevDecl) { // When in C++, we may get a TagDecl with the same name; in this case the // enum constant will 'hide' the tag. assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) && "Received TagDecl when not in C++!"); - if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) { + if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S) && + shouldLinkPossiblyHiddenDecl(PrevDecl, New)) { if (isa<EnumConstantDecl>(PrevDecl)) Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id; else @@ -13737,26 +14097,12 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, } } - // C++ [class.mem]p15: - // If T is the name of a class, then each of the following shall have a name - // different from T: - // - every enumerator of every member of class T that is an unscoped - // enumerated type - if (!TheEnumDecl->isScoped()) - DiagnoseClassNameShadow(TheEnumDecl->getDeclContext(), - DeclarationNameInfo(Id, IdLoc)); - - EnumConstantDecl *New = - CheckEnumConstant(TheEnumDecl, LastEnumConst, IdLoc, Id, Val); + // Process attributes. + if (Attr) ProcessDeclAttributeList(S, New, Attr); - if (New) { - // Process attributes. - if (Attr) ProcessDeclAttributeList(S, New, Attr); - - // Register this decl in the current scope stack. - New->setAccess(TheEnumDecl->getAccess()); - PushOnScopeChains(New, S); - } + // Register this decl in the current scope stack. + New->setAccess(TheEnumDecl->getAccess()); + PushOnScopeChains(New, S); ActOnDocumentableDecl(New); @@ -13803,6 +14149,7 @@ static bool ValidDuplicateEnum(EnumConstantDecl *ECD, EnumDecl *Enum) { return false; } +namespace { struct DupKey { int64_t val; bool isTombstoneOrEmptyKey; @@ -13826,6 +14173,7 @@ struct DenseMapInfoDupKey { LHS.val == RHS.val; } }; +} // end anonymous namespace // Emits a warning when an element is implicitly set a value that // a previous element has already been set to. @@ -13937,17 +14285,22 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements, } } -bool -Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, - bool AllowMask) const { - FlagEnumAttr *FEAttr = ED->getAttr<FlagEnumAttr>(); - assert(FEAttr && "looking for value in non-flag enum"); +bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, + bool AllowMask) const { + assert(ED->hasAttr<FlagEnumAttr>() && "looking for value in non-flag enum"); + assert(ED->isCompleteDefinition() && "expected enum definition"); - llvm::APInt FlagMask = ~FEAttr->getFlagBits(); - unsigned Width = FlagMask.getBitWidth(); + auto R = FlagBitsCache.insert(std::make_pair(ED, llvm::APInt())); + llvm::APInt &FlagBits = R.first->second; - // We will try a zero-extended value for the regular check first. - llvm::APInt ExtVal = Val.zextOrSelf(Width); + if (R.second) { + for (auto *E : ED->enumerators()) { + const auto &EVal = E->getInitVal(); + // Only single-bit enumerators introduce new flag values. + if (EVal.isPowerOf2()) + FlagBits = FlagBits.zextOrSelf(EVal.getBitWidth()) | EVal; + } + } // A value is in a flag enum if either its bits are a subset of the enum's // flag bits (the first condition) or we are allowing masks and the same is @@ -13957,27 +14310,8 @@ Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, // While it's true that any value could be used as a mask, the assumption is // that a mask will have all of the insignificant bits set. Anything else is // likely a logic error. - if (!(FlagMask & ExtVal)) - return true; - - if (AllowMask) { - // Try a one-extended value instead. This can happen if the enum is wider - // than the constant used, in C with extensions to allow for wider enums. - // The mask will still have the correct behaviour, so we give the user the - // benefit of the doubt. - // - // FIXME: This heuristic can cause weird results if the enum was extended - // to a larger type and is signed, because then bit-masks of smaller types - // that get extended will fall out of range (e.g. ~0x1u). We currently don't - // detect that case and will get a false positive for it. In most cases, - // though, it can be fixed by making it a signed type (e.g. ~0x1), so it may - // be fine just to accept this as a warning. - ExtVal |= llvm::APInt::getHighBitsSet(Width, Width - Val.getBitWidth()); - if (!(FlagMask & ~ExtVal)) - return true; - } - - return false; + llvm::APInt FlagMask = ~FlagBits.zextOrTrunc(Val.getBitWidth()); + return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, @@ -14131,13 +14465,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, } } - FlagEnumAttr *FEAttr = Enum->getAttr<FlagEnumAttr>(); - if (FEAttr) - FEAttr->getFlagBits() = llvm::APInt(BestWidth, 0); - // Loop over all of the enumerator constants, changing their types to match - // the type of the enum if needed. If we have a flag type, we also prepare the - // FlagBits cache. + // the type of the enum if needed. for (auto *D : Elements) { auto *ECD = cast_or_null<EnumConstantDecl>(D); if (!ECD) continue; // Already issued a diagnostic. @@ -14169,7 +14498,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // enum-specifier, each enumerator has the type of its // enumeration. ECD->setType(EnumType); - goto flagbits; + continue; } else { NewTy = BestType; NewWidth = BestWidth; @@ -14196,37 +14525,26 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setType(EnumType); else ECD->setType(NewTy); - -flagbits: - // Check to see if we have a constant with exactly one bit set. Note that x - // & (x - 1) will be nonzero if and only if x has more than one bit set. - if (FEAttr) { - llvm::APInt ExtVal = InitVal.zextOrSelf(BestWidth); - if (ExtVal != 0 && !(ExtVal & (ExtVal - 1))) { - FEAttr->getFlagBits() |= ExtVal; - } - } } - if (FEAttr) { + Enum->completeDefinition(BestType, BestPromotionType, + NumPositiveBits, NumNegativeBits); + + CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType); + + if (Enum->hasAttr<FlagEnumAttr>()) { for (Decl *D : Elements) { EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D); if (!ECD) continue; // Already issued a diagnostic. llvm::APSInt InitVal = ECD->getInitVal(); - if (InitVal != 0 && !IsValueInFlagEnum(Enum, InitVal, true)) + if (InitVal != 0 && !InitVal.isPowerOf2() && + !IsValueInFlagEnum(Enum, InitVal, true)) Diag(ECD->getLocation(), diag::warn_flag_enum_constant_out_of_range) << ECD << Enum; } } - - - Enum->completeDefinition(BestType, BestPromotionType, - NumPositiveBits, NumNegativeBits); - - CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType); - // Now that the enum type is defined, ensure it's not been underaligned. if (Enum->hasAttrs()) CheckAlignasUnderalignment(Enum); @@ -14245,17 +14563,15 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, } static void checkModuleImportContext(Sema &S, Module *M, - SourceLocation ImportLoc, - DeclContext *DC) { + SourceLocation ImportLoc, DeclContext *DC, + bool FromInclude = false) { + SourceLocation ExternCLoc; + if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) { switch (LSD->getLanguage()) { case LinkageSpecDecl::lang_c: - if (!M->IsExternC) { - S.Diag(ImportLoc, diag::err_module_import_in_extern_c) - << M->getFullModuleName(); - S.Diag(LSD->getLocStart(), diag::note_module_import_in_extern_c); - return; - } + if (ExternCLoc.isInvalid()) + ExternCLoc = LSD->getLocStart(); break; case LinkageSpecDecl::lang_cxx: break; @@ -14265,15 +14581,25 @@ static void checkModuleImportContext(Sema &S, Module *M, while (isa<LinkageSpecDecl>(DC)) DC = DC->getParent(); + if (!isa<TranslationUnitDecl>(DC)) { - S.Diag(ImportLoc, diag::err_module_import_not_at_top_level) - << M->getFullModuleName() << DC; + S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M)) + ? diag::ext_module_import_not_at_top_level_noop + : diag::err_module_import_not_at_top_level_fatal) + << M->getFullModuleName() << DC; S.Diag(cast<Decl>(DC)->getLocStart(), - diag::note_module_import_not_at_top_level) - << DC; + diag::note_module_import_not_at_top_level) << DC; + } else if (!M->IsExternC && ExternCLoc.isValid()) { + S.Diag(ImportLoc, diag::ext_module_import_in_extern_c) + << M->getFullModuleName(); + S.Diag(ExternCLoc, diag::note_module_import_in_extern_c); } } +void Sema::diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc) { + return checkModuleImportContext(*this, M, ImportLoc, CurContext); +} + DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, ModuleIdPath Path) { @@ -14318,7 +14644,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, } void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { - checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); // Determine whether we're in the #include buffer for a module. The #includes // in that buffer do not qualify as module imports; they're just an @@ -14394,12 +14720,14 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, // 1) declares a function or a variable // 2) has external linkage // already exists, add a label attribute to it. - if (PrevDecl && - (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl)) && - PrevDecl->hasExternalFormalLinkage()) - PrevDecl->addAttr(Attr); + if (PrevDecl && (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl))) { + if (isDeclExternC(PrevDecl)) + PrevDecl->addAttr(Attr); + else + Diag(PrevDecl->getLocation(), diag::warn_redefine_extname_not_applied) + << /*Variable*/(isa<FunctionDecl>(PrevDecl) ? 0 : 1) << PrevDecl; // Otherwise, add a label atttibute to ExtnameUndeclaredIdentifiers. - else + } else (void)ExtnameUndeclaredIdentifiers.insert(std::make_pair(Name, Attr)); } @@ -14426,7 +14754,7 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name, LookupOrdinaryName); WeakInfo W = WeakInfo(Name, NameLoc); - if (PrevDecl) { + if (PrevDecl && (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl))) { if (!PrevDecl->hasAttr<AliasAttr>()) if (NamedDecl *ND = dyn_cast<NamedDecl>(PrevDecl)) DeclApplyPragmaWeak(TUScope, ND, W); |