CONSTRUCTOR_ELTS (init)->ordered_remove (idx);
--idx;
- if (array_type_p)
- sub = build4 (ARRAY_REF, inner_type, dest, field_index,
- NULL_TREE, NULL_TREE);
+ if (TREE_CODE (field_index) == RANGE_EXPR)
+ {
+ /* Use build_vec_init to initialize a range. */
+ tree low = TREE_OPERAND (field_index, 0);
+ tree hi = TREE_OPERAND (field_index, 1);
+ sub = build4 (ARRAY_REF, inner_type, dest, low,
+ NULL_TREE, NULL_TREE);
+ sub = cp_build_addr_expr (sub, tf_warning_or_error);
+ tree max = size_binop (MINUS_EXPR, hi, low);
+ code = build_vec_init (sub, max, value, false, 0,
+ tf_warning_or_error);
+ add_stmt (code);
+ }
else
- sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
- NULL_TREE);
-
- code = build2 (INIT_EXPR, inner_type, sub, value);
- code = build_stmt (input_location, EXPR_STMT, code);
- code = maybe_cleanup_point_expr_void (code);
- add_stmt (code);
- if (type_build_dtor_call (inner_type))
{
- code = (build_special_member_call
- (sub, complete_dtor_identifier, NULL, inner_type,
- LOOKUP_NORMAL, tf_warning_or_error));
- if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
- finish_eh_cleanup (code);
+ if (array_type_p)
+ sub = build4 (ARRAY_REF, inner_type, dest, field_index,
+ NULL_TREE, NULL_TREE);
+ else
+ sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
+ NULL_TREE);
+
+ code = build2 (INIT_EXPR, inner_type, sub, value);
+ code = build_stmt (input_location, EXPR_STMT, code);
+ code = maybe_cleanup_point_expr_void (code);
+ add_stmt (code);
+ if (type_build_dtor_call (inner_type))
+ {
+ code = (build_special_member_call
+ (sub, complete_dtor_identifier, NULL, inner_type,
+ LOOKUP_NORMAL, tf_warning_or_error));
+ if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+ finish_eh_cleanup (code);
+ }
}
num_split_elts++;
return 0;
}
+/* Adjust INIT for going into a CONSTRUCTOR. */
+
+static tree
+massage_init_elt (tree type, tree init, tsubst_flags_t complain)
+{
+ init = digest_init_r (type, init, true, LOOKUP_IMPLICIT, complain);
+ /* Strip a simple TARGET_EXPR when we know this is an initializer. */
+ if (TREE_CODE (init) == TARGET_EXPR
+ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
+ init = TARGET_EXPR_INITIAL (init);
+ /* When we defer constant folding within a statement, we may want to
+ defer this folding as well. */
+ init = maybe_constant_init (init);
+ return init;
+}
+
/* Subroutine of process_init_constructor, which will process an initializer
INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
which describe the initializers. */
else
ce->index = size_int (i);
gcc_assert (ce->value);
- ce->value = digest_init_r (TREE_TYPE (type), ce->value, true,
- LOOKUP_IMPLICIT, complain);
+ ce->value = massage_init_elt (TREE_TYPE (type), ce->value, complain);
if (ce->value != error_mark_node)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
flags |= picflag_from_initializer (ce->value);
}
- /* No more initializers. If the array is unbounded, we are done. Otherwise,
- we must add initializers ourselves. */
- if (!unbounded)
- for (; i < len; ++i)
- {
- tree next;
-
- if (type_build_ctor_call (TREE_TYPE (type)))
- {
- /* If this type needs constructors run for default-initialization,
- we can't rely on the back end to do it for us, so make the
- initialization explicit by list-initializing from {}. */
- next = build_constructor (init_list_type_node, NULL);
- next = digest_init (TREE_TYPE (type), next, complain);
- }
- else if (!zero_init_p (TREE_TYPE (type)))
- next = build_zero_init (TREE_TYPE (type),
- /*nelts=*/NULL_TREE,
- /*static_storage_p=*/false);
- else
- /* The default zero-initialization is fine for us; don't
- add anything to the CONSTRUCTOR. */
- break;
+ /* No more initializers. If the array is unbounded, or we've initialized
+ all the elements, we are done. Otherwise, we must add initializers
+ ourselves. */
+ if (!unbounded && i < len)
+ {
+ tree next;
- flags |= picflag_from_initializer (next);
- CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
- }
+ if (type_build_ctor_call (TREE_TYPE (type)))
+ {
+ /* If this type needs constructors run for default-initialization,
+ we can't rely on the back end to do it for us, so make the
+ initialization explicit by list-initializing from {}. */
+ next = build_constructor (init_list_type_node, NULL);
+ next = massage_init_elt (TREE_TYPE (type), next, complain);
+ if (initializer_zerop (next))
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ next = NULL_TREE;
+ }
+ else if (!zero_init_p (TREE_TYPE (type)))
+ next = build_zero_init (TREE_TYPE (type),
+ /*nelts=*/NULL_TREE,
+ /*static_storage_p=*/false);
+ else
+ /* The default zero-initialization is fine for us; don't
+ add anything to the CONSTRUCTOR. */
+ next = NULL_TREE;
+
+ if (next)
+ {
+ flags |= picflag_from_initializer (next);
+ tree index = build2 (RANGE_EXPR, sizetype, size_int (i),
+ size_int (len - 1));
+ CONSTRUCTOR_APPEND_ELT (v, index, next);
+ }
+ }
CONSTRUCTOR_ELTS (init) = v;
return flags;
}
gcc_assert (ce->value);
- next = digest_init_r (type, ce->value, true,
- LOOKUP_IMPLICIT, complain);
+ next = massage_init_elt (type, ce->value, complain);
++idx;
}
else if (type_build_ctor_call (TREE_TYPE (field)))
for us, so build up TARGET_EXPRs. If the type in question is
a class, just build one up; if it's an array, recurse. */
next = build_constructor (init_list_type_node, NULL);
- if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field)))
- {
- next = finish_compound_literal (TREE_TYPE (field), next,
- complain);
- /* direct-initialize the target. No temporary is going
- to be involved. */
- if (TREE_CODE (next) == TARGET_EXPR)
- TARGET_EXPR_DIRECT_INIT_P (next) = true;
- }
-
- next = digest_init_r (TREE_TYPE (field), next, true,
- LOOKUP_IMPLICIT, complain);
+ next = massage_init_elt (TREE_TYPE (field), next, complain);
/* Warn when some struct elements are implicitly initialized. */
warning (OPT_Wmissing_field_initializers,
}
if (ce->value && ce->value != error_mark_node)
- ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value,
- true, LOOKUP_IMPLICIT, complain);
+ ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, complain);
return picflag_from_initializer (ce->value);
}