Skip to content

Commit

Permalink
c++: ICE initializing array of aggrs [PR117985]
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mpolacek committed Dec 17, 2024
1 parent d17b09c commit 40e5636
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
9 changes: 9 additions & 0 deletions gcc/cp/init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5109,6 +5109,15 @@ build_vec_init (tree base, tree maxindex, tree init,
{
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);
}
Expand Down
28 changes: 28 additions & 0 deletions gcc/testsuite/g++.dg/cpp0x/initlist-array23.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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{};
}
27 changes: 27 additions & 0 deletions gcc/testsuite/g++.dg/cpp0x/initlist-array24.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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{};
}

0 comments on commit 40e5636

Please sign in to comment.