Commit 3b9997bb by Jason Merrill Committed by Jason Merrill

re PR c++/67104 (Constant expression factory function initializes std::array…

re PR c++/67104 (Constant expression factory function initializes std::array with static storage duration strangely)

	PR c++/67104
	* constexpr.c (cxx_eval_array_reference): Handle sparse
	CONSTRUCTORs.

From-SVN: r226830
parent e5e58dbe
2015-08-12 Jason Merrill <jason@redhat.com> 2015-08-12 Jason Merrill <jason@redhat.com>
PR c++/67104
* constexpr.c (cxx_eval_array_reference): Handle sparse
CONSTRUCTORs.
PR c++/67108 PR c++/67108
* decl2.c (c_parse_final_cleanups): Set at_eof to 2 at end. * decl2.c (c_parse_final_cleanups): Set at_eof to 2 at end.
* error.c (dump_template_bindings): Don't tsubst in that case. * error.c (dump_template_bindings): Don't tsubst in that case.
......
...@@ -1697,7 +1697,38 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -1697,7 +1697,38 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
VERIFY_CONSTANT (ary); VERIFY_CONSTANT (ary);
gcc_unreachable (); gcc_unreachable ();
} }
if (compare_tree_int (index, len) >= 0)
i = tree_to_shwi (index);
bool found = true;
if (TREE_CODE (ary) == CONSTRUCTOR && len
&& (TREE_CODE (CONSTRUCTOR_ELT (ary, len-1)->index) == RANGE_EXPR
|| compare_tree_int (CONSTRUCTOR_ELT (ary, len-1)->index, len-1)))
{
/* The last element doesn't match its position in the array; this must be
a sparse array from cxx_eval_store_expression. So iterate. */
found = false;
vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (ary);
constructor_elt *e;
for (unsigned ix = 0; vec_safe_iterate (v, ix, &e); ++i)
{
if (TREE_CODE (e->index) == RANGE_EXPR)
{
tree lo = TREE_OPERAND (e->index, 0);
tree hi = TREE_OPERAND (e->index, 1);
if (tree_int_cst_le (lo, index) && tree_int_cst_le (index, hi))
found = true;
}
else if (tree_int_cst_equal (e->index, index))
found = true;
if (found)
{
i = ix;
break;
}
}
}
if (i >= len || !found)
{ {
if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary))))
{ {
...@@ -1714,14 +1745,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -1714,14 +1745,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
*non_constant_p = true; *non_constant_p = true;
return t; return t;
} }
else if (tree_int_cst_lt (index, integer_zero_node)) else if (i < 0)
{ {
if (!ctx->quiet) if (!ctx->quiet)
error ("negative array subscript"); error ("negative array subscript");
*non_constant_p = true; *non_constant_p = true;
return t; return t;
} }
i = tree_to_shwi (index);
if (TREE_CODE (ary) == CONSTRUCTOR) if (TREE_CODE (ary) == CONSTRUCTOR)
return (*CONSTRUCTOR_ELTS (ary))[i].value; return (*CONSTRUCTOR_ELTS (ary))[i].value;
else if (elem_nchars == 1) else if (elem_nchars == 1)
......
// PR c++/67104
// { dg-do compile { target c++14 } }
template <typename T, int N> struct array
{
constexpr T &operator[](int index) { return data[index]; }
constexpr T operator[](int index) const { return data[index]; }
T data[N];
};
constexpr array<long unsigned, 1001>
make_bottle_count ()
{
array<long unsigned, 1001> a{};
a[65] = 1;
return a;
}
constexpr auto bottle_count = make_bottle_count ();
static_assert (bottle_count[65], "");
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