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>
|
||||
|
||||
PR c++/71515
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -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