summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-12-12 06:19:11 +0000
committerChris Lattner <sabre@nondot.org>2008-12-12 06:19:11 +0000
commitbc2d77cdf232ac0cda7ba5cf100582f4613d628e (patch)
treee27136bf3755e91b8a70529a1421b62f4a4175dc /clang/lib/Parse/ParseStmt.cpp
parentd8980509b34da2399b197fc0bd01cd20ee16918b (diff)
downloadbcm5719-llvm-bc2d77cdf232ac0cda7ba5cf100582f4613d628e.tar.gz
bcm5719-llvm-bc2d77cdf232ac0cda7ba5cf100582f4613d628e.zip
merge recovery-2.c into recovery-3.c.
Substantially improve error recovery after broken if conditions by parsing the full if when we have a semantic error instead of using parser recovery techniques to recover from a semantic error. This fixes rdar://6094870 - spurious error after invalid 'if' condition llvm-svn: 60929
Diffstat (limited to 'clang/lib/Parse/ParseStmt.cpp')
-rw-r--r--clang/lib/Parse/ParseStmt.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index bde4a502178..263079f1380 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -448,20 +448,28 @@ Parser::OwningStmtResult Parser::ParseIfStatement() {
ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
// Parse the condition.
+ SourceLocation LParenLoc = ConsumeParen();
+
OwningExprResult CondExp(Actions);
- if (getLang().CPlusPlus) {
- SourceLocation LParenLoc = ConsumeParen();
+ if (getLang().CPlusPlus)
CondExp = ParseCXXCondition();
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
- } else {
- CondExp = ParseSimpleParenExpression();
- }
-
- if (CondExp.isInvalid()) {
+ else
+ CondExp = ParseExpression();
+
+ // If the parser was confused by the condition and we don't have a ')', try to
+ // recover by skipping ahead to a semi and bailing out. If condexp is
+ // semantically invalid but we have well formed code, keep going.
+ if (CondExp.isInvalid() && Tok.isNot(tok::r_paren)) {
SkipUntil(tok::semi);
- return StmtError();
+ // Skipping may have stopped if it found the containing ')'. If so, we can
+ // continue parsing the if statement.
+ if (Tok.isNot(tok::r_paren))
+ return StmtError();
}
+ // Otherwise the condition is valid or the rparen is present.
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
// if the body isn't a compound statement to avoid push/pop in common cases.
@@ -521,6 +529,11 @@ Parser::OwningStmtResult Parser::ParseIfStatement() {
}
IfScope.Exit();
+
+ // If the condition was invalid, discard the if statement. We could recover
+ // better by replacing it with a valid expr, but don't do that yet.
+ if (CondExp.isInvalid())
+ return StmtError();
// If the then or else stmt is invalid and the other is valid (and present),
// make turn the invalid one into a null stmt to avoid dropping the other
OpenPOWER on IntegriCloud