]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: ICE with temporary of class type in array DMI [PR109966]
authorMarek Polacek <polacek@redhat.com>
Mon, 11 Mar 2024 21:45:55 +0000 (17:45 -0400)
committerMarek Polacek <polacek@redhat.com>
Fri, 12 Apr 2024 22:05:15 +0000 (18:05 -0400)
commit6039925631780741ba77666ef2ef743aa2a925a8
tree5c8025b7b7dfbae1a66a25a68df3bb1afe524b39
parentaa57af93ba22865be747f926e4e5f219e7f8758a
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.
gcc/cp/typeck2.cc
gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr20.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr21.C [new file with mode: 0644]