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;
+}