diff options
author | Richard Sandiford <rsandifo@gcc.gnu.org> | 2011-07-13 11:16:36 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2011-07-13 11:16:36 +0000 |
commit | 953d0c90a2f0a98b6d860ecfbf1bc5672653a588 (patch) | |
tree | b416f9a74ed2aeda3b26a2a7af943a1535790bb3 /gcc/cp | |
parent | 9111c715537d8ea0829d6ab7511017ed8658f303 (diff) | |
download | gcc-953d0c90a2f0a98b6d860ecfbf1bc5672653a588.zip gcc-953d0c90a2f0a98b6d860ecfbf1bc5672653a588.tar.gz gcc-953d0c90a2f0a98b6d860ecfbf1bc5672653a588.tar.bz2 |
tree.h (categorize_ctor_elements): Remove comment.
gcc/
* tree.h (categorize_ctor_elements): Remove comment. Fix long line.
(count_type_elements): Delete.
(complete_ctor_at_level_p): Declare.
* expr.c (flexible_array_member_p): New function, split out from...
(count_type_elements): ...here. Make static. Replace allow_flexarr
parameter with for_ctor_p. When for_ctor_p is true, return the
number of elements that should appear in the top-level constructor,
otherwise return an estimate of the number of scalars.
(categorize_ctor_elements): Replace p_must_clear with p_complete.
(categorize_ctor_elements_1): Likewise. Use complete_ctor_at_level_p.
(complete_ctor_at_level_p): New function, borrowing union logic
from old categorize_ctor_elements_1.
(mostly_zeros_p): Return true if the constructor is not complete.
(all_zeros_p): Update call to categorize_ctor_elements.
* gimplify.c (gimplify_init_constructor): Update call to
categorize_ctor_elements. Don't call count_type_elements.
Unconditionally prevent clearing for variable-sized types,
otherwise rely on categorize_ctor_elements to detect
incomplete initializers.
gcc/cp/
* typeck2.c (split_nonconstant_init_1): Pass the initializer directly,
rather than a pointer to it. Return true if the whole of the value
was initialized by the generated statements. Use
complete_ctor_at_level_p instead of count_type_elements.
gcc/testsuite/
2011-07-12 Chung-Lin Tang <cltang@codesourcery.com>
* gcc.target/arm/pr48183.c: New test.
From-SVN: r176228
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 38 |
2 files changed, 23 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9e55de8..cfe3bab 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-07-13 Richard Sandiford <richard.sandiford@linaro.org> + + * typeck2.c (split_nonconstant_init_1): Pass the initializer directly, + rather than a pointer to it. Return true if the whole of the value + was initialized by the generated statements. Use + complete_ctor_at_level_p instead of count_type_elements. + 2011-07-12 Diego Novillo <dnovillo@google.com> * name-lookup.h (cp_binding_level): Rename from cxx_scope. diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 023fab3..ac4f383 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -481,18 +481,20 @@ cxx_incomplete_type_error (const_tree value, const_tree type) /* The recursive part of split_nonconstant_init. DEST is an lvalue - expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */ + expression to which INIT should be assigned. INIT is a CONSTRUCTOR. + Return true if the whole of the value was initialized by the + generated statements. */ -static void -split_nonconstant_init_1 (tree dest, tree *initp) +static bool +split_nonconstant_init_1 (tree dest, tree init) { unsigned HOST_WIDE_INT idx; - tree init = *initp; tree field_index, value; tree type = TREE_TYPE (dest); tree inner_type = NULL; bool array_type_p = false; - HOST_WIDE_INT num_type_elements, num_initialized_elements; + bool complete_p = true; + HOST_WIDE_INT num_split_elts = 0; switch (TREE_CODE (type)) { @@ -504,7 +506,6 @@ split_nonconstant_init_1 (tree dest, tree *initp) case RECORD_TYPE: case UNION_TYPE: case QUAL_UNION_TYPE: - num_initialized_elements = 0; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field_index, value) { @@ -527,13 +528,14 @@ split_nonconstant_init_1 (tree dest, tree *initp) sub = build3 (COMPONENT_REF, inner_type, dest, field_index, NULL_TREE); - split_nonconstant_init_1 (sub, &value); + if (!split_nonconstant_init_1 (sub, value)) + complete_p = false; + num_split_elts++; } else if (!initializer_constant_valid_p (value, inner_type)) { tree code; tree sub; - HOST_WIDE_INT inner_elements; /* FIXME: Ordered removal is O(1) so the whole function is worst-case quadratic. This could be fixed using an aside @@ -557,21 +559,9 @@ split_nonconstant_init_1 (tree dest, tree *initp) code = build_stmt (input_location, EXPR_STMT, code); add_stmt (code); - inner_elements = count_type_elements (inner_type, true); - if (inner_elements < 0) - num_initialized_elements = -1; - else if (num_initialized_elements >= 0) - num_initialized_elements += inner_elements; - continue; + num_split_elts++; } } - - num_type_elements = count_type_elements (type, true); - /* If all elements of the initializer are non-constant and - have been split out, we don't need the empty CONSTRUCTOR. */ - if (num_type_elements > 0 - && num_type_elements == num_initialized_elements) - *initp = NULL; break; case VECTOR_TYPE: @@ -583,6 +573,7 @@ split_nonconstant_init_1 (tree dest, tree *initp) code = build2 (MODIFY_EXPR, type, dest, cons); code = build_stmt (input_location, EXPR_STMT, code); add_stmt (code); + num_split_elts += CONSTRUCTOR_NELTS (init); } break; @@ -592,6 +583,8 @@ split_nonconstant_init_1 (tree dest, tree *initp) /* The rest of the initializer is now a constant. */ TREE_CONSTANT (init) = 1; + return complete_p && complete_ctor_at_level_p (TREE_TYPE (init), + num_split_elts, inner_type); } /* A subroutine of store_init_value. Splits non-constant static @@ -607,7 +600,8 @@ split_nonconstant_init (tree dest, tree init) if (TREE_CODE (init) == CONSTRUCTOR) { code = push_stmt_list (); - split_nonconstant_init_1 (dest, &init); + if (split_nonconstant_init_1 (dest, init)) + init = NULL_TREE; code = pop_stmt_list (code); DECL_INITIAL (dest) = init; TREE_READONLY (dest) = 0; |