[cfe-commits] r60929 - in /cfe/trunk: lib/Parse/ParseStmt.cpp test/Parser/recovery-2.c test/Parser/recovery-3.c
Chris Lattner
sabre at nondot.org
Thu Dec 11 22:19:12 PST 2008
Author: lattner
Date: Fri Dec 12 00:19:11 2008
New Revision: 60929
URL: http://llvm.org/viewvc/llvm-project?rev=60929&view=rev
Log:
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
Removed:
cfe/trunk/test/Parser/recovery-2.c
Modified:
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/test/Parser/recovery-3.c
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=60929&r1=60928&r2=60929&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Dec 12 00:19:11 2008
@@ -448,20 +448,28 @@
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 @@
}
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
Removed: cfe/trunk/test/Parser/recovery-2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/recovery-2.c?rev=60928&view=auto
==============================================================================
--- cfe/trunk/test/Parser/recovery-2.c (original)
+++ cfe/trunk/test/Parser/recovery-2.c (removed)
@@ -1,8 +0,0 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
-
-
-// PR2241
-float f[] = {
- 1e, // expected-error {{exponent}}
- 1ee0 // expected-error {{exponent}}
-};
Modified: cfe/trunk/test/Parser/recovery-3.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/recovery-3.c?rev=60929&r1=60928&r2=60929&view=diff
==============================================================================
--- cfe/trunk/test/Parser/recovery-3.c (original)
+++ cfe/trunk/test/Parser/recovery-3.c Fri Dec 12 00:19:11 2008
@@ -1,5 +1,12 @@
// RUN: clang -fsyntax-only -verify -pedantic %s
+// PR2241
+float test2241[] = {
+ 1e, // expected-error {{exponent}}
+ 1ee0 // expected-error {{exponent}}
+};
+
+
// Testcase derived from PR2692
static char *f (char * (*g) (char **, int), char **p, ...) {
char *s;
@@ -12,3 +19,28 @@
} // expected-error {{expected external declaration}}
+// rdar://6094870
+int test(int) {
+ struct { int i; } x;
+
+ if (x.hello) // expected-error {{no member named 'hello'}}
+ test(0);
+ else
+ ;
+
+ if (x.hello == 0) // expected-error {{no member named 'hello'}}
+ test(0);
+ else
+ ;
+
+ if ((x.hello == 0)) // expected-error {{no member named 'hello'}}
+ test(0);
+ else
+ ;
+
+ if (x.i == 0)) // expected-error {{expected expression}}
+ test(0);
+ else
+ ;
+}
+
More information about the cfe-commits
mailing list