Hi,

On 12/22/2014 10:12 PM, Jason Merrill wrote:
We could also peek for a colon in cp_parser_init_declarator after parsing the initializer, and give an error then.
I see.
For
the record, clang vs edg appear to handle this case differently: clang
considers it a wrong for loop, edg a wrong range-based for loop. Humm...

They're both right.  :)
Well, if they are both right, could we maybe do something closer to clang, instead, thus not consider the for loop a range-based for loop only because after the initializer there is a colon when the decl is error_mark_node? As an heuristics I think it may make sense in these borderline cases because the declarator is more restricted for a range-based. The below passes testing.

Thanks,
Paolo.

/////////////
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 219030)
+++ cp/parser.c (working copy)
@@ -10894,16 +10894,26 @@ cp_parser_for_init_statement (cp_parser* parser, t
       parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
       if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
        {
-         /* It is a range-for, consume the ':' */
-         cp_lexer_consume_token (parser->lexer);
-         is_range_for = true;
-         if (cxx_dialect < cxx11)
+         if (*decl == error_mark_node)
            {
-             pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
-                      "range-based %<for%> loops only available with "
-                      "-std=c++11 or -std=gnu++11");
-             *decl = error_mark_node;
+             /* Give an error and consume the ':' anyway for better
+                error recovery.  */
+             cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+             cp_lexer_consume_token (parser->lexer);
            }
+         else
+           {
+             /* It is a range-for, consume the ':' */
+             cp_lexer_consume_token (parser->lexer);
+             is_range_for = true;
+             if (cxx_dialect < cxx11)
+               {
+                 pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
+                          "range-based %<for%> loops only available with "
+                          "-std=c++11 or -std=gnu++11");
+                 *decl = error_mark_node;
+               }
+           }
        }
       else
          /* The ';' is not consumed yet because we told
Index: testsuite/g++.dg/cpp0x/range-for29.C
===================================================================
--- testsuite/g++.dg/cpp0x/range-for29.C        (revision 0)
+++ testsuite/g++.dg/cpp0x/range-for29.C        (working copy)
@@ -0,0 +1,10 @@
+// PR c++/63985
+// { dg-require-effective-target c++11 }
+
+int main()
+{
+  int arr;
+  for (int i = 5: arr)  // { dg-error "expected ';'" }
+    return 1;
+  return 0;
+}

Reply via email to