aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/constexpr.c16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-array25.C21
2 files changed, 37 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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array25.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array25.C
new file mode 100644
index 0000000..9162943
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array25.C
@@ -0,0 +1,21 @@
+// PR c++/95241
+// { dg-do compile { target c++11 } }
+
+struct Fragment
+{
+ int off;
+ constexpr Fragment(int _off) : off(_off) { }
+ constexpr Fragment() : Fragment(1) { }
+};
+
+struct Field
+{
+ Fragment fragments[3];
+ constexpr Field(int off) : fragments{{off}} { }
+};
+
+constexpr Field field{0};
+
+static_assert(field.fragments[0].off == 0
+ && field.fragments[1].off == 1
+ && field.fragments[2].off == 1, "");