PR c++/71972 - constexpr array self-modification

* constexpr.c (cxx_eval_array_reference): Handle looking for the
	value of an element we're currently modifying.

From-SVN: r238729
This commit is contained in:
Jason Merrill 2016-07-25 14:32:06 -04:00 committed by Jason Merrill
parent 8d6833755c
commit fd2bfee51e
3 changed files with 54 additions and 28 deletions

View File

@ -1,3 +1,9 @@
2016-07-25 Jason Merrill <jason@redhat.com>
PR c++/71972
* constexpr.c (cxx_eval_array_reference): Handle looking for the
value of an element we're currently modifying.
2016-07-24 Jason Merrill <jason@redhat.com>
PR c++/71515

View File

@ -2129,8 +2129,32 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
else
found = (i < len);
if (!found)
if (found)
{
tree r;
if (TREE_CODE (ary) == CONSTRUCTOR)
r = (*CONSTRUCTOR_ELTS (ary))[i].value;
else if (TREE_CODE (ary) == VECTOR_CST)
r = VECTOR_CST_ELT (ary, i);
else if (elem_nchars == 1)
r = build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
TREE_STRING_POINTER (ary)[i]);
else
{
tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (ary)));
r = native_interpret_expr (type, (const unsigned char *)
TREE_STRING_POINTER (ary)
+ i * elem_nchars, elem_nchars);
}
if (r)
/* Don't VERIFY_CONSTANT here. */
return r;
/* Otherwise the element doesn't have a value yet. */
}
/* Not found. */
if (TREE_CODE (ary) == CONSTRUCTOR
&& CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
{
@ -2150,23 +2174,6 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
overflow_p);
}
if (TREE_CODE (ary) == CONSTRUCTOR)
return (*CONSTRUCTOR_ELTS (ary))[i].value;
else if (TREE_CODE (ary) == VECTOR_CST)
return VECTOR_CST_ELT (ary, i);
else if (elem_nchars == 1)
return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
TREE_STRING_POINTER (ary)[i]);
else
{
tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (ary)));
return native_interpret_expr (type, (const unsigned char *)
TREE_STRING_POINTER (ary)
+ i * elem_nchars, elem_nchars);
}
/* Don't VERIFY_CONSTANT here. */
}
/* Subroutine of cxx_eval_constant_expression.
Attempt to reduce a field access of a value of class type. */

View File

@ -0,0 +1,13 @@
// PR c++/71972
// { dg-do compile { target c++14 } }
typedef int size_t;
template <int N> struct S {
template <size_t M> constexpr S(const char (&)[M]) : data{} {
data[0] = data[0];
}
char data[N];
};
int main() {
constexpr S<1> s1("");
}