Commit fd2bfee5 by Jason Merrill Committed by Jason Merrill

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
parent 8d683375
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> 2016-07-24 Jason Merrill <jason@redhat.com>
PR c++/71515 PR c++/71515
......
...@@ -2129,42 +2129,49 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -2129,42 +2129,49 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
else else
found = (i < len); found = (i < len);
if (!found) if (found)
{ {
if (TREE_CODE (ary) == CONSTRUCTOR tree r;
&& CONSTRUCTOR_NO_IMPLICIT_ZERO (ary)) 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
{ {
/* 'ary' is part of the aggregate initializer we're currently tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (ary)));
building; if there's no initializer for this element yet, r = native_interpret_expr (type, (const unsigned char *)
that's an error. */ TREE_STRING_POINTER (ary)
if (!ctx->quiet) + i * elem_nchars, elem_nchars);
error ("accessing uninitialized array element");
*non_constant_p = true;
return t;
} }
if (r)
/* Don't VERIFY_CONSTANT here. */
return r;
/* If it's within the array bounds but doesn't have an explicit /* Otherwise the element doesn't have a value yet. */
initializer, it's value-initialized. */
tree val = build_value_init (elem_type, tf_warning_or_error);
return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
overflow_p);
} }
if (TREE_CODE (ary) == CONSTRUCTOR) /* Not found. */
return (*CONSTRUCTOR_ELTS (ary))[i].value;
else if (TREE_CODE (ary) == VECTOR_CST) if (TREE_CODE (ary) == CONSTRUCTOR
return VECTOR_CST_ELT (ary, i); && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
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))); /* 'ary' is part of the aggregate initializer we're currently
return native_interpret_expr (type, (const unsigned char *) building; if there's no initializer for this element yet,
TREE_STRING_POINTER (ary) that's an error. */
+ i * elem_nchars, elem_nchars); if (!ctx->quiet)
error ("accessing uninitialized array element");
*non_constant_p = true;
return t;
} }
/* Don't VERIFY_CONSTANT here. */
/* If it's within the array bounds but doesn't have an explicit
initializer, it's value-initialized. */
tree val = build_value_init (elem_type, tf_warning_or_error);
return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
overflow_p);
} }
/* Subroutine of cxx_eval_constant_expression. /* Subroutine of cxx_eval_constant_expression.
......
// 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("");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment