]> granicus.if.org Git - clang/commitdiff
SemaCXX: Don't crash when annotation tokens show up before the tag name
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Dec 2014 02:14:26 +0000 (02:14 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Dec 2014 02:14:26 +0000 (02:14 +0000)
Clang has a hack to accept definitions of structs with tag names which
have the same name as intrinsics.  However, this hack didn't guard
against annotation tokens showing up in the token stream.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224909 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDeclCXX.cpp
test/SemaCXX/libstdcxx_is_pod_hack.cpp

index e2a51ecfca4034b856e729b238abe5f3093dbb6f..14fe9f7cf37f51d7bf68435869b498f540b438c3 100644 (file)
@@ -1244,7 +1244,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   SourceLocation AttrFixitLoc = Tok.getLocation();
 
   if (TagType == DeclSpec::TST_struct &&
-      !Tok.is(tok::identifier) &&
+      Tok.isNot(tok::identifier) &&
+      !Tok.isAnnotation() &&
       Tok.getIdentifierInfo() &&
       (Tok.is(tok::kw___is_abstract) ||
        Tok.is(tok::kw___is_arithmetic) ||
index 1ba3721c8c2ef8e8849227a31b035ae69611fc39..8d187124f013a2e743a95b604e278969a2375d9a 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 // This is a test for an egregious hack in Clang that works around
 // issues with GCC's evolution. libstdc++ 4.2.x uses __is_pod as an
@@ -7,7 +7,7 @@
 // a keyword *unless* it is introduced following the struct keyword.
 
 template<typename T>
-struct __is_pod {
+struct __is_pod { // expected-warning {{keyword '__is_pod' will be made available as an identifier}}
   __is_pod() {}
 };
 
@@ -15,7 +15,7 @@ __is_pod<int> ipi;
 
 // Ditto for __is_same.
 template<typename T>
-struct __is_same {
+struct __is_same { // expected-warning {{keyword '__is_same' will be made available as an identifier}}
 };
 
 __is_same<int> isi;
@@ -24,7 +24,7 @@ __is_same<int> isi;
 // trait in Embarcadero's compiler but is used as an identifier in
 // libstdc++.
 struct test_is_signed {
-  static const bool __is_signed = true;
+  static const bool __is_signed = true; // expected-warning {{keyword '__is_signed' will be made available as an identifier}}
 };
 
 bool check_signed = test_is_signed::__is_signed;
@@ -36,6 +36,13 @@ void foo() {
   bool b = __is_pod(int);
   must_be_true<__is_pod(int)> mbt;
 }
+
+// expected-warning@+1 {{declaration does not declare anything}}
+struct // expected-error {{declaration of anonymous struct must be a definition}}
+#pragma pack(pop)
+    S {
+};
+
 #if !__has_feature(is_pod)
 #  error __is_pod should still be available.
 #endif