aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-05-29 09:44:09 -0400
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-17 13:09:20 -0300
commit1083f12b6f7ba3ed2dd58e8e337e8919bd1f1b8b (patch)
tree0736750c4a385bf446156301e50e055a9b96170a /gcc/cp/constexpr.c
parent18d36044bc7d26b02f2fc02054587d40d626c5aa (diff)
downloadgcc-1083f12b6f7ba3ed2dd58e8e337e8919bd1f1b8b.zip
gcc-1083f12b6f7ba3ed2dd58e8e337e8919bd1f1b8b.tar.gz
gcc-1083f12b6f7ba3ed2dd58e8e337e8919bd1f1b8b.tar.bz2
c++: constexpr ctor with RANGE_EXPR index [PR95241]
In the testcase below, the CONSTRUCTOR for 'field' contains a RANGE_EXPR index: {{aggr_init_expr<...>, [1...2]={.off=1}}} but get_or_insert_ctor_field isn't prepared to handle looking up a RANGE_EXPR index. This patch adds limited support to get_or_insert_ctor_field for looking up a RANGE_EXPR index. The limited scope of this patch should make it more suitable for backporting, and more extensive support would be needed only to handle self-modifying CONSTRUCTORs that contain a RANGE_EXPR index, but I haven't yet been able to come up with a testcase that actually creates such a CONSTRUCTOR. gcc/cp/ChangeLog: PR c++/95241 * constexpr.c (get_or_insert_ctor_field): Add limited support for RANGE_EXPR index lookups. gcc/testsuite/ChangeLog: PR c++/95241 * g++.dg/cpp0x/constexpr-array25.C: New test.
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4b1f92f..959f025 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3299,6 +3299,22 @@ get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
}
else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
{
+ if (TREE_CODE (index) == RANGE_EXPR)
+ {
+ /* Support for RANGE_EXPR index lookups is currently limited to
+ accessing an existing element via POS_HINT, or appending a new
+ element to the end of CTOR. ??? Support for other access
+ patterns may also be needed. */
+ vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
+ if (vec_safe_length (elts))
+ {
+ tree lo = TREE_OPERAND (index, 0);
+ gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
+ }
+ CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
+ return &elts->last();
+ }
+
HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, /*insert*/true);
gcc_assert (i >= 0);
constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);