N3994 proposes that people writing a range-based for should be able to
leave out the type and have it default to auto&&. I expect the proposal
to be voted into the working paper at the November standards meeting.
The second patch changes the existing range-for diagnostic from error to
pedwarn, for consistency with other C++11 features.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 00389876d06b03b2550f018e3f96a7b5525c9f38
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Jun 24 06:15:02 2014 -0400
N3994 Ranged-based for-loops: The Next Generation
* parser.c (cp_lexer_nth_token_is): New.
(cp_parser_for_init_statement): Allow "for (id : init)".
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c440c99..426dca4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -892,6 +892,12 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
}
static inline bool
+cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type)
+{
+ return cp_lexer_peek_nth_token (lexer, n)->type == type;
+}
+
+static inline bool
cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
{
return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword;
@@ -10607,6 +10613,23 @@ cp_parser_for_init_statement (cp_parser* parser, tree *decl)
bool is_range_for = false;
bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
+ {
+ /* N3994 -- for (id : init) ... */
+ if (cxx_dialect < cxx1z)
+ pedwarn (input_location, 0, "range-based for loop without a "
+ "type-specifier only available with "
+ "-std=c++1z or -std=gnu++1z");
+ tree name = cp_parser_identifier (parser);
+ tree type = cp_build_reference_type (make_auto (), /*rval*/true);
+ *decl = build_decl (input_location, VAR_DECL, name, type);
+ pushdecl (*decl);
+ cp_lexer_consume_token (parser->lexer);
+ return true;
+ }
+
+ /* A colon is used in range-based for. */
parser->colon_corrects_to_scope_p = false;
/* We're going to speculatively look for a declaration, falling back
diff --git a/gcc/testsuite/g++.dg/cpp1z/range-for1.C b/gcc/testsuite/g++.dg/cpp1z/range-for1.C
new file mode 100644
index 0000000..7e6d055
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/range-for1.C
@@ -0,0 +1,12 @@
+// { dg-options "-std=c++1z -pedantic-errors" }
+
+extern "C" int printf (const char *, ...);
+#include <initializer_list>
+
+int main()
+{
+ for (i : {1,2})
+ {
+ printf ("%d ", i);
+ }
+}
commit 90ba192ca14292be71459b1ca8a85aadfe9832e1
Author: Jason Merrill <ja...@redhat.com>
Date: Thu Jun 26 13:26:35 2014 -0400
* parser.c (cp_parser_for_init_statement): Change range-for error
to pedwarn.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 426dca4..a7edd41 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10647,9 +10647,9 @@ cp_parser_for_init_statement (cp_parser* parser, tree *decl)
is_range_for = true;
if (cxx_dialect < cxx11)
{
- error_at (cp_lexer_peek_token (parser->lexer)->location,
- "range-based %<for%> loops are not allowed "
- "in C++98 mode");
+ 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;
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for9.C b/gcc/testsuite/g++.dg/cpp0x/range-for9.C
index c51cbf9..6a50ec3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/range-for9.C
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for9.C
@@ -1,7 +1,6 @@
// Test for range-based for loop error in C++98 mode
-// { dg-do compile }
-// { dg-options "-std=c++98" }
+// { dg-do compile { target { ! c++11 } } }
void test()
{