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
