Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -2426,12 +2426,14 @@ bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex); - TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, - TypeVisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex); + TypeVisibilityAttr * + mergeTypeVisibilityAttr(Decl *D, SourceRange Range, + TypeVisibilityAttr::VisibilityType Vis, + unsigned AttrSpellingListIndex, bool IsInherited); VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range, VisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex); + unsigned AttrSpellingListIndex, + bool IsInherited); UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex, StringRef Uuid); DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range, @@ -3330,14 +3332,18 @@ void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. - void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); + void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, + bool IsInherited); // Helper for delayed processing of attributes. void ProcessDeclAttributeDelayed(Decl *D, const ParsedAttributesView &AttrList); - void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL, - bool IncludeCXX11Attributes = true); + void ProcessDeclAttributeList(Scope *S, Decl *D, + const ParsedAttributesView &AL, + bool IncludeCXX11Attributes /*=true*/, + bool IsInherited); bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, - const ParsedAttributesView &AttrList); + const ParsedAttributesView &AttrList, + bool IsInherited); void checkUnusedDeclAttributes(Declarator &D); Index: lib/Parse/ParseCXXInlineMethods.cpp =================================================================== --- lib/Parse/ParseCXXInlineMethods.cpp +++ lib/Parse/ParseCXXInlineMethods.cpp @@ -44,7 +44,8 @@ TemplateParams, nullptr, VS, ICIS_NoInit); if (FnD) { - Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs); + Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs, true, + false); if (PureSpecLoc.isValid()) Actions.ActOnPureSpecifier(FnD, PureSpecLoc); } Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -2761,7 +2761,8 @@ ThisDecl = VT->getTemplatedDecl(); if (ThisDecl) - Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs); + Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, + true, false); } // Error recovery might have converted a non-static member into a static Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -627,7 +627,7 @@ LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(), IdentTok.getLocation()); - Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs); + Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs, true, false); attrs.clear(); return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc, Index: lib/Sema/SemaAttr.cpp =================================================================== --- lib/Sema/SemaAttr.cpp +++ lib/Sema/SemaAttr.cpp @@ -662,7 +662,7 @@ PragmaAttributeCurrentTargetDecl = D; ParsedAttributesView Attrs; Attrs.addAtEnd(Attribute); - ProcessDeclAttributeList(S, D, Attrs); + ProcessDeclAttributeList(S, D, Attrs, true, false); PragmaAttributeCurrentTargetDecl = nullptr; } } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -2415,7 +2415,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, const InheritableAttr *Attr, - Sema::AvailabilityMergeKind AMK) { + Sema::AvailabilityMergeKind AMK, + bool IsInherited) { // This function copies an attribute Attr from a previous declaration to the // new declaration D if the new declaration doesn't itself have that attribute // yet or if that attribute allows duplicates. @@ -2435,10 +2436,10 @@ AttrSpellingListIndex); else if (const auto *VA = dyn_cast(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), - AttrSpellingListIndex); + AttrSpellingListIndex, IsInherited); else if (const auto *VA = dyn_cast(Attr)) NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), - AttrSpellingListIndex); + AttrSpellingListIndex, IsInherited); else if (const auto *ImportA = dyn_cast(Attr)) NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(), AttrSpellingListIndex); @@ -2713,7 +2714,7 @@ if (isa(I)) continue; - if (mergeDeclAttribute(*this, New, I, LocalAMK)) + if (mergeDeclAttribute(*this, New, I, LocalAMK, true)) foundAny = true; } @@ -5752,7 +5753,7 @@ if (!NewTD) return nullptr; // Handle attributes prior to checking for duplicates in MergeVarDecl - ProcessDeclAttributes(S, NewTD, D); + ProcessDeclAttributes(S, NewTD, D, false); CheckTypedefForVariablyModifiedType(S, NewTD); @@ -6732,7 +6733,7 @@ } // Handle attributes prior to checking for duplicates in MergeVarDecl - ProcessDeclAttributes(S, NewVD, D); + ProcessDeclAttributes(S, NewVD, D, false); if (getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) { if (EmitTLSUnsupportedError && @@ -8832,7 +8833,7 @@ } // Handle attributes. - ProcessDeclAttributes(S, NewFD, D); + ProcessDeclAttributes(S, NewFD, D, false); if (getLangOpts().OpenCL) { // OpenCL v1.1 s6.5: Using an address space qualifier in a function return @@ -12394,7 +12395,7 @@ if (II) IdResolver.AddDecl(New); - ProcessDeclAttributes(S, New, D); + ProcessDeclAttributes(S, New, D, false); if (D.getDeclSpec().isModulePrivateSpecified()) Diag(New->getLocation(), diag::err_module_private_local) @@ -13304,7 +13305,7 @@ // Always attach attributes to the underlying decl. if (TemplateDecl *TD = dyn_cast(D)) D = TD->getTemplatedDecl(); - ProcessDeclAttributeList(S, D, Attrs); + ProcessDeclAttributeList(S, D, Attrs, true, false); if (CXXMethodDecl *Method = dyn_cast_or_null(D)) if (Method->isStatic()) @@ -14761,7 +14762,7 @@ if (TUK == TUK_Definition) New->startDefinition(); - ProcessDeclAttributeList(S, New, Attrs); + ProcessDeclAttributeList(S, New, Attrs, true, false); AddPragmaAttributes(S, New); // If this has an identifier, add it to the scope stack. @@ -15337,7 +15338,7 @@ // representation, not a parser representation. if (D) { // FIXME: The current scope is almost... but not entirely... correct here. - ProcessDeclAttributes(getCurScope(), NewFD, *D); + ProcessDeclAttributes(getCurScope(), NewFD, *D, false); if (NewFD->hasAttrs()) CheckAlignasUnderalignment(NewFD); @@ -15514,7 +15515,7 @@ } // Process attributes attached to the ivar. - ProcessDeclAttributes(S, NewID, D); + ProcessDeclAttributes(S, NewID, D, false); if (D.isInvalidType()) NewID->setInvalidDecl(); @@ -15899,7 +15900,7 @@ Record->completeDefinition(); // Handle attributes before checking the layout. - ProcessDeclAttributeList(S, Record, Attrs); + ProcessDeclAttributeList(S, Record, Attrs, true, false); // We may have deferred checking for a deleted destructor. Check now. if (CXXRecordDecl *CXXRecord = dyn_cast(Record)) { @@ -16328,7 +16329,7 @@ } // Process attributes. - ProcessDeclAttributeList(S, New, Attrs); + ProcessDeclAttributeList(S, New, Attrs, true, false); AddPragmaAttributes(S, New); // Register this decl in the current scope stack. @@ -16525,7 +16526,7 @@ EnumDecl *Enum = cast(EnumDeclX); QualType EnumType = Context.getTypeDeclType(Enum); - ProcessDeclAttributeList(S, Enum, Attrs); + ProcessDeclAttributeList(S, Enum, Attrs, true, false); if (Enum->isDependentType()) { for (unsigned i = 0, e = Elements.size(); i != e; ++i) { Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -1600,7 +1600,8 @@ return false; } -static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { +static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL, + bool IsInherited) { // This attribute must be applied to a function declaration. The first // argument to the attribute must be an identifier, the name of the resource, // for example: malloc. The following arguments must be argument indexes, the @@ -1687,10 +1688,12 @@ // A returns attribute conflicts with any other returns attribute using // a different index. if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { - S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) + S.Diag(IsInherited ? I->getLocation() : AL.getLoc(), + diag::err_ownership_returns_index_mismatch) << I->args_begin()->getSourceIndex(); if (I->args_size()) - S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) + S.Diag(IsInherited ? AL.getLoc() : I->getLocation(), + diag::note_ownership_returns_index_mismatch) << Idx.getSourceIndex() << Ex->getSourceRange(); return; } @@ -2475,14 +2478,19 @@ template static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range, typename T::VisibilityType value, - unsigned attrSpellingListIndex) { + unsigned attrSpellingListIndex, + bool IsInherited) { T *existingAttr = D->getAttr(); if (existingAttr) { typename T::VisibilityType existingValue = existingAttr->getVisibility(); if (existingValue == value) return nullptr; - S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); - S.Diag(range.getBegin(), diag::note_previous_attribute); + S.Diag(IsInherited ? existingAttr->getLocation() : range.getBegin(), + diag::err_mismatched_visibility); + S.Diag(IsInherited ? range.getBegin() : existingAttr->getLocation(), + diag::note_previous_attribute); + // S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); + // S.Diag(range.getBegin(), diag::note_previous_attribute); D->dropAttr(); } return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex); @@ -2490,20 +2498,21 @@ VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, VisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex) { - return ::mergeVisibilityAttr(*this, D, Range, Vis, - AttrSpellingListIndex); + unsigned AttrSpellingListIndex, + bool IsInherited) { + return ::mergeVisibilityAttr( + *this, D, Range, Vis, AttrSpellingListIndex, IsInherited); } -TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range, - TypeVisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex) { - return ::mergeVisibilityAttr(*this, D, Range, Vis, - AttrSpellingListIndex); +TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr( + Decl *D, SourceRange Range, TypeVisibilityAttr::VisibilityType Vis, + unsigned AttrSpellingListIndex, bool IsInherited) { + return ::mergeVisibilityAttr( + *this, D, Range, Vis, AttrSpellingListIndex, IsInherited); } static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL, - bool isTypeVisibility) { + bool isTypeVisibility, bool IsInherited) { // Visibility attributes don't mean anything on a typedef. if (isa(D)) { S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) @@ -2545,11 +2554,11 @@ unsigned Index = AL.getAttributeSpellingListIndex(); Attr *newAttr; if (isTypeVisibility) { - newAttr = S.mergeTypeVisibilityAttr(D, AL.getRange(), - (TypeVisibilityAttr::VisibilityType) type, - Index); + newAttr = S.mergeTypeVisibilityAttr( + D, AL.getRange(), (TypeVisibilityAttr::VisibilityType)type, Index, + IsInherited); } else { - newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index); + newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index, IsInherited); } if (newAttr) D->addAttr(newAttr); @@ -5948,7 +5957,8 @@ /// silently ignore it if a GNU attribute. static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, - bool IncludeCXX11Attributes) { + bool IncludeCXX11Attributes, + bool IsInherited) { if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute) return; @@ -6190,7 +6200,7 @@ handleSimpleAttribute(S, D, AL); break; case ParsedAttr::AT_Ownership: - handleOwnershipAttr(S, D, AL); + handleOwnershipAttr(S, D, AL, IsInherited); break; case ParsedAttr::AT_Cold: handleSimpleAttributeWithExclusions(S, D, AL); @@ -6340,10 +6350,10 @@ handleSimpleAttribute(S, D, AL); break; case ParsedAttr::AT_Visibility: - handleVisibilityAttr(S, D, AL, false); + handleVisibilityAttr(S, D, AL, false, IsInherited); break; case ParsedAttr::AT_TypeVisibility: - handleVisibilityAttr(S, D, AL, true); + handleVisibilityAttr(S, D, AL, true, IsInherited); break; case ParsedAttr::AT_WarnUnused: handleSimpleAttribute(S, D, AL); @@ -6611,12 +6621,13 @@ /// attribute list to the specified decl, ignoring any type attributes. void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, - bool IncludeCXX11Attributes) { + bool IncludeCXX11Attributes, + bool IsInherited) { if (AttrList.empty()) return; for (const ParsedAttr &AL : AttrList) - ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes); + ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes, IsInherited); // FIXME: We should be able to handle these cases in TableGen. // GCC accepts @@ -6683,11 +6694,13 @@ // Annotation attributes are the only attributes allowed after an access // specifier. -bool Sema::ProcessAccessDeclAttributeList( - AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) { +bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, + const ParsedAttributesView &AttrList, + bool IsInherited) { for (const ParsedAttr &AL : AttrList) { if (AL.getKind() == ParsedAttr::AT_Annotate) { - ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute()); + ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute(), + IsInherited); } else { Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec); return true; @@ -6825,10 +6838,12 @@ /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in /// it, apply them to D. This is a bit tricky because PD can have attributes /// specified in many different places, and we need to find and apply them all. -void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { +void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, + bool IsInherited) { // Apply decl attributes from the DeclSpec if present. if (!PD.getDeclSpec().getAttributes().empty()) - ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes()); + ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes(), + IsInherited, false); // Walk the declarator structure, applying decl attributes that were in a type // position to the decl itself. This handles cases like: @@ -6836,10 +6851,10 @@ // when X is a decl attribute. for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(), - /*IncludeCXX11Attributes=*/false); + /*IncludeCXX11Attributes=*/false, IsInherited); // Finally, apply any attributes on the decl itself. - ProcessDeclAttributeList(S, D, PD.getAttributes()); + ProcessDeclAttributeList(S, D, PD.getAttributes(), true, IsInherited); // Apply additional attributes specified by '#pragma clang attribute'. AddPragmaAttributes(S, D); Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -2706,7 +2706,7 @@ AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext, ASLoc, ColonLoc); CurContext->addHiddenDecl(ASDecl); - return ProcessAccessDeclAttributeList(ASDecl, Attrs); + return ProcessAccessDeclAttributeList(ASDecl, Attrs, false); } /// CheckOverrideControl - Check C++11 override control semantics. @@ -8804,7 +8804,7 @@ if (IsInvalid) Namespc->setInvalidDecl(); - ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList); + ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList, true, false); AddPragmaAttributes(DeclRegionScope, Namespc); // FIXME: Should we be merging attributes? @@ -9322,7 +9322,7 @@ } if (UDir) - ProcessDeclAttributeList(S, UDir, AttrList); + ProcessDeclAttributeList(S, UDir, AttrList, true, false); return UDir; } @@ -10425,7 +10425,7 @@ if (Invalid) NewTD->setInvalidDecl(); - ProcessDeclAttributeList(S, NewTD, AttrList); + ProcessDeclAttributeList(S, NewTD, AttrList, true, false); AddPragmaAttributes(S, NewTD); CheckTypedefForVariablyModifiedType(S, NewTD); @@ -13539,7 +13539,7 @@ Decl *ED = EmptyDecl::Create(Context, CurContext, SemiLoc); // Attribute declarations appertain to empty declaration so we handle // them here. - ProcessDeclAttributeList(S, ED, AttrList); + ProcessDeclAttributeList(S, ED, AttrList, true, false); CurContext->addDecl(ED); return ED; @@ -13724,7 +13724,7 @@ else CurContext->addDecl(ExDecl); - ProcessDeclAttributes(S, ExDecl, D); + ProcessDeclAttributes(S, ExDecl, D, false); return ExDecl; } @@ -15443,7 +15443,7 @@ const ParsedAttr::PropertyData &Data = MSPropertyAttr.getPropertyData(); MSPropertyDecl *NewPD = MSPropertyDecl::Create( Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId); - ProcessDeclAttributes(TUScope, NewPD, D); + ProcessDeclAttributes(TUScope, NewPD, D, false); NewPD->setAccess(AS); if (NewPD->isInvalidDecl()) Index: lib/Sema/SemaDeclObjC.cpp =================================================================== --- lib/Sema/SemaDeclObjC.cpp +++ lib/Sema/SemaDeclObjC.cpp @@ -1059,7 +1059,7 @@ } } - ProcessDeclAttributeList(TUScope, IDecl, AttrList); + ProcessDeclAttributeList(TUScope, IDecl, AttrList, true, false); AddPragmaAttributes(TUScope, IDecl); PushOnScopeChains(IDecl, TUScope); @@ -1246,7 +1246,7 @@ PDecl->startDefinition(); } - ProcessDeclAttributeList(TUScope, PDecl, AttrList); + ProcessDeclAttributeList(TUScope, PDecl, AttrList, true, false); AddPragmaAttributes(TUScope, PDecl); // Merge attributes from previous declarations. @@ -1774,7 +1774,7 @@ PushOnScopeChains(PDecl, TUScope); CheckObjCDeclScope(PDecl); - ProcessDeclAttributeList(TUScope, PDecl, attrList); + ProcessDeclAttributeList(TUScope, PDecl, attrList, true, false); AddPragmaAttributes(TUScope, PDecl); if (PrevDecl) @@ -1861,7 +1861,7 @@ // Process the attributes before looking at protocols to ensure that the // availability attribute is attached to the category to provide availability // checking for protocol uses. - ProcessDeclAttributeList(TUScope, CDecl, AttrList); + ProcessDeclAttributeList(TUScope, CDecl, AttrList, true, false); AddPragmaAttributes(TUScope, CDecl); if (NumProtoRefs) { @@ -4603,7 +4603,7 @@ CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier())); // Apply the attributes to the parameter. - ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs); + ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs, true, false); AddPragmaAttributes(TUScope, Param); if (Param->hasAttr()) { @@ -4633,7 +4633,7 @@ ObjCMethod->setObjCDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); - ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList); + ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList, true, false); AddPragmaAttributes(TUScope, ObjCMethod); // Add the method now. @@ -4924,7 +4924,7 @@ if (D.getIdentifier()) IdResolver.AddDecl(New); - ProcessDeclAttributes(S, New, D); + ProcessDeclAttributes(S, New, D, false); if (New->hasAttr()) Diag(New->getLocation(), diag::err_block_on_nonlocal); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -13381,7 +13381,7 @@ } // Finally we can process decl attributes. - ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo); + ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo, false); // Put the parameter variables in scope. for (auto AI : CurBlock->TheDecl->parameters()) { Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -919,7 +919,7 @@ Method->addAttr(A); // Attributes on the lambda apply to the method. - ProcessDeclAttributes(CurScope, Method, ParamInfo); + ProcessDeclAttributes(CurScope, Method, ParamInfo, false); // CUDA lambdas get implicit attributes based on the scope in which they're // declared. Index: lib/Sema/SemaObjCProperty.cpp =================================================================== --- lib/Sema/SemaObjCProperty.cpp +++ lib/Sema/SemaObjCProperty.cpp @@ -644,7 +644,7 @@ PDecl->setInvalidDecl(); } - ProcessDeclAttributes(S, PDecl, FD.D); + ProcessDeclAttributes(S, PDecl, FD.D, false); // Regardless of setter/getter attribute, we save the default getter/setter // selector names in anticipation of declaration of setter/getter methods. Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -1609,7 +1609,7 @@ if (TUK == TUK_Definition) NewClass->startDefinition(); - ProcessDeclAttributeList(S, NewClass, Attr); + ProcessDeclAttributeList(S, NewClass, Attr, true, false); if (PrevClassTemplate) mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl()); @@ -7711,7 +7711,7 @@ } } - ProcessDeclAttributeList(S, Specialization, Attr); + ProcessDeclAttributeList(S, Specialization, Attr, true, false); // Add alignment attributes if necessary; these attributes are checked when // the ASTContext lays out the structure. @@ -8763,7 +8763,7 @@ Specialization->setBraceRange(SourceRange()); bool PreviouslyDLLExported = Specialization->hasAttr(); - ProcessDeclAttributeList(S, Specialization, Attr); + ProcessDeclAttributeList(S, Specialization, Attr, true, false); // Add the explicit instantiation into its lexical context. However, // since explicit instantiations are never found by name lookup, we @@ -9167,7 +9167,8 @@ Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); if (PrevTemplate) { // Merge attributes. - ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); + ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes(), true, + false); } if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateVariableDefinition(D.getIdentifierLoc(), Prev); @@ -9329,7 +9330,8 @@ return (Decl*) nullptr; } - ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes()); + ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes(), + true, false); // In MSVC mode, dllimported explicit instantiation definitions are treated as // instantiation declarations.