https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110441
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed| |2023-06-28 CC| |jason at gcc dot gnu.org, | |ppalka at gcc dot gnu.org --- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> --- Confirmed, this never worked. The problem seems to be that because f is static, 'S().f()' is represented as a COMPOUND_EXPR that evaluates the otherwise unused object argument S() followed by a TARGET_EXPR for S::f(). And this COMPOUND_EXPR foils the copy elision check in build_special_member_call which looks only for an outermost TARGET_EXPR and doesn't look through COMPOUND_EXPR. In contrast, '(S(), S::f())' (which should be equivalent) is represented as a TARGET_EXPR of a COMPOUND_EXPR rather than a COMPOUND_EXPR of a TARGET_EXPR, and so copy elision is correctly avoided. So perhaps we could make keep_unused_object_arg for a TARGET_EXPR result place the COMPOUND_EXPR inside the TARGET_EXPR_INITIAL instead of around the TARGET_EXPR?