https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109966
--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The releases/gcc-13 branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>: https://gcc.gnu.org/g:9ad64458dd8fdb384e45aa3647380de53e04cedd commit r13-9301-g9ad64458dd8fdb384e45aa3647380de53e04cedd Author: Marek Polacek <pola...@redhat.com> Date: Mon Mar 11 17:45:55 2024 -0400 c++: ICE with temporary of class type in array DMI [PR109966] This ICE started with the fairly complicated r13-765. We crash in gimplify_var_or_parm_decl because a stray VAR_DECL leaked there. The problem is ultimately that potential_prvalue_result_of wasn't correctly handling arrays and replace_placeholders_for_class_temp_r replaced a PLACEHOLDER_EXPR in a TARGET_EXPR which is used in the context of copy elision. If I have M m[2] = { M{""}, M{""} }; then we don't invoke the M(const M&) copy-ctor. One part of the fix is to use TARGET_EXPR_ELIDING_P rather than potential_prvalue_result_of. That unfortunately doesn't handle the case like struct N { N(M); }; N arr[2] = { M{""}, M{""} }; because TARGET_EXPRs that initialize a function argument are not marked TARGET_EXPR_ELIDING_P even though gimplify_arg drops such TARGET_EXPRs on the floor. We can use a pset to avoid replacing placeholders in them. I made an attempt to use set_target_expr_eliding in convert_for_arg_passing but that regressed constexpr-diag1.C, and does not seem like a prudent change in stage 4 anyway. PR c++/109966 gcc/cp/ChangeLog: * typeck2.cc (potential_prvalue_result_of): Remove. (replace_placeholders_for_class_temp_r): Check TARGET_EXPR_ELIDING_P. Use a pset. Don't replace_placeholders in TARGET_EXPRs that initialize a function argument. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/nsdmi-aggr20.C: New test. * g++.dg/cpp1y/nsdmi-aggr21.C: New test. (cherry picked from commit 6039925631780741ba77666ef2ef743aa2a925a8)