aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2015-10-01 22:22:08 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2015-10-01 22:22:08 +0300
commit55fec44def29854be875ac68c304fc0c55b538ff (patch)
treec64ed0713431721871f5a948d0649009558ae7f7
parent0d1a8f7517eaed1d38d3827248e007634475bca4 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/name-lookup.h1
-rw-r--r--gcc/cp/parser.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/range-for30.C17
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" }
+}