diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-08-07 10:07:38 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-08-07 10:07:38 +0200 |
commit | 190776773516955df480bfa75731c34c5aaf2306 (patch) | |
tree | b3140f5eccf67869abd92bdc051b0dc6c1487622 /gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C | |
parent | a46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c (diff) |
c++: Add support for __real__/__imag__ modifications in constant expressions [PR88174]linaro-local/ci/tcwg_kernel/gnu-master-arm-norov-allnoconfiglinaro-local/ci/tcwg_kernel/gnu-master-arm-norov-allmodconfiglinaro-local/ci/tcwg_kernel/gnu-master-arm-mainline-defconfiglinaro-local/ci/tcwg_kernel/gnu-master-aarch64-norov-allnoconfiglinaro-local/ci/tcwg_kernel/gnu-master-aarch64-next-allnoconfiglinaro-local/ci/tcwg_bmk_llvm_tk1/llvm-master-arm-spec2k6-O2linaro-local/ci/tcwg_bmk_llvm_apm/llvm-master-arm-spec2k6-Ozlinaro-local/ci/tcwg_bmk_gnu_fx/gnu-master-aarch64-cpu2017-O2linaro-local/ci/tcwg_bmk_gnu_eabi_stm32/gnu_eabi-master-arm_eabi-coremark-Os_LTOlinaro-local/ci/tcwg_bmk_gnu_eabi_stm32/gnu_eabi-master-arm_eabi-coremark-O3_LTOlinaro-local/ci/tcwg_bmk_gnu_eabi_stm32/gnu_eabi-master-arm_eabi-coremark-O2linaro-local/ci/tcwg_bmk_gnu_apm/gnu-master-aarch64-spec2k6-Os_LTO
We claim we support P0415R1 (constexpr complex), but e.g.
#include <complex>
constexpr bool
foo ()
{
std::complex<double> a (1.0, 2.0);
a += 3.0;
a.real (6.0);
return a.real () == 6.0 && a.imag () == 2.0;
}
static_assert (foo ());
fails with
test.C:12:20: error: non-constant condition for static assertion
12 | static_assert (foo ());
| ~~~~^~
test.C:12:20: in ‘constexpr’ expansion of ‘foo()’
test.C:8:10: in ‘constexpr’ expansion of ‘a.std::complex<double>::real(6.0e+0)’
test.C:12:20: error: modification of ‘__real__ a.std::complex<double>::_M_value’ is not a constant expression
The problem is we don't handle REALPART_EXPR and IMAGPART_EXPR
in cxx_eval_store_expression.
The following patch attempts to support it (with a requirement
that those are the outermost expressions, ARRAY_REF/COMPONENT_REF
etc. are just not possible on the result of these, BIT_FIELD_REF
would be theoretically possible if trying to extract some bits
from one part of a complex int, but I don't see how it could appear
in the FE trees.
For these references, the code handles value being COMPLEX_CST,
COMPLEX_EXPR or CONSTRUCTOR_NO_CLEARING empty CONSTRUCTOR (what we use
to represent uninitialized values for C++20 and later) and the
code starts by rewriting it to COMPLEX_EXPR, so that we can freely
adjust the individual parts and later on possibly optimize it back
to COMPLEX_CST if both halves are constant.
2022-08-07 Jakub Jelinek <jakub@redhat.com>
PR c++/88174
* constexpr.cc (cxx_eval_store_expression): Handle REALPART_EXPR
and IMAGPART_EXPR. Change ctors from releasing_vec to
auto_vec<tree *>, adjust all uses. For !preeval, update ctors
vector.
* g++.dg/cpp1y/constexpr-complex1.C: New test.
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C new file mode 100644 index 00000000000..8bb24cb2775 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C @@ -0,0 +1,24 @@ +// PR c++/88174 +// { dg-do compile { target c++14 } } + +constexpr bool +foo (double x, double y, double z, double w) +{ + __complex__ double a = 0; + __real__ a = x; + __imag__ a = y; +#if __cpp_constexpr >= 201907L + __complex__ double b; + __real__ b = z; +#else + __complex__ double b = z; +#endif + __imag__ b = w; + a += b; + a -= b; + a *= b; + a /= b; + return __real__ a == x && __imag__ a == y; +} + +static_assert (foo (1.0, 2.0, 3.0, 4.0), ""); |