mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
8d6833755c
commit
fd2bfee51e
|
|
@ -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>
|
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,
|
||||||
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.
|
||||||
|
|
|
||||||
|
|
@ -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("");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue