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.
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.
Jason