diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2015-10-01 22:22:08 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2015-10-01 22:22:08 +0300 |
commit | 55fec44def29854be875ac68c304fc0c55b538ff (patch) | |
tree | c64ed0713431721871f5a948d0649009558ae7f7 | |
parent | 0d1a8f7517eaed1d38d3827248e007634475bca4 (diff) | |
download | gcc-55fec44def29854be875ac68c304fc0c55b538ff.zip gcc-55fec44def29854be875ac68c304fc0c55b538ff.tar.gz gcc-55fec44def29854be875ac68c304fc0c55b538ff.tar.bz2 |
re PR c++/54430 ([C++11] For-Loop: Scope of iterating variable begins too early)
PR c++/54430
/cp
2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com>
PR c++/54430
* name-lookup.c (push_binding): Make non-static.
* name-lookup.h (push_binding): Declare it.
* parser.c (cp_parser_range_for): Use it, get the range
declaration away from the scope until the range expression
has been parsed, then restore the declaration.
/testsuite
2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com>
PR c++/54430
* g++.dg/cpp0x/range-for30.C: New.
From-SVN: r228354
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 2 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/range-for30.C | 17 |
6 files changed, 42 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb3a9b1..72c3bf9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com> + + PR c++/54430 + * name-lookup.c (push_binding): Make non-static. + * name-lookup.h (push_binding): Declare it. + * parser.c (cp_parser_range_for): Use it, get the range + declaration away from the scope until the range expression + has been parsed, then restore the declaration. + 2015-09-23 Ville Voutilainen <ville.voutilainen@gmail.com> Fix small typos in the coding rule enforcement warnings. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index baaf3e7..bd052a4 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -332,7 +332,7 @@ new_class_binding (tree name, tree value, tree type, cp_binding_level *scope) /* Make DECL the innermost binding for ID. The LEVEL is the binding level at which this declaration is being bound. */ -static void +void push_binding (tree id, tree decl, cp_binding_level* level) { cxx_binding *binding; diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 4b94192..82b5e53 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -88,6 +88,7 @@ struct GTY(()) cxx_saved_binding { extern tree identifier_type_value (tree); extern void set_identifier_type_value (tree, tree); +extern void push_binding (tree, tree, cp_binding_level*); extern void pop_binding (tree, tree); extern void pop_bindings_and_leave_scope (void); extern tree constructor_name (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1148156..8aeca40 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10725,6 +10725,11 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, { tree stmt, range_expr; + /* 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); + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { bool expr_non_constant_p; @@ -10733,6 +10738,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, else range_expr = cp_parser_expression (parser); + /* Put the range declaration back into scope. */ + if (range_decl != error_mark_node) + push_binding (DECL_NAME (range_decl), range_decl, current_binding_level); + /* If in template, STMT is converted to a normal for-statement at instantiation. If not, it is done just ahead. */ if (processing_template_decl) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7e2246..92625b3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-01 Ville Voutilainen <ville.voutilainen@gmail.com> + + PR c++/54430 + * g++.dg/cpp0x/range-for30.C: New. + 2015-10-01 Marek Polacek <polacek@redhat.com> PR c/65345 diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for30.C b/gcc/testsuite/g++.dg/cpp0x/range-for30.C new file mode 100644 index 0000000..d559d0f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/range-for30.C @@ -0,0 +1,17 @@ +// PR c++/54430 +// { dg-require-effective-target c++11 } + +struct A +{ + A(int) {} + int* begin() {return nullptr;} + int* end() {return nullptr;} +}; + +int main() +{ + int i[] = { 1, 2, 3, 4 }; + for (int i : i); + for (auto i : i); + for (A v : v); // { dg-error "not declared in this scope" } +} |