[cfe-commits] r125722 - in /cfe/trunk: lib/Parse/ParseStmt.cpp test/Parser/for.cpp

Douglas Gregor dgregor at apple.com
Wed Feb 16 19:38:46 PST 2011


Author: dgregor
Date: Wed Feb 16 21:38:46 2011
New Revision: 125722

URL: http://llvm.org/viewvc/llvm-project?rev=125722&view=rev
Log:
Improve parser recovery in "for" statements, from Richard Smith!

Added:
    cfe/trunk/test/Parser/for.cpp   (with props)
Modified:
    cfe/trunk/lib/Parse/ParseStmt.cpp

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=125722&r1=125721&r2=125722&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Feb 16 21:38:46 2011
@@ -1039,7 +1039,6 @@
       Collection = ParseExpression();
     } else {
       Diag(Tok, diag::err_expected_semi_for);
-      SkipUntil(tok::semi);
     }
   } else {
     Value = ParseExpression();
@@ -1065,8 +1064,14 @@
       }
       Collection = ParseExpression();
     } else {
-      if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
-      SkipUntil(tok::semi);
+      if (!Value.isInvalid()) {
+        Diag(Tok, diag::err_expected_semi_for);
+      } else {
+        // Skip until semicolon or rparen, don't consume it.
+        SkipUntil(tok::r_paren, true, true);
+        if (Tok.is(tok::semi))
+          ConsumeToken();
+      }
     }
   }
   if (!ForEach) {
@@ -1074,6 +1079,8 @@
     // Parse the second part of the for specifier.
     if (Tok.is(tok::semi)) {  // for (...;;
       // no second part.
+    } else if (Tok.is(tok::r_paren)) {
+      // missing both semicolons.
     } else {
       ExprResult Second;
       if (getLang().CPlusPlus)
@@ -1088,12 +1095,16 @@
       SecondPart = Actions.MakeFullExpr(Second.get());
     }
 
+    if (Tok.isNot(tok::semi)) {
+      if (!SecondPartIsInvalid || SecondVar)
+        Diag(Tok, diag::err_expected_semi_for);
+      else
+        // Skip until semicolon or rparen, don't consume it.
+        SkipUntil(tok::r_paren, true, true);
+    }
+
     if (Tok.is(tok::semi)) {
       ConsumeToken();
-    } else {
-      if (!SecondPartIsInvalid || SecondVar) 
-        Diag(Tok, diag::err_expected_semi_for);
-      SkipUntil(tok::semi);
     }
 
     // Parse the third part of the for specifier.

Added: cfe/trunk/test/Parser/for.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/for.cpp?rev=125722&view=auto
==============================================================================
--- cfe/trunk/test/Parser/for.cpp (added)
+++ cfe/trunk/test/Parser/for.cpp Wed Feb 16 21:38:46 2011
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f1() {
+  int n;
+
+  for (n = 0; n < 10; n++);
+
+  for (n = 0 n < 10; n++); // expected-error {{expected ';' in 'for'}}
+  for (n = 0; n < 10 n++); // expected-error {{expected ';' in 'for'}}
+
+  for (int n = 0 n < 10; n++); // expected-error {{expected ';' in 'for'}}
+  for (int n = 0; n < 10 n++); // expected-error {{expected ';' in 'for'}}
+
+  for (n = 0 bool b = n < 10; n++); // expected-error {{expected ';' in 'for'}}
+  for (n = 0; bool b = n < 10 n++); // expected-error {{expected ';' in 'for'}}
+
+  for (n = 0 n < 10 n++); // expected-error 2{{expected ';' in 'for'}}
+
+  for (;); // expected-error {{expected ';' in 'for'}}
+}

Propchange: cfe/trunk/test/Parser/for.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/Parser/for.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/Parser/for.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list