c++: aggregate prvalue as for range [PR106230]

Since my PR94041 work on temporary lifetime in aggregate initialization, we
end up calling build_vec_init to initialize the reference-extended temporary
for the artificial __for_range variable.  And build_vec_init uses
finish_for_stmt to implement its loop.  That function assumes that if
__for_range is in current_binding_level, we're finishing a range-for, and we
should fix up the variable as it goes out of scope.  But when called from
build_vec_init we aren't finishing a range-for, and do_poplevel doesn't
remove the variable from scope because stmts_are_full_exprs_p is false.  So
let's check that here as well, and leave the DECL_NAME alone.

	PR c++/106230

gcc/cp/ChangeLog:

	* semantics.cc (finish_for_stmt): Check stmts_are_full_exprs_p.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/range-for38.C: New test.
This commit is contained in:
Jason Merrill 2022-07-25 11:13:31 -04:00
parent 3387ec2651
commit 60954a06ce
2 changed files with 21 additions and 0 deletions

View File

@ -1398,6 +1398,11 @@ finish_for_stmt (tree for_stmt)
add_stmt (do_poplevel (scope));
/* If we're being called from build_vec_init, don't mess with the names of
the variables for an enclosing range-for. */
if (!stmts_are_full_exprs_p ())
return;
for (int i = 0; i < 3; i++)
if (range_for_decl[i])
DECL_NAME (range_for_decl[i])

View File

@ -0,0 +1,16 @@
// PR c++/106230
// { dg-do compile { target c++11 } }
struct A {
A();
operator int();
};
template <int N> struct array {
A elts[N];
A *begin();
A *end();
};
void fn() {
for (int i : array<4>{})
;
}