r238550 - Fix assertion on C++ attributes in fillAttributedTypeLoc

Alexander Musman alexander.musman at gmail.com
Fri May 29 04:24:33 PDT 2015


Author: amusman
Date: Fri May 29 06:24:32 2015
New Revision: 238550

URL: http://llvm.org/viewvc/llvm-project?rev=238550&view=rev
Log:
Fix assertion on C++ attributes in fillAttributedTypeLoc
this fixes http://llvm.org/PR17424
fillAttributedTypeLoc() function is only called with AttributeLists of either
DeclarationChunk (which is used for each type in a declarator being parsed) or
DeclSpec (which captures information about declaration specifiers).
As C++11 attributes actually appertain to declarators, they are moved straight
to the declarator’s attr list in distributeFunctionTypeAttrFromDeclSpec()
function.
'Put them wherever you like' semantics is not supported for C++11 attributes
(but is allowed for GNU attributes, for example). So when we meet an attribute
while parsing the declaration, we cannot be sure if it appertains to either
DeclarationChunk or DeclSpec.

This investigation correlates with the history of changes of SemaType.cpp:
• Asserts in fillAttributedTypeLoc() were added on 3 Mar 2011 in r126986
(http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-
        20110228/039638.html);
• Distributing C++11 attrs to the declarator was added on 14 Jan 2013
in r172504 (http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-
        20130114/071830.html).
Considering all written above I changed asserts in fillAttributedTypeLoc()
to nullptr checks.

This fixes PR17424 and related assertion on
[[gnu::fastcall]] void __stdcall foo();

Author: Alexey Frolov

Differential Revision: http://reviews.llvm.org/D9288


Modified:
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=238550&r1=238549&r2=238550&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri May 29 06:24:32 2015
@@ -3500,16 +3500,27 @@ static AttributeList::Kind getAttrListKi
 }
 
 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 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
                                      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<PackExpansionType>(T)) {
@@ -3879,7 +3891,7 @@ Sema::GetTypeSourceInfoForDeclarator(Dec
     }
 
     while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
-      fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs());
+      fillAttributedTypeLoc(TL, D.getTypeObject(i).getAttrs(), DeclAttrs);
       CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
     }
 

Modified: cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp?rev=238550&r1=238549&r2=238550&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp Fri May 29 06:24:32 2015
@@ -8,6 +8,19 @@ int [[gnu::unused]] attr_on_type;
 // expected-error at -1 {{'unused' attribute cannot be applied to types}}
 int *[[gnu::unused]] attr_on_ptr;
 // expected-warning at -1 {{attribute 'unused' ignored, because it cannot be applied to a type}}
+[[gnu::fastcall]] void pr17424_1();
+// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
+[[gnu::fastcall]] [[gnu::stdcall]] void pr17424_2();
+// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
+// expected-warning at -2 {{calling convention 'stdcall' ignored for this target}}
+[[gnu::fastcall]] __stdcall void pr17424_3();
+// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
+// expected-warning at -2 {{calling convention '__stdcall' ignored for this target}}
+[[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]];
+// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
+// expected-warning at -2 {{attribute 'stdcall' ignored, because it cannot be applied to a type}}
+void pr17424_5 [[gnu::fastcall]]();
+// expected-warning at -1 {{calling convention 'fastcall' ignored for this target}}
 
 // Valid cases.
 






More information about the cfe-commits mailing list