[cfe-commits] r167481 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp test/CXX/expr/expr.const/p5-0x.cpp test/Parser/cxx0x-attributes.cpp test/SemaCXX/cxx98-compat.cpp

Michael Han Michael.Han at autodesk.com
Tue Nov 6 11:34:54 PST 2012


Author: hanm
Date: Tue Nov  6 13:34:54 2012
New Revision: 167481

URL: http://llvm.org/viewvc/llvm-project?rev=167481&view=rev
Log:
Teach Clang parser to reject C++11 attributes that appertain to declaration specifiers.

We don't support any C++11 attributes that appertain to declaration specifiers so reject 
the attributes in parser until we support them; this also conforms to what g++ 4.8 is doing.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
    cfe/trunk/test/CXX/expr/expr.const/p5-0x.cpp
    cfe/trunk/test/Parser/cxx0x-attributes.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Nov  6 13:34:54 2012
@@ -1865,6 +1865,11 @@
   }
   void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
 
+  // Forbid C++11 attributes that appear on certain syntactic 
+  // locations which standard permits but we don't supported yet, 
+  // for example, attributes appertain to decl specifiers.
+  void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
+
   void MaybeParseGNUAttributes(Declarator &D,
                                LateParsedAttrList *LateAttrs = 0) {
     if (Tok.is(tok::kw___attribute)) {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Nov  6 13:34:54 2012
@@ -1142,6 +1142,18 @@
     << attrs.Range;
 }
 
+void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
+  AttributeList *AttrList = attrs.getList();
+  while (AttrList) {
+    if (AttrList->isCXX0XAttribute()) {
+      Diag(AttrList->getLoc(), diag::warn_attribute_no_decl) 
+        << AttrList->getName();
+      AttrList->setInvalid();
+    }
+    AttrList = AttrList->getNext();
+  }
+}
+
 /// ParseDeclaration - Parse a full 'declaration', which consists of
 /// declaration-specifiers, some number of declarators, and a semicolon.
 /// 'Context' should be a Declarator::TheContext value.  This returns the
@@ -2148,8 +2160,14 @@
     DoneWithDeclSpec:
       if (!AttrsLastTime)
         ProhibitAttributes(attrs);
-      else
+      else {
+        // Reject C++11 attributes that appertain to decl specifiers as
+        // we don't support any C++11 attributes that appertain to decl
+        // specifiers. This also conforms to what g++ 4.8 is doing.
+        ProhibitCXX11Attributes(attrs);
+
         DS.takeAttributesFrom(attrs);
+      }
 
       // If this is not a declaration specifier token, we're done reading decl
       // specifiers.  First verify that DeclSpec's are consistent.

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp Tue Nov  6 13:34:54 2012
@@ -34,7 +34,7 @@
 void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}}
 }
 
-int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a type specifier}}
+alignas(struct Aa {}) int x; // expected-error {{'Aa' can not be defined in a type specifier}}
 
 int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}}
 int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}}

Modified: cfe/trunk/test/CXX/expr/expr.const/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p5-0x.cpp?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p5-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p5-0x.cpp Tue Nov  6 13:34:54 2012
@@ -61,10 +61,10 @@
 // [dcl.align]p2: When the alignment-specifier is of the form
 // alignas(assignment-expression), the assignment-expression shall be an
 // integral constant expression
-int alignas(ok) alignas1;
-int alignas(incomplete) alignas2; // expected-error {{incomplete}}
-int alignas(expl) alignas3; // expected-error {{explicit conversion}}
-int alignas(ambig) alignas4; // expected-error {{ambiguous conversion}}
+alignas(ok) int alignas1;
+alignas(incomplete) int alignas2; // expected-error {{incomplete}}
+alignas(expl) int alignas3; // expected-error {{explicit conversion}}
+alignas(ambig) int alignas4; // expected-error {{ambiguous conversion}}
 
 // [dcl.array]p1: If the constant-expression is present, it shall be an integral
 // constant expression

Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Nov  6 13:34:54 2012
@@ -223,3 +223,10 @@
   void f(const char*, ...) [[gnu::format(printf, 1, 2)]]; // expected-warning {{unknown attribute 'format' ignored}}
   void g() [[unknown::foo(currently arguments of attributes from unknown namespace other than 'gnu' namespace are ignored... blah...)]]; // expected-warning {{unknown attribute 'foo' ignored}}
 }
+
+// forbid attributes on decl specifiers
+unsigned [[gnu::used]] static int [[gnu::unused]] v1; // expected-warning {{attribute 'unused' ignored, because it is not attached to a declaration}} \
+           expected-error {{an attribute list cannot appear here}}
+typedef [[gnu::used]] unsigned long [[gnu::unused]] v2; // expected-warning {{attribute 'unused' ignored, because it is not attached to a declaration}} \
+          expected-error {{an attribute list cannot appear here}}
+int [[carries_dependency]] foo(int [[carries_dependency]] x); // expected-warning 2{{attribute 'carries_dependency' ignored, because it is not attached to a declaration}}

Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=167481&r1=167480&r2=167481&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Tue Nov  6 13:34:54 2012
@@ -20,7 +20,7 @@
 template<int ...I>  // expected-warning {{variadic templates are incompatible with C++98}}
 class Variadic3 {};
 
-int alignas(8) with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
+alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
 int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
 
 void Literals() {





More information about the cfe-commits mailing list