Hi!
As mentioned in the PR, the following testcase ICEs starting with
r272430. The problem is that if cxx_eval_array_reference is called with
lval true, we just want to constant evaluate the index and array, but need
to keep the ARRAY_REF or possibly new one with updated operands in the IL.
The code to look through VCEs from VECTOR_TYPEs has been previously in the
!lval section, but has been made unconditional in that change.
For !lval, we want that, we don't reconstruct ARRAY_REF, but want to fold it
into a constant. For lval, we only use ary in:
if (lval && ary == oldary && index == oldidx)
return t;
else if (lval)
return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
though, so if we look through the VCE, we both for vectors can never reuse
t and build always a new ARRAY_REF, but futhermore build a wrong one,
as ARRAY_REF should always apply to an object with ARRAY_TYPE, not
VECTOR_TYPE.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2019-06-25 Jakub Jelinek <[email protected]>
PR c++/90969
* constexpr.c (cxx_eval_array_reference): Don't look through VCE from
vector type if lval.
* g++.dg/ext/vector38.C: New test.
--- gcc/cp/constexpr.c.jj 2019-06-19 10:04:24.000000000 +0200
+++ gcc/cp/constexpr.c 2019-06-24 11:01:57.535816915 +0200
@@ -2616,7 +2616,8 @@ cxx_eval_array_reference (const constexp
non_constant_p, overflow_p);
if (*non_constant_p)
return t;
- if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
+ if (!lval
+ && TREE_CODE (ary) == VIEW_CONVERT_EXPR
&& VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
&& TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))
ary = TREE_OPERAND (ary, 0);
--- gcc/testsuite/g++.dg/ext/vector38.C.jj 2019-06-24 11:17:26.303987110
+0200
+++ gcc/testsuite/g++.dg/ext/vector38.C 2019-06-24 11:08:01.603004478 +0200
@@ -0,0 +1,5 @@
+// PR c++/90969
+// { dg-do compile }
+
+__attribute__ ((__vector_size__ (4))) int v;
+int &a = v[0];
Jakub