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  <ja...@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

Reply via email to