[cfe-commits] r165082 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaStmtAttr.cpp test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp test/Parser/cxx0x-attributes.cpp test/Parser/cxx11-stmt-attributes.cpp test/Parser/objcxx11-attributes.mm test/SemaCXX/switch-implicit-fallthrough-per-method.cpp

Michael Han Michael.Han at autodesk.com
Tue Oct 2 18:56:22 PDT 2012


Author: hanm
Date: Tue Oct  2 20:56:22 2012
New Revision: 165082

URL: http://llvm.org/viewvc/llvm-project?rev=165082&view=rev
Log:
Improve C++11 attribute parsing.

- General C++11 attributes were previously parsed and ignored. Now they are parsed and stored in AST.
- Add support to parse arguments of attributes that in 'gnu' namespace.
- Differentiate unknown attributes and known attributes that can't be applied to statements when emitting diagnostic.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaStmtAttr.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp
    cfe/trunk/test/Parser/cxx0x-attributes.cpp
    cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp
    cfe/trunk/test/Parser/objcxx11-attributes.mm
    cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Oct  2 20:56:22 2012
@@ -1848,7 +1848,10 @@
   void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
                              SourceLocation AttrNameLoc,
                              ParsedAttributes &Attrs,
-                             SourceLocation *EndLoc);
+                             SourceLocation *EndLoc,
+                             IdentifierInfo *ScopeName,
+                             SourceLocation ScopeLoc,
+                             AttributeList::Syntax Syntax);
 
   void MaybeParseCXX0XAttributes(Declarator &D) {
     if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) {
@@ -1878,6 +1881,7 @@
                                     SourceLocation *EndLoc = 0);
   void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
                             SourceLocation *EndLoc = 0);
+
   IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
 
   void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Oct  2 20:56:22 2012
@@ -154,7 +154,8 @@
           Eof.setLocation(Tok.getLocation());
           LA->Toks.push_back(Eof);
         } else {
-          ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc);
+          ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
+                                0, AttrNameLoc, AttributeList::AS_GNU);
         }
       } else {
         attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
@@ -173,11 +174,15 @@
 }
 
 
-/// Parse the arguments to a parameterized GNU attribute
+/// Parse the arguments to a parameterized GNU attribute or
+/// a C++11 attribute in "gnu" namespace.
 void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
                                    SourceLocation AttrNameLoc,
                                    ParsedAttributes &Attrs,
-                                   SourceLocation *EndLoc) {
+                                   SourceLocation *EndLoc,
+                                   IdentifierInfo *ScopeName,
+                                   SourceLocation ScopeLoc,
+                                   AttributeList::Syntax Syntax) {
 
   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
 
@@ -278,9 +283,9 @@
   SourceLocation RParen = Tok.getLocation();
   if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
     AttributeList *attr =
-      Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc,
-                   ParmName, ParmLoc, ArgExprs.data(), ArgExprs.size(),
-                   AttributeList::AS_GNU);
+      Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen),
+                   ScopeName, ScopeLoc, ParmName, ParmLoc,
+                   ArgExprs.data(), ArgExprs.size(), Syntax);
     if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection)
       Diag(Tok, diag::err_iboutletcollection_builtintype);
   }
@@ -923,7 +928,8 @@
       if (HasFunScope)
         Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
 
-      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
+                            0, LA.AttrNameLoc, AttributeList::AS_GNU);
 
       if (HasFunScope) {
         Actions.ActOnExitFunctionContext();
@@ -935,7 +941,8 @@
     } else {
       // If there are multiple decls, then the decl cannot be within the
       // function scope.
-      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
+                            0, LA.AttrNameLoc, AttributeList::AS_GNU);
     }
   } else {
     Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Oct  2 20:56:22 2012
@@ -2879,6 +2879,21 @@
   }
 }
 
+static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
+                                               IdentifierInfo *ScopeName) {
+  switch (AttributeList::getKind(AttrName, ScopeName,
+                                 AttributeList::AS_CXX11)) {
+  case AttributeList::AT_CarriesDependency:
+  case AttributeList::AT_FallThrough:
+  case AttributeList::AT_NoReturn: {
+    return true;
+  }
+
+  default:
+    return false;
+  }
+}
+
 /// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently
 /// only parses standard attributes.
 ///
