Index: cfe/trunk/lib/Sema/SemaType.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp +++ cfe/trunk/lib/Sema/SemaType.cpp @@ -3500,16 +3500,27 @@ } static void fillAttributedTypeLoc(AttributedTypeLoc TL, - const AttributeList *attrs) { - AttributedType::Kind kind = TL.getAttrKind(); - - assert(attrs && "no type attributes in the expected location!"); - AttributeList::Kind parsedKind = getAttrListKind(kind); - while (attrs->getKind() != parsedKind) { + const AttributeList *attrs, + const AttributeList *DeclAttrs = nullptr) { + // DeclAttrs and attrs cannot be both empty. + assert((attrs || DeclAttrs) && + "no type attributes in the expected location!"); + + AttributeList::Kind parsedKind = getAttrListKind(TL.getAttrKind()); + // Try to search for an attribute of matching kind in attrs list. + while (attrs && attrs->getKind() != parsedKind) attrs = attrs->getNext(); - assert(attrs && "no matching attribute in expected location!"); + if (!attrs) { + // No matching type attribute in attrs list found. + // Try searching through C++11 attributes in the declarator attribute list. + while (DeclAttrs && (!DeclAttrs->isCXX11Attribute() || + DeclAttrs->getKind() != parsedKind)) + DeclAttrs = DeclAttrs->getNext(); + attrs = DeclAttrs; } + assert(attrs && "no matching type attribute in expected location!"); + TL.setAttrNameLoc(attrs->getLoc()); if (TL.hasAttrExprOperand()) { assert(attrs->isArgExpr(0) && "mismatched attribute operand kind"); @@ -3863,6 +3874,7 @@ TypeSourceInfo *ReturnTypeInfo) { TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T); UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc(); + const AttributeList *DeclAttrs = D.getAttributes(); // Handle parameter packs whose type is a pack expansion. if (isa(T)) { @@ -3879,7 +3891,7 @@ } while (AttributedTypeLoc TL = CurrTL.getAs()) { - fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs()); + fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(), DeclAttrs); CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); } Index: cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp =================================================================== --- cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp +++ cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp @@ -8,6 +8,19 @@ // expected-error@-1 {{'unused' attribute cannot be applied to types}} int *[[gnu::unused]] attr_on_ptr; // expected-warning@-1 {{attribute 'unused' ignored, because it cannot be applied to a type}} +[[gnu::fastcall]] void pr17424_1(); +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} +[[gnu::fastcall]] [[gnu::stdcall]] void pr17424_2(); +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} +// expected-warning@-2 {{calling convention 'stdcall' ignored for this target}} +[[gnu::fastcall]] __stdcall void pr17424_3(); +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} +// expected-warning@-2 {{calling convention '__stdcall' ignored for this target}} +[[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]]; +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} +// expected-warning@-2 {{attribute 'stdcall' ignored, because it cannot be applied to a type}} +void pr17424_5 [[gnu::fastcall]](); +// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}} // Valid cases.