diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 10 | ||||
-rw-r--r-- | clang/test/Parser/cxx0x-attributes.cpp | 4 |
2 files changed, 14 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 14fe9f7cf37..4377a782864 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2706,6 +2706,16 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // and the only possible place for them to appertain // to the class would be between class-key and class-name. CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc); + + // ParseClassSpecifier() does only a superficial check for attributes before + // deciding to call this method. For example, for + // `class C final alignas ([l) {` it will decide that this looks like a + // misplaced attribute since it sees `alignas '(' ')'`. But the actual + // attribute parsing code will try to parse the '[' as a constexpr lambda + // and consume enough tokens that the alignas parsing code will eat the + // opening '{'. So bail out if the next token isn't one we expect. + if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) + return; } if (Tok.is(tok::colon)) { diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index e366d8582e8..02791f4f54c 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -330,3 +330,7 @@ namespace { [[deprecated()]] void foo(); // expected-error {{parentheses must be omitted if 'deprecated' attribute's argument list is empty}} [[gnu::deprecated()]] void quux(); } + +// The diagnostics here don't matter much, this just shouldn't crash: +class C final [[deprecated(l]] {}; // expected-error {{use of undeclared identifier}} expected-error {{expected ']'}} expected-error {{an attribute list cannot appear here}} +class C final alignas ([l) {}; // expected-error {{expected ';' after class}} |