@@ -2963,46 +2978,38 @@
       }
     }
 
+    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName);
     bool AttrParsed = false;
-    switch (AttributeList::getKind(AttrName, ScopeName,
-                                   AttributeList::AS_CXX11)) {
-    // No arguments
-    case AttributeList::AT_CarriesDependency:
-    // FIXME: implement generic support of attributes with C++11 syntax
-    // see Parse/ParseDecl.cpp: ParseGNUAttributes
-    case AttributeList::AT_FallThrough:
-    case AttributeList::AT_NoReturn: {
-      if (Tok.is(tok::l_paren)) {
-        Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
-          << AttrName->getName();
-        break;
+
+    // Parse attribute arguments
+    if (Tok.is(tok::l_paren)) {
+      if (ScopeName && ScopeName->getName() == "gnu") {
+        ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc,
+                              ScopeName, ScopeLoc, AttributeList::AS_CXX11);
+        AttrParsed = true;
+      } else {
+        if (StandardAttr)
+          Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
+            << AttrName->getName();
+
+        // FIXME: handle other formats of c++11 attribute arguments
+        ConsumeParen();
+        SkipUntil(tok::r_paren, false);
       }
+    }
 
+    if (!AttrParsed)
       attrs.addNew(AttrName,
                    SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
                                AttrLoc),
                    ScopeName, ScopeLoc, 0,
                    SourceLocation(), 0, 0, AttributeList::AS_CXX11);
-      AttrParsed = true;
-      break;
-    }
-
-    // Silence warnings
-    default: break;
-    }
-
-    // Skip the entire parameter clause, if any
-    if (!AttrParsed && Tok.is(tok::l_paren)) {
-      ConsumeParen();
-      // SkipUntil maintains the balancedness of tokens.
-      SkipUntil(tok::r_paren, false);
-    }
 
     if (Tok.is(tok::ellipsis)) {
-      if (AttrParsed)
-        Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
-          << AttrName->getName();
       ConsumeToken();
+
+      Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
+        << AttrName->getName();
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Tue Oct  2 20:56:22 2012
@@ -48,11 +48,16 @@
 static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
                                   SourceRange Range) {
   switch (A.getKind()) {
+  case AttributeList::UnknownAttribute:
+    S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
+           diag::warn_unhandled_ms_attribute_ignored :
+           diag::warn_unknown_attribute_ignored) << A.getName();
+    return 0;
   case AttributeList::AT_FallThrough:
     return handleFallThroughAttr(S, St, A, Range);
   default:
-    // if we're here, then we parsed an attribute, but didn't recognize it as a
-    // statement attribute => it is declaration attribute
+    // if we're here, then we parsed a known attribute, but didn't recognize
+    // it as a statement attribute => it is declaration attribute
     S.Diag(A.getRange().getBegin(), diag::warn_attribute_invalid_on_stmt)
         << A.getName()->getName() << St->getLocStart();
     return 0;

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp Tue Oct  2 20:56:22 2012
@@ -6,7 +6,8 @@
 void f() {
   int x = 42, y[5];
   // FIXME: Produce a better diagnostic for this case.
-  int(p[[x] { return x; }()]); // expected-error {{expected ']'}}
+  int(p[[x] { return x; }()]); // expected-error {{expected ']'}} \
+  // expected-warning {{unknown attribute 'x' ignored}}
   y[[] { return 2; }()] = 2; // expected-error {{consecutive left square brackets}}
 }
 

Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Oct  2 20:56:22 2012
@@ -44,10 +44,15 @@
 int && [[]] rref_attr = 0;
 int array_attr [1] [[]];
 alignas(8) int aligned_attr;
-[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]]
-  int garbage_attr;
-[[,,,static, class, namespace,, inline, constexpr, mutable,, bi\
-tand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr;
+[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown attribute 'valid' ignored}}
+[[,,,static, class, namespace,, inline, constexpr, mutable,, bitand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr; // expected-warning {{unknown attribute 'static' ignored}} \
+	// expected-warning {{unknown attribute 'class' ignored}} \
+	// expected-warning {{unknown attribute 'namespace' ignored}} \
+	// expected-warning {{unknown attribute 'inline' ignored}} \
+	// expected-warning {{unknown attribute 'constexpr' ignored}} \
+	// expected-warning {{unknown attribute 'mutable' ignored}} \
+	// expected-warning {{unknown attribute 'bitand' ignored}} \
+        // expected-warning {{unknown attribute 'compl' ignored}}
 [[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected ']'}}
 void fn_attr () [[]];
 void noexcept_fn_attr () noexcept [[]];
@@ -212,3 +217,9 @@
   one, /* rest are deprecated */ two, three
 };
 enum class [[]] EvenMoreSecrets {};
+
+namespace arguments {
+  // FIXME: remove the sema warnings after migrating existing gnu attributes to c++11 syntax.
+  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}}
+}

