The constexpr code was treating __real/__imag as always producing an rvalue, which is incorrect.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit b61d1ce84c2e66dde4662dab41ccd99dd360a02f Author: Jason Merrill <ja...@redhat.com> Date: Sat Nov 12 10:45:14 2016 -0800 Fix constexpr lvalue use of __real and __imag. * constexpr.c (potential_constant_expression_1): REALPART_EXPR and IMAGPART_EXPR can be lvalues. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f75f0b0..739e902 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5105,6 +5105,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, #endif return RECUR (t, any); + case REALPART_EXPR: + case IMAGPART_EXPR: case COMPONENT_REF: case BIT_FIELD_REF: case ARROW_EXPR: @@ -5276,8 +5278,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, return true; /* fall through. */ - case REALPART_EXPR: - case IMAGPART_EXPR: case CONJ_EXPR: case SAVE_EXPR: case FIX_TRUNC_EXPR: diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-complex2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-complex2.C new file mode 100644 index 0000000..9a9291b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-complex2.C @@ -0,0 +1,5 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } + +static _Complex int i; +static_assert (&__imag i == &__imag i, "");