Commit 73ed17ff by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/22043 (Fields not initialized for automatic structs with flexible array members)

	PR tree-optimization/22043
	* tree.h (count_type_elements): Add ALLOW_FLEXARR argument.
	* expr.c (count_type_elements): Add ALLOW_FLEXARR argument.
	If ALLOW_FLEXARR, handle types ending with flexible array member.
	Pass false as second argument to recursive count_type_elements calls.
	(categorize_ctor_elements_1, mostly_zeros_p): Pass false as second
	argument to count_type_elements call.
	* tree-sra.c (decide_block_copy): Likewise.
	* gimplify.c (gimplify_init_constructor): If num_type_elements < 0
	for a constant-sized object, set cleared as well.  Pass true as
	second argument to count_type_elements call.

	* gcc.c-torture/execute/20050613-1.c: New test.

From-SVN: r103389
parent 18b10a72
2005-08-23 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/22043
* tree.h (count_type_elements): Add ALLOW_FLEXARR argument.
* expr.c (count_type_elements): Add ALLOW_FLEXARR argument.
If ALLOW_FLEXARR, handle types ending with flexible array member.
Pass false as second argument to recursive count_type_elements calls.
(categorize_ctor_elements_1, mostly_zeros_p): Pass false as second
argument to count_type_elements call.
* tree-sra.c (decide_block_copy): Likewise.
* gimplify.c (gimplify_init_constructor): If num_type_elements < 0
for a constant-sized object, set cleared as well. Pass true as
second argument to count_type_elements call.
2005-08-23 Alan Modra <amodra@bigpond.net.au> 2005-08-23 Alan Modra <amodra@bigpond.net.au>
PR target/21571 PR target/21571
......
...@@ -4504,7 +4504,7 @@ categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts, ...@@ -4504,7 +4504,7 @@ categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts,
/* And now we have to find out if the element itself is fully /* And now we have to find out if the element itself is fully
constructed. E.g. for union { struct { int a, b; } s; } u constructed. E.g. for union { struct { int a, b; } s; } u
= { .s = { .a = 1 } }. */ = { .s = { .a = 1 } }. */
if (elt_count == count_type_elements (init_sub_type)) if (elt_count == count_type_elements (init_sub_type, false))
clear_this = false; clear_this = false;
} }
} }
...@@ -4532,10 +4532,11 @@ categorize_ctor_elements (tree ctor, HOST_WIDE_INT *p_nz_elts, ...@@ -4532,10 +4532,11 @@ categorize_ctor_elements (tree ctor, HOST_WIDE_INT *p_nz_elts,
} }
/* Count the number of scalars in TYPE. Return -1 on overflow or /* Count the number of scalars in TYPE. Return -1 on overflow or
variable-sized. */ variable-sized. If ALLOW_FLEXARR is true, don't count flexible
array member at the end of the structure. */
HOST_WIDE_INT HOST_WIDE_INT
count_type_elements (tree type) count_type_elements (tree type, bool allow_flexarr)
{ {
const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1)); const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1));
switch (TREE_CODE (type)) switch (TREE_CODE (type))
...@@ -4546,7 +4547,7 @@ count_type_elements (tree type) ...@@ -4546,7 +4547,7 @@ count_type_elements (tree type)
if (telts && host_integerp (telts, 1)) if (telts && host_integerp (telts, 1))
{ {
HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1; HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1;
HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type)); HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type), false);
if (n == 0) if (n == 0)
return 0; return 0;
else if (max / n > m) else if (max / n > m)
...@@ -4563,9 +4564,23 @@ count_type_elements (tree type) ...@@ -4563,9 +4564,23 @@ count_type_elements (tree type)
for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
if (TREE_CODE (f) == FIELD_DECL) if (TREE_CODE (f) == FIELD_DECL)
{ {
t = count_type_elements (TREE_TYPE (f)); t = count_type_elements (TREE_TYPE (f), false);
if (t < 0) if (t < 0)
return -1; {
/* Check for structures with flexible array member. */
tree tf = TREE_TYPE (f);
if (allow_flexarr
&& TREE_CHAIN (f) == NULL
&& TREE_CODE (tf) == ARRAY_TYPE
&& TYPE_DOMAIN (tf)
&& TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
&& integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
&& !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
&& int_size_in_bytes (type) >= 0)
break;
return -1;
}
n += t; n += t;
} }
...@@ -4623,7 +4638,7 @@ mostly_zeros_p (tree exp) ...@@ -4623,7 +4638,7 @@ mostly_zeros_p (tree exp)
if (must_clear) if (must_clear)
return 1; return 1;
elts = count_type_elements (TREE_TYPE (exp)); elts = count_type_elements (TREE_TYPE (exp), false);
return nz_elts < elts / 4; return nz_elts < elts / 4;
} }
......
...@@ -2706,13 +2706,18 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -2706,13 +2706,18 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
parts in, then generate code for the non-constant parts. */ parts in, then generate code for the non-constant parts. */
/* TODO. There's code in cp/typeck.c to do this. */ /* TODO. There's code in cp/typeck.c to do this. */
num_type_elements = count_type_elements (TREE_TYPE (ctor)); num_type_elements = count_type_elements (type, true);
/* If count_type_elements could not determine number of type elements
for a constant-sized object, assume clearing is needed.
Don't do this for variable-sized objects, as store_constructor
will ignore the clearing of variable-sized objects. */
if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
cleared = true;
/* If there are "lots" of zeros, then block clear the object first. */ /* If there are "lots" of zeros, then block clear the object first. */
if (num_type_elements - num_nonzero_elements > CLEAR_RATIO else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
&& num_nonzero_elements < num_type_elements/4) && num_nonzero_elements < num_type_elements/4)
cleared = true; cleared = true;
/* ??? This bit ought not be needed. For any element not present /* ??? This bit ought not be needed. For any element not present
in the initializer, we should simply set them to zero. Except in the initializer, we should simply set them to zero. Except
we'd need to *find* the elements that are not present, and that we'd need to *find* the elements that are not present, and that
......
2005-08-23 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/22043
* gcc.c-torture/execute/20050613-1.c: New test.
2005-08-23 Ben Elliston <bje@au.ibm.com> 2005-08-23 Ben Elliston <bje@au.ibm.com>
* gcc.c-torture/execute/ieee/ieee.exp: Load gcc-dg.exp library. * gcc.c-torture/execute/ieee/ieee.exp: Load gcc-dg.exp library.
......
/* PR tree-optimization/22043 */
extern void abort (void);
struct A { int i; int j; int k; int l; };
struct B { struct A a; int r[1]; };
struct C { struct A a; int r[0]; };
struct D { struct A a; int r[]; };
void
foo (struct A *x)
{
if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0)
abort ();
}
int
main ()
{
struct B b = { .a.j = 5 };
struct C c = { .a.j = 5 };
struct D d = { .a.j = 5 };
foo (&b.a);
foo (&c.a);
foo (&d.a);
return 0;
}
...@@ -1338,7 +1338,7 @@ decide_block_copy (struct sra_elt *elt) ...@@ -1338,7 +1338,7 @@ decide_block_copy (struct sra_elt *elt)
: MOVE_RATIO; : MOVE_RATIO;
full_size = tree_low_cst (size_tree, 1); full_size = tree_low_cst (size_tree, 1);
full_count = count_type_elements (elt->type); full_count = count_type_elements (elt->type, false);
inst_count = sum_instantiated_sizes (elt, &inst_size); inst_count = sum_instantiated_sizes (elt, &inst_size);
/* ??? What to do here. If there are two fields, and we've only /* ??? What to do here. If there are two fields, and we've only
......
...@@ -3555,7 +3555,7 @@ extern bool initializer_zerop (tree); ...@@ -3555,7 +3555,7 @@ extern bool initializer_zerop (tree);
extern void categorize_ctor_elements (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, extern void categorize_ctor_elements (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
HOST_WIDE_INT *, bool *); HOST_WIDE_INT *, bool *);
extern HOST_WIDE_INT count_type_elements (tree); extern HOST_WIDE_INT count_type_elements (tree, bool);
/* add_var_to_bind_expr (bind_expr, var) binds var to bind_expr. */ /* add_var_to_bind_expr (bind_expr, var) binds var to bind_expr. */
......
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