From 8402429e47e3e13b4d505c4746ea2d75d1701aaf Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 13 Aug 2014 02:13:15 +0000 Subject: [PATCH] PR20634: add some more cases that can legitimately come after a struct declaration to our list of special cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Parse/ParseDeclCXX.cpp | 11 +++++++---- test/Parser/atomic.c | 3 +++ test/Parser/cxx0x-decl.cpp | 5 +++++ test/Parser/declarators.c | 2 ++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d7ed2fa54b..380b6d7794 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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 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(); diff --git a/test/Parser/atomic.c b/test/Parser/atomic.c index 432deeb59c..07a83dddcd 100644 --- a/test/Parser/atomic.c +++ b/test/Parser/atomic.c @@ -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; diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp index a0334cdde2..2cd6825213 100644 --- a/test/Parser/cxx0x-decl.cpp +++ b/test/Parser/cxx0x-decl.cpp @@ -122,3 +122,8 @@ struct MemberComponentOrder : Base { void g() __attribute__(( )) override; void h() __attribute__(( )) override {} }; + +void NoMissingSemicolonHere(struct S + [3]); +template void NoMissingSemicolonHereEither(struct S + ... [N]); diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c index e3024206e4..48936d5922 100644 --- a/test/Parser/declarators.c +++ b/test/Parser/declarators.c @@ -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]); -- 2.40.0