Skip to content

Commit dedaccb

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. (cherry picked from commit 40e5636)
1 parent 21600f3 commit dedaccb

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
@@ -5062,6 +5062,15 @@ build_vec_init (tree base, tree maxindex, tree init,
50625062
{
50635063
if (!saw_non_const)
50645064
{
5065+
/* If we're not generating the loop, we don't need to reset the
5066+
iterator. */
5067+
if (cleanup_flags
5068+
&& !vec_safe_is_empty (*cleanup_flags))
5069+
{
5070+
auto l = (*cleanup_flags)->last ();
5071+
gcc_assert (TREE_PURPOSE (l) == iterator);
5072+
(*cleanup_flags)->pop ();
5073+
}
50655074
tree const_init = build_constructor (atype, const_vec);
50665075
return build2 (INIT_EXPR, atype, obase, const_init);
50675076
}
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)