diff options
author | Chris Lattner <sabre@nondot.org> | 2008-04-20 19:07:56 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-04-20 19:07:56 +0000 |
commit | 14cd1ee95f4bec33199857fd355373c474da795c (patch) | |
tree | 5dbc3f86717a808d70372ead2f3adf3a112cbb71 | |
parent | 4885b976644691a4f4549cb0663fdc9b133b9be7 (diff) | |
download | bcm5719-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.cpp | 24 | ||||
-rw-r--r-- | clang/test/Parser/recovery-2.c | 8 |
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}} +}; |