[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