From ab908fdb911d6a337cd02b6018bc74b3a2f99acf Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 28 Feb 2025 15:22:47 +0100 Subject: [PATCH] c++: Fix cxx_eval_store_expression {REAL,IMAG}PART_EXPR handling [PR119045] I've added the asserts that probe == target because {REAL,IMAG}PART_EXPR always implies a scalar type and so applying ARRAY_REF/COMPONENT_REF etc. on it further doesn't make sense and the later code relies on it to be the last one in refs array. But as the following testcase shows, we can fail those assertions in case there is a reference or pointer to the __real__ or __imag__ part, in that case we just evaluate the constant expression and so probe won't be the same as target. That case doesn't push anything into the refs array though. The following patch changes those asserts to verify that refs is still empty, which fixes it. 2025-02-28 Jakub Jelinek PR c++/119045 * constexpr.cc (cxx_eval_store_expression) : Assert that refs->is_empty () rather than probe == target. (cxx_eval_store_expression) : Likewise. * g++.dg/cpp1y/constexpr-complex2.C: New test. (cherry picked from commit 7eb8ec1856f71b039d1c2235b1c941934fa28e22) --- gcc/cp/constexpr.cc | 4 ++-- .../g++.dg/cpp1y/constexpr-complex2.C | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-complex2.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index a5c6227b8dd..f3b61f5f391 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -6313,7 +6313,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, break; case REALPART_EXPR: - gcc_assert (probe == target); + gcc_assert (refs->is_empty ()); vec_safe_push (refs, NULL_TREE); vec_safe_push (refs, probe); vec_safe_push (refs, TREE_TYPE (probe)); @@ -6321,7 +6321,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, break; case IMAGPART_EXPR: - gcc_assert (probe == target); + gcc_assert (refs->is_empty ()); vec_safe_push (refs, NULL_TREE); vec_safe_push (refs, probe); vec_safe_push (refs, TREE_TYPE (probe)); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-complex2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-complex2.C new file mode 100644 index 00000000000..7baafd83a32 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-complex2.C @@ -0,0 +1,18 @@ +// PR c++/119045 +// { dg-do compile { target c++14 } } + +constexpr float +foo () +{ + __complex__ float f {1, 2}; + float s = __real__ f + __imag__ f; + float &r = __real__ f; + float &i = __imag__ f; + r = 42; + s += __real__ f; + i = 3; + s += __imag__ f; + return s; +} + +static_assert (foo () == 48.0f, ""); -- 2.47.2