]> granicus.if.org Git - clang/commitdiff
Parse: Don't crash during parsing if we lack a simple-type-specifier
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 22 Sep 2013 01:24:26 +0000 (01:24 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 22 Sep 2013 01:24:26 +0000 (01:24 +0000)
Summary:
Parsing cast expressions during error recovery can put us in a bad
state.  Check to see if the token for a simple-type-specifier makes
sense before further parsing.

Fixes PR17255.

Reviewers: rsmith, doug.gregor, CornedBee, eli.friedman

CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1696

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

lib/Parse/ParseExpr.cpp
lib/Sema/SemaDecl.cpp
test/Parser/cxx-decl.cpp

index bbc7dadde8f3a2747062f8b148f40f2a7df4bed4..9719d857f39e1317d9388c73ca6c9da773a0a425 100644 (file)
@@ -1049,6 +1049,11 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
     //                     simple-type-specifier braced-init-list
     //
     DeclSpec DS(AttrFactory);
+
+    if (!Actions.isSimpleTypeSpecifier(Tok.getKind()))
+      // This can happen if we tried to recover from errors earlier.
+      return ExprError();
+
     ParseCXXSimpleTypeSpecifier(DS);
     if (Tok.isNot(tok::l_paren) &&
         (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace)))
index 68762e97fa2b07e5ce39b9808cf68306f5ea8a54..92400df00ce2ca51da761663dc0989647c2a721e 100644 (file)
@@ -108,6 +108,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
   case tok::kw_char16_t:
   case tok::kw_char32_t:
   case tok::kw_typeof:
+  case tok::annot_decltype:
   case tok::kw_decltype:
     return getLangOpts().CPlusPlus;
 
index 281e33b20f8b1d19e7686c6560ff6a026382dfe2..c33a8d561cafc76f217ae2878bb0c5dc0eebe878 100644 (file)
@@ -209,6 +209,14 @@ namespace PR5066 {
   using T = int (*T)(); // expected-error {{type-id cannot have a name}} expected-warning {{C++11}}
 }
 
+namespace PR17255 {
+void foo() {
+  typename A::template B<>; // expected-error {{use of undeclared identifier 'A'}} \
+                            // expected-error {{expected a qualified name after 'typename'}} \
+                            // expected-warning {{'template' keyword outside of a template}}
+}
+}
+
 // PR8380
 extern ""      // expected-error {{unknown linkage language}}
 test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \