\f
/* Structure holding the current initializer being processed by reshape_init.
CUR is a pointer to the current element being processed, END is a pointer
- after the last element present in the initializer. */
+ after the last element present in the initializer and RAW_IDX is index into
+ RAW_DATA_CST if that is CUR elt. */
struct reshape_iter
{
constructor_elt *cur;
constructor_elt *end;
+ unsigned raw_idx;
};
static tree reshape_init_r (tree, reshape_iter *, tree, tsubst_flags_t);
}
/* Helper function for reshape_init*. Split first element of
- RAW_DATA_CST and save the rest to d->cur->value. */
+ RAW_DATA_CST or return NULL for other elements. Set *INC_CUR
+ to true if the whole d->cur has been consumed. */
static tree
-cp_maybe_split_raw_data (reshape_iter *d)
+cp_maybe_split_raw_data (reshape_iter *d, bool *inc_cur)
{
+ *inc_cur = true;
if (TREE_CODE (d->cur->value) != RAW_DATA_CST)
return NULL_TREE;
- tree ret = *raw_data_iterator (d->cur->value, 0);
- ++RAW_DATA_POINTER (d->cur->value);
- --RAW_DATA_LENGTH (d->cur->value);
- if (RAW_DATA_LENGTH (d->cur->value) == 1)
- d->cur->value = *raw_data_iterator (d->cur->value, 0);
+ tree ret = *raw_data_iterator (d->cur->value, d->raw_idx++);
+ if (d->raw_idx != (unsigned) RAW_DATA_LENGTH (d->cur->value))
+ *inc_cur = false;
+ else
+ d->raw_idx = 0;
return ret;
}
static tree
consume_init (tree init, reshape_iter *d)
{
- if (tree raw_init = cp_maybe_split_raw_data (d))
- return raw_init;
- d->cur++;
+ bool inc_cur;
+ if (tree raw_init = cp_maybe_split_raw_data (d, &inc_cur))
+ init = raw_init;
+ if (inc_cur)
+ d->cur++;
return init;
}
{
tree elt_init;
constructor_elt *old_cur = d->cur;
- const char *old_raw_data_ptr = NULL;
-
- if (TREE_CODE (d->cur->value) == RAW_DATA_CST)
- old_raw_data_ptr = RAW_DATA_POINTER (d->cur->value);
+ unsigned int old_raw_idx = d->raw_idx;
+ bool old_raw_data_cst = TREE_CODE (d->cur->value) == RAW_DATA_CST;
if (d->cur->index)
CONSTRUCTOR_IS_DESIGNATED_INIT (new_init) = true;
&& !vector_p)
{
elt_init = d->cur->value;
- if (!sized_array_p
- || ((unsigned) RAW_DATA_LENGTH (d->cur->value)
- <= max_index_cst - index + 1))
- d->cur++;
+ unsigned int off = d->raw_idx;
+ unsigned int len = RAW_DATA_LENGTH (elt_init) - off;
+ if (!sized_array_p || len <= max_index_cst - index + 1)
+ {
+ d->cur++;
+ d->raw_idx = 0;
+ }
else
{
- unsigned int len = max_index_cst - index + 1;
- if ((unsigned) RAW_DATA_LENGTH (d->cur->value) == len + 1)
- d->cur->value
- = build_int_cst (integer_type_node,
- *(const unsigned char *)
- RAW_DATA_POINTER (d->cur->value) + len);
- else
- {
- d->cur->value = copy_node (elt_init);
- RAW_DATA_LENGTH (d->cur->value) -= len;
- RAW_DATA_POINTER (d->cur->value) += len;
- }
+ len = max_index_cst - index + 1;
+ d->raw_idx += len;
+ }
+ if (!reuse || off || d->cur == old_cur)
+ {
+ elt_init = copy_node (elt_init);
RAW_DATA_LENGTH (elt_init) = len;
+ RAW_DATA_POINTER (elt_init) += off;
}
TREE_TYPE (elt_init) = elt_type;
}
if (elt_init == error_mark_node)
return error_mark_node;
tree idx = size_int (index);
- if (reuse && old_raw_data_ptr && d->cur == old_cur)
+ if (reuse && old_raw_data_cst && d->cur == old_cur)
{
/* We need to stop reusing as some RAW_DATA_CST in the original
ctor had to be split. */
/* This can happen with an invalid initializer (c++/54501). */
if (d->cur == old_cur
&& !sized_array_p
- && (old_raw_data_ptr == NULL
- || (TREE_CODE (d->cur->value) == RAW_DATA_CST
- && RAW_DATA_POINTER (d->cur->value) == old_raw_data_ptr)))
+ && d->raw_idx == old_raw_idx)
break;
if (TREE_CODE (elt_init) == RAW_DATA_CST)
/* We could also implement this by wrapping init in a new CONSTRUCTOR and
calling reshape_init, but this way can just live on the stack. */
constructor_elt elt = { /*index=*/NULL_TREE, init };
- reshape_iter iter = { &elt, &elt + 1 };
+ reshape_iter iter = { &elt, &elt + 1, 0 };
return reshape_init_r (type, &iter,
/*first_initializer_p=*/NULL_TREE,
complain);
{
tree field_init;
constructor_elt *old_cur = d->cur;
- const char *old_raw_data_ptr = NULL;
+ unsigned old_raw_idx = d->raw_idx;
bool direct_desig = false;
- if (TREE_CODE (d->cur->value) == RAW_DATA_CST)
- old_raw_data_ptr = RAW_DATA_POINTER (d->cur->value);
-
/* Handle C++20 designated initializers. */
if (d->cur->index)
{
if (field_init == error_mark_node)
return error_mark_node;
- if (d->cur == old_cur
- && d->cur->index
- && (old_raw_data_ptr == NULL
- || (TREE_CODE (d->cur->value) == RAW_DATA_CST
- && RAW_DATA_POINTER (d->cur->value) == old_raw_data_ptr)))
+ if (d->cur == old_cur && d->cur->index && d->raw_idx == old_raw_idx)
{
/* This can happen with an invalid initializer for a flexible
array member (c++/54441). */
if (last_was_pack_expansion)
{
tree init = d->cur->value;
- if (tree raw_init = cp_maybe_split_raw_data (d))
+ bool inc_cur;
+ if (tree raw_init = cp_maybe_split_raw_data (d, &inc_cur))
init = raw_init;
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
last_was_pack_expansion, init);
}
else if (first_initializer_p && d->cur != d->end)
{
+ if (error_operand_p (d->cur->value)
+ || has_designator_problem (d, complain))
+ return error_mark_node;
vec<constructor_elt, va_gc> *v = 0;
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
- tree raw_init = cp_maybe_split_raw_data (d);
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
- raw_init ? raw_init : d->cur->value);
- if (has_designator_problem (d, complain))
- return error_mark_node;
- if (!raw_init)
- d->cur++;
+ init = consume_init (d->cur->value, d);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
init = build_constructor (init_list_type_node, v);
}
return init;
/* Recurse on this CONSTRUCTOR. */
d.cur = &(*v)[0];
d.end = d.cur + v->length ();
+ d.raw_idx = 0;
new_init = reshape_init_r (type, &d, init, complain);
if (new_init == error_mark_node)
--- /dev/null
+// PR c++/118214
+// { dg-do run { target c++11 } }
+
+struct A { int a[256]; };
+
+void
+foo (A a)
+{
+ for (int i = 0; i < 256; ++i)
+ if (a.a[i] != (i < 130 && (i & 1) == 0))
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo ({ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, });
+}