Hello,it turns out there wasn't much missing here. I got side-tracked because fold_unary_loc doesn't call fold_indirect_ref_1, and fold_indirect_ref_1 has a too strict comparison type == TREE_TYPE (optype) (should compare TYPE_MAIN_VARIANT instead?), but none of that was necessary so I'll leave it for another time. The new testcase is not that useful, but I didn't remember there was already one with dg-bogus.
Bootstrap+testsuite on x86_64-unknown-linux-gnu. 2013-07-07 Marc Glisse <marc.gli...@inria.fr> PR c++/53094 gcc/cp/ * semantics.c (cxx_eval_bit_field_ref): Handle VECTOR_CST. gcc/testsuite/ * g++.dg/cpp0x/constexpr-53094-1.C: Adjust. * g++.dg/ext/vector24.C: New testcase. -- Marc Glisse
Index: testsuite/g++.dg/cpp0x/constexpr-53094-1.C =================================================================== --- testsuite/g++.dg/cpp0x/constexpr-53094-1.C (revision 200742) +++ testsuite/g++.dg/cpp0x/constexpr-53094-1.C (working copy) @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++11" } typedef float __attribute__ ((vector_size (4 * sizeof (float)))) V4; constexpr V4 v = { 1, 1, 1, 0 }; -constexpr V4 r = v[0] + v; // { dg-bogus "not a constant expression" "" { xfail *-*-* } } +constexpr V4 r = v[0] + v; Index: testsuite/g++.dg/ext/vector24.C =================================================================== --- testsuite/g++.dg/ext/vector24.C (revision 0) +++ testsuite/g++.dg/ext/vector24.C (revision 0) @@ -0,0 +1,8 @@ +// { dg-do compile { target c++11 } } + +typedef long vec __attribute__((vector_size(2*sizeof(long)))); +constexpr vec v = { 33, 42 }; +constexpr auto l0 = v[0]; +constexpr auto l1 = v[1]; +static_assert(l0==33,"Fail"); +static_assert(l1==42,"Fail"); Property changes on: testsuite/g++.dg/ext/vector24.C ___________________________________________________________________ Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision URL Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 200742) +++ cp/semantics.c (working copy) @@ -7179,29 +7179,35 @@ cxx_eval_bit_field_ref (const constexpr_ tree whole = cxx_eval_constant_expression (call, orig_whole, allow_non_constant, addr, non_constant_p, overflow_p); tree start, field, value; unsigned HOST_WIDE_INT i; if (whole == orig_whole) return t; /* Don't VERIFY_CONSTANT here; we only want to check that we got a CONSTRUCTOR. */ - if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR) + if (!*non_constant_p + && TREE_CODE (whole) != VECTOR_CST + && TREE_CODE (whole) != CONSTRUCTOR) { if (!allow_non_constant) error ("%qE is not a constant expression", orig_whole); *non_constant_p = true; } if (*non_constant_p) return t; + if (TREE_CODE (whole) == VECTOR_CST) + return fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole, + TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)); + start = TREE_OPERAND (t, 2); istart = tree_low_cst (start, 0); isize = tree_low_cst (TREE_OPERAND (t, 1), 0); utype = TREE_TYPE (t); if (!TYPE_UNSIGNED (utype)) utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1); retval = build_int_cst (utype, 0); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) { tree bitpos = bit_position (field);