Hi! As written in the PR, location wrappers are stripped by cxx_eval_constant_expression as the first thing it does after dealing with jump_target. The problem is that when this function is called on a CONSTRUCTOR, is TREE_CONSTANT and reduced_constant_expression_p (which allows location wrappers around constants), we don't recurse on the CONSTRUCTOR elements and so nothing strips them away. Then when cxx_eval_component_reference or bit_field_ref we actually can run into those location wrappers and the callers assume they don't appear anymore.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? I admit I'm not 100% sure about the second case which will call the function to do the stripping for all the elts until the one found. The alternative would be: tree bitpos = bit_position (field); if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1)) - return value; + { + STRIP_ANY_LOCATION_WRAPPER (value); + return value; + } if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE - && TREE_CODE (value) == INTEGER_CST && tree_fits_shwi_p (bitpos) && tree_fits_shwi_p (DECL_SIZE (field))) { HOST_WIDE_INT bit = tree_to_shwi (bitpos); HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field)); HOST_WIDE_INT shift; if (bit >= istart && bit + sz <= istart + isize) { + STRIP_ANY_LOCATION_WRAPPER (value); + if (TREE_CODE (value) != INTEGER_CST) + continue; but then we'd do those tree_fits_shwi_p/tree_to_shwi. Guess a micro-optimization without a clear winner. 2019-10-17 Jakub Jelinek <ja...@redhat.com> PR c++/92015 * constexpr.c (cxx_eval_component_reference, cxx_eval_bit_field_ref): Use STRIP_ANY_LOCATION_WRAPPER on CONSTRUCTOR elts. * g++.dg/cpp0x/constexpr-92015.C: New test. --- gcc/cp/constexpr.c.jj 2019-10-16 09:30:57.300112739 +0200 +++ gcc/cp/constexpr.c 2019-10-16 17:06:03.943539476 +0200 @@ -2887,7 +2887,10 @@ cxx_eval_component_reference (const cons : field == part) { if (value) - return value; + { + STRIP_ANY_LOCATION_WRAPPER (value); + return value; + } else /* We're in the middle of initializing it. */ break; @@ -2977,6 +2980,7 @@ cxx_eval_bit_field_ref (const constexpr_ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) { tree bitpos = bit_position (field); + STRIP_ANY_LOCATION_WRAPPER (value); if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1)) return value; if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE --- gcc/testsuite/g++.dg/cpp0x/constexpr-92015.C.jj 2019-10-16 17:16:44.204871319 +0200 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-92015.C 2019-10-16 17:14:14.773127884 +0200 @@ -0,0 +1,7 @@ +// PR c++/92015 +// { dg-do compile { target c++11 } } + +struct S1 { char c[6] {'h', 'e', 'l', 'l', 'o', 0}; }; +struct S2 { char c[6] = "hello"; }; +static_assert (S1{}.c[0] == 'h', ""); +static_assert (S2{}.c[0] == 'h', ""); Jakub