summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2022-08-07 10:07:38 +0200
committerJakub Jelinek <jakub@redhat.com>2022-08-07 10:07:38 +0200
commit190776773516955df480bfa75731c34c5aaf2306 (patch)
treeb3140f5eccf67869abd92bdc051b0dc6c1487622 /gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C
parenta46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c (diff)
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.C24
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), "");