Modified: cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp Tue Oct  2 20:56:22 2012
@@ -2,53 +2,78 @@
 
 void foo(int i) {
 
-  [[unknown_attribute]] ;
-  [[unknown_attribute]] { }
-  [[unknown_attribute]] if (0) { }
-  [[unknown_attribute]] for (;;);
-  [[unknown_attribute]] do {
-    [[unknown_attribute]] continue;
+  [[unknown_attribute]] ; // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+  [[unknown_attribute]] { } // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+  [[unknown_attribute]] if (0) { } // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+  [[unknown_attribute]] for (;;); // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+  [[unknown_attribute]] do { // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+    [[unknown_attribute]] continue; // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
   } while (0);
-  [[unknown_attribute]] while (0);
+  [[unknown_attribute]] while (0); // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
 
-  [[unknown_attribute]] switch (i) {
-    [[unknown_attribute]] case 0:
-    [[unknown_attribute]] default:
-      [[unknown_attribute]] break;
+  [[unknown_attribute]] switch (i) { // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+    [[unknown_attribute]] case 0: // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+    [[unknown_attribute]] default: // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+      [[unknown_attribute]] break; // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
   }
 
-  [[unknown_attribute]] goto here;
-  [[unknown_attribute]] here:
+  [[unknown_attribute]] goto here; // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+  [[unknown_attribute]] here: // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
 
-  [[unknown_attribute]] try {
+  [[unknown_attribute]] try { // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
   } catch (...) {
   }
 
-  [[unknown_attribute]] return;
-
+  [[unknown_attribute]] return; // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+	 
 
   alignas(8) ; // expected-warning {{attribute aligned cannot be specified on a statement}}
   [[noreturn]] { } // expected-warning {{attribute noreturn cannot be specified on a statement}}
   [[noreturn]] if (0) { } // expected-warning {{attribute noreturn cannot be specified on a statement}}
   [[noreturn]] for (;;); // expected-warning {{attribute noreturn cannot be specified on a statement}}
   [[noreturn]] do { // expected-warning {{attribute noreturn cannot be specified on a statement}}
-    [[unavailable]] continue; // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
+    [[unavailable]] continue; // expected-warning {{unknown attribute 'unavailable' ignored}}
+  } while (0);
+  [[unknown_attributqqq]] while (0); // expected-warning {{unknown attribute 'unknown_attributqqq' ignored}}
+	// TODO: remove 'qqq' part and enjoy 'empty loop body' warning here (DiagnoseEmptyLoopBody)
+
+  [[unknown_attribute]] while (0); // expected-warning {{unknown attribute 'unknown_attribute' ignored}}
+
+  [[unused]] switch (i) { // expected-warning {{unknown attribute 'unused' ignored}}
+    [[uuid]] case 0: // expected-warning {{unknown attribute 'uuid' ignored}}
+    [[visibility]] default: // expected-warning {{unknown attribute 'visibility' ignored}}
+      [[carries_dependency]] break; // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+  }
+
+  [[fastcall]] goto there; // expected-warning {{unknown attribute 'fastcall' ignored}}
+  [[noinline]] there: // expected-warning {{unknown attribute 'noinline' ignored}}
+
+  [[lock_returned]] try { // expected-warning {{unknown attribute 'lock_returned' ignored}}
+  } catch (...) {
+  }
+
+  [[weakref]] return; // expected-warning {{unknown attribute 'weakref' ignored}}
+
+  [[carries_dependency]] ; // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+  [[carries_dependency]] { } // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+  [[carries_dependency]] if (0) { } // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+  [[carries_dependency]] for (;;); // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+  [[carries_dependency]] do { // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+    [[carries_dependency]] continue; // expected-warning {{attribute carries_dependency cannot be specified on a statement}} ignored}}
   } while (0);
-  [[unknown_attributqqq]] while (0); // TODO: remove 'qqq' part and enjoy 'empty loop body' warning here (DiagnoseEmptyLoopBody)
-  [[unknown_attribute]] while (0); // no warning here yet, just an unknown attribute
+  [[carries_dependency]] while (0); // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
 
-  [[unused]] switch (i) { // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
-    [[uuid]] case 0: // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
-    [[visibility]] default: // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
+  [[carries_dependency]] switch (i) { // expected-warning {{attribute carries_dependency cannot be specified on a statement}} ignored}}
+    [[carries_dependency]] case 0: // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
+    [[carries_dependency]] default: // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
       [[carries_dependency]] break; // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
   }
 
-  [[fastcall]] goto there; // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
-  [[noinline]] there: // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
+  [[carries_dependency]] goto here; // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
 
-  [[lock_returned]] try { // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
+  [[carries_dependency]] try { // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
   } catch (...) {
   }
 
-  [[weakref]] return; // TODO: only noreturn, alignas and carries_dependency are parsed in C++ 11 syntax at the moment, hence no warning here
+  [[carries_dependency]] return; // expected-warning {{attribute carries_dependency cannot be specified on a statement}}
 }

Modified: cfe/trunk/test/Parser/objcxx11-attributes.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-attributes.mm?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/test/Parser/objcxx11-attributes.mm (original)
+++ cfe/trunk/test/Parser/objcxx11-attributes.mm Tue Oct  2 20:56:22 2012
@@ -31,9 +31,13 @@
 
   // An attribute is OK.
   [[]];
-  [[int(), noreturn]]; // expected-warning {{attribute noreturn cannot be specified on a statement}}
-  [[class, test(foo 'x' bar),,,]];
-  [[bitand, noreturn]]; // expected-warning {{attribute noreturn cannot be specified on a statement}}
+  [[int(), noreturn]]; // expected-warning {{unknown attribute 'int' ignored}} \
+  // expected-warning {{attribute noreturn cannot be specified on a statement}}
+  [[class, test(foo 'x' bar),,,]]; // expected-warning {{unknown attribute 'test' ignored}}\
+  // expected-warning {{unknown attribute 'class' ignored}}
+
+  [[bitand, noreturn]]; // expected-warning {{attribute noreturn cannot be specified on a statement}} \
+  expected-warning {{unknown attribute 'bitand' ignored}} 
 
   // FIXME: Suppress vexing parse warning
   [[noreturn]]int(e)(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}} 
@@ -52,7 +56,11 @@
 }
 
 template<typename...Ts> void f(Ts ...x) {
-  [[test::foo(bar, baz)...]];
-  [[used(x)...]];
+  [[test::foo(bar, baz)...]]; // expected-error {{attribute 'foo' cannot be used as an attribute pack}} \
+  // expected-warning {{unknown attribute 'foo' ignored}}
+
+  [[used(x)...]]; // expected-error {{attribute 'used' cannot be used as an attribute pack}} \
+  // expected-warning {{unknown attribute 'used' ignored}}
+
   [[x...] { return [ X alloc ]; }() init];
 }

Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp?rev=165082&r1=165081&r2=165082&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp Tue Oct  2 20:56:22 2012
@@ -42,7 +42,7 @@
   switch (n % 2) {
     case 0:
       // FIXME: This should be typo-corrected, probably.
-      [[fallthrough]];
+      [[fallthrough]]; // expected-warning{{unknown attribute 'fallthrough' ignored}}
     case 2: // expected-warning{{unannotated fall-through}} expected-note{{clang::fallthrough}} expected-note{{break;}}
       [[clang::fallthrough]];
     case 1:





More information about the cfe-commits mailing list