aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@gcc.gnu.org>2011-07-13 11:16:36 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2011-07-13 11:16:36 +0000
commit953d0c90a2f0a98b6d860ecfbf1bc5672653a588 (patch)
treeb416f9a74ed2aeda3b26a2a7af943a1535790bb3 /gcc/cp
parent9111c715537d8ea0829d6ab7511017ed8658f303 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/typeck2.c38
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;