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.
{
if (!saw_non_const)
{
+ /* If we're not generating the loop, we don't need to reset the
+ iterator. */
+ if (cleanup_flags
+ && !vec_safe_is_empty (*cleanup_flags))
+ {
+ auto l = (*cleanup_flags)->last ();
+ gcc_assert (TREE_PURPOSE (l) == iterator);
+ (*cleanup_flags)->pop ();
+ }
tree const_init = build_constructor (atype, const_vec);
return build2 (INIT_EXPR, atype, obase, const_init);
}
--- /dev/null
+// PR c++/117985
+// { dg-do compile { target c++11 } }
+
+struct _Vector_impl {
+ constexpr
+ _Vector_impl() {}
+};
+struct _Vector_base {
+ ~_Vector_base();
+ _Vector_impl _M_impl;
+};
+struct vector : private _Vector_base {};
+struct string {
+ string();
+};
+struct VEC {
+ vector pane{};
+};
+struct FOO {
+ VEC screen[1]{};
+ string debug_name;
+};
+
+int
+main ()
+{
+ FOO{};
+}
--- /dev/null
+// PR c++/117985
+// { dg-do compile { target c++20 } }
+
+struct _Vector_impl {
+ constexpr _Vector_impl() {}
+};
+struct _Vector_base {
+ constexpr ~_Vector_base() {}
+ _Vector_impl _M_impl;
+};
+struct vector : private _Vector_base {};
+struct string {
+ string();
+};
+struct VEC {
+ vector pane{};
+};
+struct FOO {
+ VEC screen[1]{};
+ string debug_name;
+};
+
+int
+main ()
+{
+ FOO{};
+}