Skip to content

Commit 40e5636

Browse files
committed
c++: ICE initializing array of aggrs [PR117985]
This crash started with my r12-7803 but I believe the problem lies elsewhere. build_vec_init has cleanup_flags whose purpose is -- if I grok this correctly -- to avoid destructing an object multiple times. Let's say we are initializing an array of A. Then we might end up in a scenario similar to initlist-eh1.C: try { call A::A in a loop // #0 try { call a fn using the array } finally { // #1 call A::~A in a loop } } catch { // #2 call A::~A in a loop } cleanup_flags makes us emit a statement like D.3048 = 2; at #0 to disable performing the cleanup at #2, since #1 will take care of the destruction of the array. But if we are not emitting the loop because we can use a constant initializer (and use a single { a, b, ...}), we shouldn't generate the statement resetting the iterator to its initial value. Otherwise we crash in gimplify_var_or_parm_decl because it gets the stray decl D.3048. PR c++/117985 gcc/cp/ChangeLog: * init.cc (build_vec_init): Pop CLEANUP_FLAGS if we're not generating the loop. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array23.C: New test. * g++.dg/cpp0x/initlist-array24.C: New test.
1 parent d17b09c commit 40e5636

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

gcc/cp/init.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5109,6 +5109,15 @@ build_vec_init (tree base, tree maxindex, tree init,
51095109
{
51105110
if (!saw_non_const)
51115111
{
5112+
/* If we're not generating the loop, we don't need to reset the
5113+
iterator. */
5114+
if (cleanup_flags
5115+
&& !vec_safe_is_empty (*cleanup_flags))
5116+
{
5117+
auto l = (*cleanup_flags)->last ();
5118+
gcc_assert (TREE_PURPOSE (l) == iterator);
5119+
(*cleanup_flags)->pop ();
5120+
}
51125121
tree const_init = build_constructor (atype, const_vec);
51135122
return build2 (INIT_EXPR, atype, obase, const_init);
51145123
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// PR c++/117985
2+
// { dg-do compile { target c++11 } }
3+
4+
struct _Vector_impl {
5+
constexpr
6+
_Vector_impl() {}
7+
};
8+
struct _Vector_base {
9+
~_Vector_base();
10+
_Vector_impl _M_impl;
11+
};
12+
struct vector : private _Vector_base {};
13+
struct string {
14+
string();
15+
};
16+
struct VEC {
17+
vector pane{};
18+
};
19+
struct FOO {
20+
VEC screen[1]{};
21+
string debug_name;
22+
};
23+
24+
int
25+
main ()
26+
{
27+
FOO{};
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// PR c++/117985
2+
// { dg-do compile { target c++20 } }
3+
4+
struct _Vector_impl {
5+
constexpr _Vector_impl() {}
6+
};
7+
struct _Vector_base {
8+
constexpr ~_Vector_base() {}
9+
_Vector_impl _M_impl;
10+
};
11+
struct vector : private _Vector_base {};
12+
struct string {
13+
string();
14+
};
15+
struct VEC {
16+
vector pane{};
17+
};
18+
struct FOO {
19+
VEC screen[1]{};
20+
string debug_name;
21+
};
22+
23+
int
24+
main ()
25+
{
26+
FOO{};
27+
}

0 commit comments

Comments
 (0)