diff options
author | Marek Polacek <polacek@redhat.com> | 2022-05-25 18:11:31 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2022-07-01 12:07:34 -0400 |
commit | ecd11acacd6be57af930fa617d7c31ecb40e7f74 (patch) | |
tree | 78da6f3fa4cbeec13ab2abf2b93d7a8c98015863 /gcc/gimple-range-infer.cc | |
parent | 9a668532fb19e7c57aa595a26ce3f0d95f9cbb1b (diff) | |
download | gcc-ecd11acacd6be57af930fa617d7c31ecb40e7f74.zip gcc-ecd11acacd6be57af930fa617d7c31ecb40e7f74.tar.gz gcc-ecd11acacd6be57af930fa617d7c31ecb40e7f74.tar.bz2 |
c++: fix broken copy elision with nested TARGET_EXPRs [PR105550]
In this problem, we are failing to properly perform copy elision with
a conditional operator, so this:
constexpr A a = true ? A{} : A{};
fails with:
error: 'A{((const A*)(&<anonymous>))}' is not a constant expression
The whole initializer is
TARGET_EXPR <D.2395, 1 ? TARGET_EXPR <D.2393, {.p=(const struct A *) &<PLACEHOLDER_EXPR struct A>}> : TARGET_EXPR <D.2394, {.p=(const struct A *) &<PLACEHOLDER_EXPR struct A>}>>
where the outermost TARGET_EXPR is elided, but not the nested ones.
Then we end up replacing the PLACEHOLDER_EXPRs with the temporaries the
TARGET_EXPRs represent, which is precisely what should *not* happen with
copy elision.
I've tried the approach of tweaking ctx->object, but I ran into gazillion
problems with that. I thought that I would let cxx_eval_constant_expression
/TARGET_EXPR create a new object only when ctx->object was null, then
adjust setting of ctx->object in places like cxx_bind_parameters_in_call
and cxx_eval_component_reference but that failed completely. Sometimes
ctx->object has to be reset, sometimes it cannot be reset, 'this' needed
special handling, etc. I gave up.
Instead, this patch strips TARGET_EXPRs from the operands of ?: like
we do in various other places in constexpr.c.
PR c++/105550
gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_conditional_expression): Strip TARGET_EXPRs.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/nsdmi-aggr16.C: Remove FIXME.
* g++.dg/cpp1y/nsdmi-aggr17.C: Remove FIXME.
* g++.dg/cpp0x/constexpr-elision1.C: New test.
* g++.dg/cpp1y/constexpr-elision1.C: New test.
Diffstat (limited to 'gcc/gimple-range-infer.cc')
0 files changed, 0 insertions, 0 deletions