aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJie Zhang <jie@codesourcery.com>2010-04-07 10:14:45 +0000
committerJie Zhang <jiez@gcc.gnu.org>2010-04-07 10:14:45 +0000
commit6addabbbe815be8107207fcb6e2aa640e2e8c6ca (patch)
tree88b97457fae13a30b8afc5e88b682efba5339cfe /gcc
parent366f945f9bc15d885af5a20ed70547e96b2dafae (diff)
downloadgcc-6addabbbe815be8107207fcb6e2aa640e2e8c6ca.zip
gcc-6addabbbe815be8107207fcb6e2aa640e2e8c6ca.tar.gz
gcc-6addabbbe815be8107207fcb6e2aa640e2e8c6ca.tar.bz2
re PR c++/42556 (Unnecessary generation of a zero initializer for array with C++)
cp/ PR c++/42556 * typeck2.c (split_nonconstant_init_1): Drop empty CONSTRUCTOR when all of its elements are non-constant and have been split out. testsuite/ PR c++/42556 * g++.dg/init/pr42556.C: New test. From-SVN: r158047
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck2.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/pr42556.C10
4 files changed, 41 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 782c674..fd10691 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-07 Jie Zhang <jie@codesourcery.com>
+
+ PR c++/42556
+ * typeck2.c (split_nonconstant_init_1): Drop empty CONSTRUCTOR
+ when all of its elements are non-constant and have been split out.
+
2010-04-06 Taras Glek <taras@mozilla.com>
Jason Merrill <jason@redhat.com>
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 7ec4374..2610b28 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -549,13 +549,15 @@ cxx_incomplete_type_error (const_tree value, const_tree type)
expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */
static void
-split_nonconstant_init_1 (tree dest, tree init)
+split_nonconstant_init_1 (tree dest, tree *initp)
{
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;
switch (TREE_CODE (type))
{
@@ -567,6 +569,7 @@ split_nonconstant_init_1 (tree dest, tree init)
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)
{
@@ -589,12 +592,13 @@ split_nonconstant_init_1 (tree dest, tree init)
sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
- split_nonconstant_init_1 (sub, value);
+ split_nonconstant_init_1 (sub, &value);
}
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
@@ -617,9 +621,22 @@ split_nonconstant_init_1 (tree dest, tree init)
code = build2 (INIT_EXPR, inner_type, sub, value);
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_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:
@@ -655,7 +672,7 @@ split_nonconstant_init (tree dest, tree init)
if (TREE_CODE (init) == CONSTRUCTOR)
{
code = push_stmt_list ();
- split_nonconstant_init_1 (dest, init);
+ split_nonconstant_init_1 (dest, &init);
code = pop_stmt_list (code);
DECL_INITIAL (dest) = init;
TREE_READONLY (dest) = 0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ce0a439..cb2412e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-07 Jie Zhang <jie@codesourcery.com>
+
+ PR c++/42556
+ * g++.dg/init/pr42556.C: New test.
+
2010-04-07 Dodji Seketeli <dodji@redhat.com>
PR debug/43628
diff --git a/gcc/testsuite/g++.dg/init/pr42556.C b/gcc/testsuite/g++.dg/init/pr42556.C
new file mode 100644
index 0000000..27370af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr42556.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-fdump-tree-gimple" }
+
+void foo (int a, int b, int c, int d)
+{
+ int v[4] = {a, b, c, d};
+}
+
+// { dg-final { scan-tree-dump-not "v = {}" "gimple" } }
+// { dg-final { cleanup-tree-dump "gimple" } }