case ARRAY_TYPE:
{
struct gimplify_init_ctor_preeval_data preeval_data;
- HOST_WIDE_INT num_type_elements, num_ctor_elements;
- HOST_WIDE_INT num_nonzero_elements;
- bool cleared, valid_const_initializer;
+ HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
+ bool cleared, complete_p, valid_const_initializer;
/* Aggregate types must lower constructors to initialization of
individual elements. The exception is that a CONSTRUCTOR node
can only do so if it known to be a valid constant initializer. */
valid_const_initializer
= categorize_ctor_elements (ctor, &num_nonzero_elements,
- &num_ctor_elements, &cleared);
+ &num_ctor_elements, &complete_p);
/* If a const aggregate variable is being initialized, then it
should never be a lose to promote the variable to be static. */
parts in, then generate code for the non-constant parts. */
/* TODO. There's code in cp/typeck.c to do this. */
- num_type_elements = count_type_elements (type, true);
-
- /* If count_type_elements could not determine number of type elements
- for a constant-sized object, assume clearing is needed.
- Don't do this for variable-sized objects, as store_constructor
- will ignore the clearing of variable-sized objects. */
- if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
+ if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
+ /* store_constructor will ignore the clearing of variable-sized
+ objects. Initializers for such objects must explicitly set
+ every field that needs to be set. */
+ cleared = false;
+ else if (!complete_p)
+ /* If the constructor isn't complete, clear the whole object
+ beforehand.
+
+ ??? This ought not to be needed. For any element not present
+ in the initializer, we should simply set them to zero. Except
+ we'd need to *find* the elements that are not present, and that
+ requires trickery to avoid quadratic compile-time behavior in
+ large cases or excessive memory use in small cases. */
cleared = true;
- /* If there are "lots" of zeros, then block clear the object first. */
- else if (num_type_elements - num_nonzero_elements
+ else if (num_ctor_elements - num_nonzero_elements
> CLEAR_RATIO (optimize_function_for_speed_p (cfun))
- && num_nonzero_elements < num_type_elements/4)
- cleared = true;
- /* ??? This bit ought not be needed. For any element not present
- in the initializer, we should simply set them to zero. Except
- we'd need to *find* the elements that are not present, and that
- requires trickery to avoid quadratic compile-time behavior in
- large cases or excessive memory use in small cases. */
- else if (num_ctor_elements < num_type_elements)
+ && num_nonzero_elements < num_ctor_elements / 4)
+ /* If there are "lots" of zeros, it's more efficient to clear
+ the memory and then set the nonzero elements. */
cleared = true;
+ else
+ cleared = false;
/* If there are "lots" of initialized elements, and all of them
are valid address constants, then the entire initializer can