From ff989a8b1d3cf52131c179fceea656d7977e5b3c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sun, 22 Sep 2013 01:24:26 +0000 Subject: [PATCH] Parse: Don't crash during parsing if we lack a simple-type-specifier 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 | 5 +++++ lib/Sema/SemaDecl.cpp | 1 + test/Parser/cxx-decl.cpp | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index bbc7dadde8..9719d857f3 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -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))) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 68762e97fa..92400df00c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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; diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp index 281e33b20f..c33a8d561c 100644 --- a/test/Parser/cxx-decl.cpp +++ b/test/Parser/cxx-decl.cpp @@ -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}} \ -- 2.50.1