On 2/3/25 8:29 AM, Simon Martin wrote:
Hi Jason,

On 16 Jan 2025, at 23:28, Jason Merrill wrote:

On 10/19/24 5:09 AM, Simon Martin wrote:
We currently ICE in checking mode with cxx_dialect < 17 on the
following
valid code

=== cut here ===
struct X {
    X(const X&) {}
};
extern X x;
void foo () {
    new X[1]{x};
}
=== cut here ===

The problem is that cp_gimplify_expr gcc_checking_asserts that a
TARGET_EXPR is not TARGET_EXPR_ELIDING_P (or cannot be elided), while
in
this case with cxx_dialect < 17, it is TARGET_EXPR_ELIDING_P but we
have
not even tried to elide.

This patch relaxes that gcc_checking_assert to not fail when using
cxx_dialect < 17 and -fno-elide-constructors (I considered being more

clever at setting TARGET_EXPR_ELIDING_P appropriately but it looks

more
risky and not worth the extra complexity for a checking assert).

The problem is that in that case we end up with two copy constructor
calls instead of one: one built in massage_init_elt, and the other in
expand_default_init.  The result of the first copy is marked
TARGET_EXPR_ELIDING_P, so when we try to pass it to the second copy we
hit the assert.  I think the assert is catching a real bug: even with
-fno-elide-constructors we should only copy once, not twice.
That’s right, thanks for pointing me in the right direction.

This seems to be because 'digested' has the wrong value in
build_vec_init; we did just call digest_init in build_new_1, but
build_vec_init doesn't understand that.
The test to determine whether digest_init has been called is indeed
incorrect, in that it will work if BASE is a reference to the array but
not if it’s a pointer to its first element. The attached updated patch
fixes this.

Successfully tested on x86_64-pc-linux-gnu. OK for trunk?

OK.

Jason

Reply via email to