Hi rsmith, doug.gregor, CornedBee, eli.friedman,
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.
http://llvm-reviews.chandlerc.com/D1696
Files:
lib/Parse/ParseExpr.cpp
lib/Sema/SemaDecl.cpp
test/Parser/cxx-decl.cpp
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1048,6 +1048,11 @@
// 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: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -108,6 +108,7 @@
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: test/Parser/cxx-decl.cpp
===================================================================
--- test/Parser/cxx-decl.cpp
+++ test/Parser/cxx-decl.cpp
@@ -209,6 +209,14 @@
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}} \
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1048,6 +1048,11 @@
// 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: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -108,6 +108,7 @@
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: test/Parser/cxx-decl.cpp
===================================================================
--- test/Parser/cxx-decl.cpp
+++ test/Parser/cxx-decl.cpp
@@ -209,6 +209,14 @@
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}} \
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits