Commit 6addabbb by Jie Zhang Committed by Jie Zhang

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
parent 366f945f
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> 2010-04-06 Taras Glek <taras@mozilla.com>
Jason Merrill <jason@redhat.com> Jason Merrill <jason@redhat.com>
......
...@@ -549,13 +549,15 @@ cxx_incomplete_type_error (const_tree value, const_tree type) ...@@ -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. */ expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */
static void static void
split_nonconstant_init_1 (tree dest, tree init) split_nonconstant_init_1 (tree dest, tree *initp)
{ {
unsigned HOST_WIDE_INT idx; unsigned HOST_WIDE_INT idx;
tree init = *initp;
tree field_index, value; tree field_index, value;
tree type = TREE_TYPE (dest); tree type = TREE_TYPE (dest);
tree inner_type = NULL; tree inner_type = NULL;
bool array_type_p = false; bool array_type_p = false;
HOST_WIDE_INT num_type_elements, num_initialized_elements;
switch (TREE_CODE (type)) switch (TREE_CODE (type))
{ {
...@@ -567,6 +569,7 @@ split_nonconstant_init_1 (tree dest, tree init) ...@@ -567,6 +569,7 @@ split_nonconstant_init_1 (tree dest, tree init)
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
case QUAL_UNION_TYPE: case QUAL_UNION_TYPE:
num_initialized_elements = 0;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
field_index, value) field_index, value)
{ {
...@@ -589,12 +592,13 @@ split_nonconstant_init_1 (tree dest, tree init) ...@@ -589,12 +592,13 @@ split_nonconstant_init_1 (tree dest, tree init)
sub = build3 (COMPONENT_REF, inner_type, dest, field_index, sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE); NULL_TREE);
split_nonconstant_init_1 (sub, value); split_nonconstant_init_1 (sub, &value);
} }
else if (!initializer_constant_valid_p (value, inner_type)) else if (!initializer_constant_valid_p (value, inner_type))
{ {
tree code; tree code;
tree sub; tree sub;
HOST_WIDE_INT inner_elements;
/* FIXME: Ordered removal is O(1) so the whole function is /* FIXME: Ordered removal is O(1) so the whole function is
worst-case quadratic. This could be fixed using an aside worst-case quadratic. This could be fixed using an aside
...@@ -617,9 +621,22 @@ split_nonconstant_init_1 (tree dest, tree init) ...@@ -617,9 +621,22 @@ split_nonconstant_init_1 (tree dest, tree init)
code = build2 (INIT_EXPR, inner_type, sub, value); code = build2 (INIT_EXPR, inner_type, sub, value);
code = build_stmt (input_location, EXPR_STMT, code); code = build_stmt (input_location, EXPR_STMT, code);
add_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; 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; break;
case VECTOR_TYPE: case VECTOR_TYPE:
...@@ -655,7 +672,7 @@ split_nonconstant_init (tree dest, tree init) ...@@ -655,7 +672,7 @@ split_nonconstant_init (tree dest, tree init)
if (TREE_CODE (init) == CONSTRUCTOR) if (TREE_CODE (init) == CONSTRUCTOR)
{ {
code = push_stmt_list (); code = push_stmt_list ();
split_nonconstant_init_1 (dest, init); split_nonconstant_init_1 (dest, &init);
code = pop_stmt_list (code); code = pop_stmt_list (code);
DECL_INITIAL (dest) = init; DECL_INITIAL (dest) = init;
TREE_READONLY (dest) = 0; TREE_READONLY (dest) = 0;
......
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> 2010-04-07 Dodji Seketeli <dodji@redhat.com>
PR debug/43628 PR debug/43628
......
// { 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" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment