]> granicus.if.org Git - clang/commitdiff
PR20634: add some more cases that can legitimately come after a struct declaration...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 13 Aug 2014 02:13:15 +0000 (02:13 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 13 Aug 2014 02:13:15 +0000 (02:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215520 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDeclCXX.cpp
test/Parser/atomic.c
test/Parser/cxx0x-decl.cpp
test/Parser/declarators.c

index d7ed2fa54b4a651bb6c9c690cfcd569d3c6567db..380b6d779408480304c618f4fe327cfacb846ac9 100644 (file)
@@ -1066,6 +1066,8 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::comma:              // __builtin_offsetof(struct foo{...} ,
   case tok::kw_operator:        // struct foo       operator  ++() {...}
   case tok::kw___declspec:      // struct foo {...} __declspec(...)
+  case tok::l_square:           // void f(struct f  [         3])
+  case tok::ellipsis:           // void f(struct f  ...       [Ns])
     return true;
   case tok::colon:
     return CouldBeBitfield;     // enum E { ... }   :         2;
@@ -1073,6 +1075,7 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::kw_const:           // struct foo {...} const     x;
   case tok::kw_volatile:        // struct foo {...} volatile  x;
   case tok::kw_restrict:        // struct foo {...} restrict  x;
+  case tok::kw__Atomic:         // struct foo {...} _Atomic   x;
   // Function specifiers
   // Note, no 'explicit'. An explicit function must be either a conversion
   // operator or a constructor. Either way, it can't have a return type.
@@ -1111,10 +1114,6 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
     if (!getLangOpts().CPlusPlus)
       return true;
     break;
-    // C++11 attributes
-  case tok::l_square: // enum E [[]] x
-    // Note, no tok::kw_alignas here; alignas cannot appertain to a type.
-    return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
   case tok::greater:
     // template<class T = class X>
     return getLangOpts().CPlusPlus;
@@ -1669,7 +1668,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   // Also enforce C++ [temp]p3:
   //   In a template-declaration which defines a class, no declarator
   //   is permitted.
+  //
+  // After a type-specifier, we don't expect a semicolon. This only happens in
+  // C, since definitions are not permitted in this context in C++.
   if (TUK == Sema::TUK_Definition &&
+      (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) &&
       (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
     if (Tok.isNot(tok::semi)) {
       const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
index 432deeb59c12f10d6e6b816ed02acb934c550180..07a83dddcd3c9abf28a1bd8d37045313eabe1bed 100644 (file)
@@ -33,3 +33,6 @@ typedef _Atomic(int) __attribute__((address_space(1))) atomic_addr_space_int;
 
 typedef _Atomic int __attribute__((vector_size(16))) atomic_vector_int;
 typedef _Atomic(int __attribute__((vector_size(16)))) atomic_vector_int;
+
+struct S
+_Atomic atomic_s_no_missing_semicolon;
index a0334cdde29231aece159b5e2ac0816a31115efb..2cd68252133c0bfffc7b1e701228658522145b01 100644 (file)
@@ -122,3 +122,8 @@ struct MemberComponentOrder : Base {
   void g() __attribute__(( )) override;
   void h() __attribute__(( )) override {}
 };
+
+void NoMissingSemicolonHere(struct S
+                            [3]);
+template<int ...N> void NoMissingSemicolonHereEither(struct S
+                                                     ... [N]);
index e3024206e4f76cabe9af3f1d54b5ee9bf22b4023..48936d59226968bb6d5a0d6c4abb642d926921ab 100644 (file)
@@ -150,3 +150,5 @@ enum E16 {
   A6;  // expected-error{{expected '= constant-expression' or end of enumerator definition}}
   A6a
 };
+
+int PR20634 = sizeof(struct { int n; } [5]);