]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Add support for __real__/__imag__ modifications in constant expressions [PR88174]
authorJakub Jelinek <jakub@redhat.com>
Sun, 7 Aug 2022 08:07:38 +0000 (10:07 +0200)
committerJakub Jelinek <jakub@redhat.com>
Sun, 7 Aug 2022 08:07:38 +0000 (10:07 +0200)
commit190776773516955df480bfa75731c34c5aaf2306
treeb3140f5eccf67869abd92bdc051b0dc6c1487622
parenta46bca36b7b3a8a7e15b04225fb2b4f9b1bed62c
c++: Add support for __real__/__imag__ modifications in constant expressions [PR88174]

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.
gcc/cp/constexpr.cc
gcc/testsuite/g++.dg/cpp1y/constexpr-complex1.C [new file with mode: 0644]