Bug 54430 - [C++11] For-Loop: Scope of iterating variable begins too early
Summary: [C++11] For-Loop: Scope of iterating variable begins too early
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: 6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, rejects-valid, wrong-code
: 57493 65201 67584 69784 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-08-30 23:08 UTC by mrks
Modified: 2016-07-21 06:16 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.8.2
Last reconfirmed: 2014-03-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mrks 2012-08-30 23:08:35 UTC
The scope of the iterating variable begins too early, i.e. it is already available in the expression of the rhs.
This is a problem if the rhs expression includes the same identifier which is shadowed by this issue.

Simple case:
  int i[] = { };
  for (int i : i);

fails to compile because the rhs 'i' will be the same as the lhs 'i' which is not a valid expression for the range-based for-loop.

The range-based for-loop is equivalent to some for-construct. According to the standard the above should compile because the scope of the lhs begins inside the body of this substituted for-loop.


Just for completeness: The Evil case:
  class MyType {
    std::vector<MyType*> vec;
  public:
    const std::vector<MyType*>& foo() { return vec; }
  };
  
  MyType * t = new MyType;
  for (MyType * t : t->foo());

this will not refuse to compile since everything is well-formed. The real problem is that foo isn't called on the previously defined t but on the new uninitialized t.
Comment 1 Thomas Lamb 2014-03-28 14:15:05 UTC
Just hit this bug in GCC 4.9. Again, the lhs side has scope before the rhs has been evaluated, which is against the standardese in section 6.5.4 of both N3936 and N3291.
Comment 2 Paul Pluzhnikov 2014-03-28 14:16:51 UTC
*** Bug 57493 has been marked as a duplicate of this bug. ***
Comment 3 Paul Pluzhnikov 2014-03-28 14:17:43 UTC
From PR57493: Google ref: b/9229787
Comment 4 Akim Demaille 2015-08-09 07:49:38 UTC
I hit that one too with 5.2.
Comment 6 Mikhail Maltsev 2015-08-17 00:52:42 UTC
*** Bug 65201 has been marked as a duplicate of this bug. ***
Comment 7 Jonathan Wakely 2015-09-15 10:15:57 UTC
*** Bug 67584 has been marked as a duplicate of this bug. ***
Comment 8 ville 2015-10-01 19:22:39 UTC
Author: ville
Date: Thu Oct  1 19:22:08 2015
New Revision: 228354

URL: https://gcc.gnu.org/viewcvs?rev=228354&root=gcc&view=rev
Log:
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.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/range-for30.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/cp/name-lookup.h
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 Ville Voutilainen 2015-10-01 19:23:55 UTC
Fixed on trunk.
Comment 10 Jonathan Wakely 2016-02-12 13:13:24 UTC
*** Bug 69784 has been marked as a duplicate of this bug. ***
Comment 11 Jason Merrill 2016-07-15 18:39:03 UTC
Author: jason
Date: Fri Jul 15 18:38:31 2016
New Revision: 238391

URL: https://gcc.gnu.org/viewcvs?rev=238391&root=gcc&view=rev
Log:
	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.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/range-for31.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/g++.dg/cpp0x/range-for8.C
Comment 12 Jason Merrill 2016-07-21 06:16:18 UTC
Author: jason
Date: Thu Jul 21 06:15:43 2016
New Revision: 238569

URL: https://gcc.gnu.org/viewcvs?rev=238569&root=gcc&view=rev
Log:
	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.

Added:
    branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp0x/range-for31.C
Modified:
    branches/gcc-6-branch/gcc/cp/ChangeLog
    branches/gcc-6-branch/gcc/cp/parser.c
    branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp0x/range-for8.C