[cfe-commits] r74264 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp test/SemaCXX/nested-name-spec.cpp
Chris Lattner
sabre at nondot.org
Thu Jun 25 21:27:48 PDT 2009
Author: lattner
Date: Thu Jun 25 23:27:47 2009
New Revision: 74264
URL: http://llvm.org/viewvc/llvm-project?rev=74264&view=rev
Log:
fix PR4452, a crash on invalid. The error recovery is still terrible in this case
but at least we don't crash :)
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/SemaCXX/nested-name-spec.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=74264&r1=74263&r2=74264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 25 23:27:47 2009
@@ -1193,7 +1193,7 @@
TemplateArgLocationList &TemplateArgLocations,
SourceLocation &RAngleLoc);
- void AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+ bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=74264&r1=74263&r2=74264&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 25 23:27:47 2009
@@ -85,8 +85,10 @@
= Actions.ActOnDependentTemplateName(TemplateKWLoc,
*Tok.getIdentifierInfo(),
Tok.getLocation(), SS);
- AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
- &SS, TemplateKWLoc, false);
+ if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
+ &SS, TemplateKWLoc, false))
+ break;
+
continue;
}
@@ -179,7 +181,9 @@
// because some clients (e.g., the parsing of class template
// specializations) still want to see the original template-id
// token.
- AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
+ if (AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(),
+ false))
+ break;
continue;
}
}
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=74264&r1=74263&r2=74264&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Jun 25 23:27:47 2009
@@ -621,7 +621,11 @@
/// replaced with a type annotation token. Otherwise, the
/// simple-template-id is always replaced with a template-id
/// annotation token.
-void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+///
+/// If an unrecoverable parse error occurs and no annotation token can be
+/// formed, this function returns true.
+///
+bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc,
bool AllowTypeAnnotation) {
@@ -644,14 +648,19 @@
TemplateArgIsType,
TemplateArgLocations,
RAngleLoc);
+
+ if (Invalid) {
+ // If we failed to parse the template ID but skipped ahead to a >, we're not
+ // going to be able to form a token annotation. Eat the '>' if present.
+ if (Tok.is(tok::greater))
+ ConsumeToken();
+ return true;
+ }
ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
TemplateArgIsType.data(),
TemplateArgs.size());
- if (Invalid) // FIXME: How to recover from a broken template-id?
- return;
-
// Build the annotation token.
if (TNK == TNK_Type_template && AllowTypeAnnotation) {
Action::TypeResult Type
@@ -659,8 +668,13 @@
LAngleLoc, TemplateArgsPtr,
&TemplateArgLocations[0],
RAngleLoc);
- if (Type.isInvalid()) // FIXME: better recovery?
- return;
+ if (Type.isInvalid()) {
+ // If we failed to parse the template ID but skipped ahead to a >, we're not
+ // going to be able to form a token annotation. Eat the '>' if present.
+ if (Tok.is(tok::greater))
+ ConsumeToken();
+ return true;
+ }
Tok.setKind(tok::annot_typename);
Tok.setAnnotationValue(Type.get());
@@ -705,6 +719,7 @@
// In case the tokens were cached, have Preprocessor replace them with the
// annotation token.
PP.AnnotateCachedTokens(Tok);
+ return false;
}
/// \brief Replaces a template-id annotation token with a type
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=74264&r1=74263&r2=74264&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Jun 25 23:27:47 2009
@@ -839,7 +839,8 @@
/// specifier, and another one to get the actual type inside
/// ParseDeclarationSpecifiers).
///
-/// This returns true if the token was annotated.
+/// This returns true if the token was annotated or an unrecoverable error
+/// occurs.
///
/// Note that this routine emits an error if you call it with ::new or ::delete
/// as the current tokens, so only call it in contexts where these are invalid.
@@ -934,7 +935,12 @@
if (TemplateNameKind TNK
= Actions.isTemplateName(*Tok.getIdentifierInfo(),
CurScope, Template, &SS))
- AnnotateTemplateIdToken(Template, TNK, &SS);
+ if (AnnotateTemplateIdToken(Template, TNK, &SS)) {
+ // If an unrecoverable error occurred, we need to return true here,
+ // because the token stream is in a damaged state. We may not return
+ // a valid identifier.
+ return Tok.isNot(tok::identifier);
+ }
}
// The current token, which is either an identifier or a
@@ -978,7 +984,8 @@
/// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
/// annotates C++ scope specifiers and template-ids. This returns
-/// true if the token was annotated.
+/// true if the token was annotated or there was an error that could not be
+/// recovered from.
///
/// Note that this routine emits an error if you call it with ::new or ::delete
/// as the current tokens, so only call it in contexts where these are invalid.
Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=74264&r1=74263&r2=74264&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Thu Jun 25 23:27:47 2009
@@ -171,3 +171,27 @@
X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
// expected-error{{C++ requires a type specifier for all declarations}} \
// expected-error{{only constructors take base initializers}}
+
+
+
+
+namespace somens {
+ struct a { };
+}
+
+template <typename T>
+class foo {
+};
+
+
+// PR4452
+// FIXME: This error recovery sucks.
+foo<somens:a> a2; // expected-error {{unexpected namespace name 'somens': expected expression}} \
+expected-error {{C++ requires a type specifier for all declarations}}
+
+// FIXME: This is bogus, there is no int here!
+somens::a a3 = a2; // expected-error {{cannot initialize 'a3' with an lvalue of type 'int'}}
+
+
+
+
More information about the cfe-commits
mailing list