diff options
author | Jason Merrill <jason@redhat.com> | 2015-08-12 14:02:43 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-08-12 14:02:43 -0400 |
commit | 3b9997bbaf04d8a8588d45f7a8be201bb8358ca9 (patch) | |
tree | 1f01823a3a1f9c9305ce164050ee14d8b4f80a78 /gcc/cp | |
parent | e5e58dbe28b71a17cb2e3e02fdf42d654e6ccd00 (diff) | |
download | gcc-3b9997bbaf04d8a8588d45f7a8be201bb8358ca9.zip gcc-3b9997bbaf04d8a8588d45f7a8be201bb8358ca9.tar.gz gcc-3b9997bbaf04d8a8588d45f7a8be201bb8358ca9.tar.bz2 |
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 37 |
2 files changed, 38 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4f3f46d..07ed20f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2015-08-12 Jason Merrill <jason@redhat.com> + PR c++/67104 + * constexpr.c (cxx_eval_array_reference): Handle sparse + CONSTRUCTORs. + PR c++/67108 * decl2.c (c_parse_final_cleanups): Set at_eof to 2 at end. * error.c (dump_template_bindings): Don't tsubst in that case. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 218faec..b6788c7 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1697,7 +1697,38 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, VERIFY_CONSTANT (ary); 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)))) { @@ -1714,14 +1745,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, *non_constant_p = true; return t; } - else if (tree_int_cst_lt (index, integer_zero_node)) + else if (i < 0) { if (!ctx->quiet) error ("negative array subscript"); *non_constant_p = true; return t; } - i = tree_to_shwi (index); + if (TREE_CODE (ary) == CONSTRUCTOR) return (*CONSTRUCTOR_ELTS (ary))[i].value; else if (elem_nchars == 1) |