This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix lval {REAL,IMAG}PART_EXPR constexpr evaluation (PR c++/71828)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 11 Jul 2016 22:08:27 +0200
- Subject: [C++ PATCH] Fix lval {REAL,IMAG}PART_EXPR constexpr evaluation (PR c++/71828)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
REALPART_EXPR and IMAGPART_EXPR are handled like unary expressions, even
though they are references. For !lval that makes no difference, but for
lval it means we can get ADDR_EXPR of INTEGER_CST etc., or trying to store
into an INTEGER_CST.
Fixed by doing roughly what we do for other references like COMPONENT_REF,
ARRAY_REF etc. in that case.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/6.2?
2016-07-11 Jakub Jelinek <jakub@redhat.com>
PR c++/71828
* constexpr.c (cxx_eval_constant_expression) <case REALPART_EXPR>:
For lval don't use cxx_eval_unary_expression and instead recurse
and if needed rebuild the reference.
* g++.dg/cpp0x/constexpr-71828.C: New test.
--- gcc/cp/constexpr.c.jj 2016-07-11 11:14:28.000000000 +0200
+++ gcc/cp/constexpr.c 2016-07-11 13:30:17.333065119 +0200
@@ -3790,6 +3790,19 @@ cxx_eval_constant_expression (const cons
case REALPART_EXPR:
case IMAGPART_EXPR:
+ if (lval)
+ {
+ r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
+ non_constant_p, overflow_p);
+ if (r == error_mark_node)
+ ;
+ else if (r == TREE_OPERAND (t, 0))
+ r = t;
+ else
+ r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
+ break;
+ }
+ /* FALLTHRU */
case CONJ_EXPR:
case FIX_TRUNC_EXPR:
case FLOAT_EXPR:
--- gcc/testsuite/g++.dg/cpp0x/constexpr-71828.C.jj 2016-07-11 13:39:31.635423827 +0200
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-71828.C 2016-07-11 13:39:02.000000000 +0200
@@ -0,0 +1,5 @@
+// PR c++/71828
+// { dg-do compile { target c++11 } }
+
+constexpr _Complex int a { 1, 2 };
+static_assert (& __imag a != &__real a, "");
Jakub