diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-15 14:38:31 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-15 14:38:31 -0400 |
commit | 37a92c0ca231f3767dd905f155fb8d9a20369f2b (patch) | |
tree | 8579794f6a66c6d0a43e524e60b1dbd9780d1d22 | |
parent | aa30dfadf3234caa8a29ef23ddc5932101a0e430 (diff) | |
download | gcc-37a92c0ca231f3767dd905f155fb8d9a20369f2b.zip gcc-37a92c0ca231f3767dd905f155fb8d9a20369f2b.tar.gz gcc-37a92c0ca231f3767dd905f155fb8d9a20369f2b.tar.bz2 |
PR c++/71604 - type definition in range-based for
PR c++/54430
* parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly.
(cp_parser_simple_declaration): Diagnose type definition in
for-range-declaration.
From-SVN: r238391
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/range-for31.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/range-for8.C | 4 |
4 files changed, 36 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d0d855e..14bcf8e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2016-07-15 Jason Merrill <jason@redhat.com> + PR c++/71604 + PR c++/54430 + * parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly. + (cp_parser_simple_declaration): Diagnose type definition in + for-range-declaration. + PR c++/71711 * operators.def: Add *_FOLD_EXPR. * cp-tree.h (FOLD_EXPR_P): Parenthesize. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3e865b0..0a0f67b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11187,11 +11187,17 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, bool ivdep) { tree stmt, range_expr; + cxx_binding *binding = NULL; + tree name = NULL_TREE; /* Get the range declaration momentarily out of the way so that the range expression doesn't clash with it. */ if (range_decl != error_mark_node) - pop_binding (DECL_NAME (range_decl), range_decl); + { + name = DECL_NAME (range_decl); + binding = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding->previous; + } if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { @@ -11203,7 +11209,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, /* Put the range declaration back into scope. */ if (range_decl != error_mark_node) - push_binding (DECL_NAME (range_decl), range_decl, current_binding_level); + { + binding->previous = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding; + } /* If in template, STMT is converted to a normal for-statement at instantiation. If not, it is done just ahead. */ @@ -12437,8 +12446,15 @@ cp_parser_simple_declaration (cp_parser* parser, if (token->type == CPP_COMMA) /* will be consumed next time around */; /* If it's a `;', we are done. */ - else if (token->type == CPP_SEMICOLON || maybe_range_for_decl) + else if (token->type == CPP_SEMICOLON) break; + else if (maybe_range_for_decl) + { + if (declares_class_or_enum && token->type == CPP_COLON) + permerror (decl_specifiers.locations[ds_type_spec], + "types may not be defined in a for-range-declaration"); + break; + } /* Anything else is an error. */ else { diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for31.C b/gcc/testsuite/g++.dg/cpp0x/range-for31.C new file mode 100644 index 0000000..833f510 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/range-for31.C @@ -0,0 +1,9 @@ +// PR c++/71604 +// { dg-do compile { target c++11 } } + +void foo () +{ + int a[2] = { 1, 2 }; + for (struct S { S (int) {} } S : a) // { dg-error "types may not be defined" } + ; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for8.C b/gcc/testsuite/g++.dg/cpp0x/range-for8.C index a389f66..38fe456 100644 --- a/gcc/testsuite/g++.dg/cpp0x/range-for8.C +++ b/gcc/testsuite/g++.dg/cpp0x/range-for8.C @@ -7,9 +7,9 @@ void test() { - for (struct S { } *x : { (S*)0, (S*)0 } ) + for (struct S { } *x : { (S*)0, (S*)0 } ) // { dg-error "types may not be defined" } ; - for (struct S { } x : { S(), S() } ) + for (struct S { } x : { S(), S() } ) // { dg-error "types may not be defined" } ; } |