c++: copy elision w/ obj arg and static memfn call [PR110441]
commit0de651db45c758f54e9ed917069795a3835499de
authorPatrick Palka <ppalka@redhat.com>
Sat, 15 Jul 2023 13:50:51 +0000 (15 09:50 -0400)
committerPatrick Palka <ppalka@redhat.com>
Sat, 15 Jul 2023 13:50:51 +0000 (15 09:50 -0400)
treef9b45ce6ee7e426c03c884e25973d901e38710ef
parent97ceaa110e1607ec8f4f1223200868e1642f3cc7
c++: copy elision w/ obj arg and static memfn call [PR110441]

Here the call A().f() is represented as a COMPOUND_EXPR whose first
operand is the otherwise unused object argument A() and second operand
is the call result (both are TARGET_EXPRs).  Within the return statement,
this outermost COMPOUND_EXPR ends up foiling the copy elision check in
build_special_member_call, resulting in us introducing a bogus call to the
deleted move constructor.  (Within the variable initialization, which goes
through ocp_convert instead of convert_for_initialization, we've already
been eliding the copy -- despite the outermost COMPOUND_EXPR -- ever since
r10-7410-g72809d6fe8e085 made ocp_convert look through COMPOUND_EXPR).

In contrast I noticed '(A(), A::f())' (which should be equivalent to
the above call) is represented with the COMPOUND_EXPR inside the RHS's
TARGET_EXPR initializer thanks to a special case in cp_build_compound_expr.

So this patch fixes this by making keep_unused_object_arg use
cp_build_compound_expr as well.

PR c++/110441

gcc/cp/ChangeLog:

* call.cc (keep_unused_object_arg): Use cp_build_compound_expr
instead of building a COMPOUND_EXPR directly.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/elide8.C: New test.
gcc/cp/call.cc
gcc/testsuite/g++.dg/cpp1z/elide8.C [new file with mode: 0644]