diff options
author | Jie Zhang <jie@codesourcery.com> | 2010-04-07 10:14:45 +0000 |
---|---|---|
committer | Jie Zhang <jiez@gcc.gnu.org> | 2010-04-07 10:14:45 +0000 |
commit | 6addabbbe815be8107207fcb6e2aa640e2e8c6ca (patch) | |
tree | 88b97457fae13a30b8afc5e88b682efba5339cfe /gcc | |
parent | 366f945f9bc15d885af5a20ed70547e96b2dafae (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr42556.C | 10 |
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" } } |