summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-20 19:07:56 +0000
committerChris Lattner <sabre@nondot.org>2008-04-20 19:07:56 +0000
commit14cd1ee95f4bec33199857fd355373c474da795c (patch)
tree5dbc3f86717a808d70372ead2f3adf3a112cbb71
parent4885b976644691a4f4549cb0663fdc9b133b9be7 (diff)
downloadbcm5719-llvm-14cd1ee95f4bec33199857fd355373c474da795c.tar.gz
bcm5719-llvm-14cd1ee95f4bec33199857fd355373c474da795c.zip
Two improvements to initializer parsing:
1. If we hit a semantic error, try harder to recover to emit diagnostics for later initializer errors (PR2241). 2. Don't leak parsed initializers on an error. llvm-svn: 49998
-rw-r--r--clang/lib/Parse/ParseInit.cpp24
-rw-r--r--clang/test/Parser/recovery-2.c8
2 files changed, 27 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 45cf86e5b44..c40fe88c217 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -201,12 +201,21 @@ Parser::ExprResult Parser::ParseInitializer() {
SubElt = ParseInitializerWithPotentialDesignator();
// If we couldn't parse the subelement, bail out.
- if (SubElt.isInvalid) {
- InitExprsOk = false;
- SkipUntil(tok::r_brace, false, true);
- break;
- } else
+ if (!SubElt.isInvalid) {
InitExprs.push_back(SubElt.Val);
+ } else {
+ InitExprsOk = false;
+
+ // We have two ways to try to recover from this error: if the code looks
+ // gramatically ok (i.e. we have a comma comming up) try to continue
+ // parsing the rest of the initializer. This allows us to emit
+ // diagnostics for later elements that we find. If we don't see a comma,
+ // assume there is a parse error, and just skip to recover.
+ if (Tok.isNot(tok::comma)) {
+ SkipUntil(tok::r_brace, false, true);
+ break;
+ }
+ }
// If we don't have a comma continued list, we're done.
if (Tok.isNot(tok::comma)) break;
@@ -220,6 +229,11 @@ Parser::ExprResult Parser::ParseInitializer() {
if (InitExprsOk && Tok.is(tok::r_brace))
return Actions.ActOnInitList(LBraceLoc, &InitExprs[0], InitExprs.size(),
ConsumeBrace());
+
+ // Delete any parsed subexpressions.
+ for (unsigned i = 0, e = InitExprs.size(); i != e; ++i)
+ Actions.DeleteExpr(InitExprs[i]);
+
// Match the '}'.
MatchRHSPunctuation(tok::r_brace, LBraceLoc);
return ExprResult(true); // an error occurred.
diff --git a/clang/test/Parser/recovery-2.c b/clang/test/Parser/recovery-2.c
new file mode 100644
index 00000000000..4451232dca8
--- /dev/null
+++ b/clang/test/Parser/recovery-2.c
@@ -0,0 +1,8 @@
+// RUN: clang -fsyntax-only -verify -pedantic %s
+
+
+// PR2241
+float f[] = {
+ 1e, // expected-error {{exponent}}
+ 1ee0 // expected-error {{exponent}}
+};
OpenPOWER on IntegriCloud