[cfe-commits] r172504 - in /cfe/trunk: lib/Sema/SemaType.cpp test/Parser/objcxx11-attributes.mm test/SemaCXX/cxx11-gnu-attrs.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Jan 14 18:48:14 PST 2013


Author: rsmith
Date: Mon Jan 14 20:48:13 2013
New Revision: 172504

URL: http://llvm.org/viewvc/llvm-project?rev=172504&view=rev
Log:
Fix behavior of [[gnu::]] function attributes. Per g++'s behavior, these
attributes appertain to a declaration, even though they would be much more
naturally modelled as appertaining to a function type. Previously, we would
try to distribute them from the declarator to the function type, then
reject them for being at an incorrect location. Now, we just distribute them
as far as the declarator; the existing attribute handling code can actually
apply them there just fine.

Modified:
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/Parser/objcxx11-attributes.mm
    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=172504&r1=172503&r2=172504&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 14 20:48:13 2013
@@ -463,6 +463,15 @@
                                        QualType &declSpecType) {
   state.saveDeclSpecAttrs();
 
+  // C++11 attributes before the decl specifiers actually appertain to
+  // the declarators. Move them straight there. We don't support the
+  // 'put them wherever you like' semantics we allow for GNU attributes.
+  if (attr.isCXX11Attribute()) {
+    moveAttrFromListToList(attr, state.getCurrentAttrListRef(),
+                           state.getDeclarator().getAttrListRef());
+    return;
+  }
+
   // Try to distribute to the innermost.
   if (distributeFunctionTypeAttrToInnermost(state, attr,
                                             state.getCurrentAttrListRef(),
@@ -512,6 +521,11 @@
   do {
     next = attr->getNext();
 
+    // Do not distribute C++11 attributes. They have strict rules for what
+    // they appertain to.
+    if (attr->isCXX11Attribute())
+      continue;
+
     switch (attr->getKind()) {
     OBJC_POINTER_TYPE_ATTRS_CASELIST:
       distributeObjCPointerTypeAttrFromDeclarator(state, *attr, declSpecType);

Modified: cfe/trunk/test/Parser/objcxx11-attributes.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-attributes.mm?rev=172504&r1=172503&r2=172504&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx11-attributes.mm (original)
+++ cfe/trunk/test/Parser/objcxx11-attributes.mm Mon Jan 14 20:48:13 2013
@@ -44,7 +44,7 @@
   int e2(); // expected-warning {{interpreted as a function declaration}} expected-note{{}}
 
   // A function taking a noreturn function.
-  int(f)([[noreturn]] int()); // expected-note {{here}}
+  int(f)([[gnu::noreturn]] int ()); // expected-note {{here}}
   f(e);
   f(e2); // expected-error {{cannot initialize a parameter of type 'int (*)() __attribute__((noreturn))' with an lvalue of type 'int ()'}}
 

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=172504&r1=172503&r2=172504&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx11-gnu-attrs.cpp Mon Jan 14 20:48:13 2013
@@ -39,7 +39,17 @@
 
 void nonnull [[gnu::nonnull]] (); // expected-warning {{applied to function with no pointer arguments}}
 
+// [[gnu::noreturn]] appertains to a declaration, and marks the innermost
+// function declarator in that declaration as being noreturn.
 int noreturn [[gnu::noreturn]]; // expected-warning {{'noreturn' only applies to function types}}
+int noreturn_fn_1();
+int noreturn_fn_2() [[gnu::noreturn]]; // expected-warning {{cannot be applied to a type}}
+int noreturn_fn_3 [[gnu::noreturn]] ();
+[[gnu::noreturn]] int noreturn_fn_4();
+int (*noreturn_fn_ptr_1 [[gnu::noreturn]])() = &noreturn_fn_1; // expected-error {{cannot initialize}}
+int (*noreturn_fn_ptr_2 [[gnu::noreturn]])() = &noreturn_fn_3;
+[[gnu::noreturn]] int (*noreturn_fn_ptr_3)() = &noreturn_fn_1; // expected-error {{cannot initialize}}
+[[gnu::noreturn]] int (*noreturn_fn_ptr_4)() = &noreturn_fn_3;
 
 struct [[gnu::packed]] packed { char c; int n; };
 static_assert(sizeof(packed) == sizeof(char) + sizeof(int), "not packed");





More information about the cfe-commits mailing list