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
This commit is contained in:
parent
18b10a7276
commit
73ed17ff80
@ -1,3 +1,17 @@
|
||||
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>
|
||||
|
||||
PR target/21571
|
||||
|
29
gcc/expr.c
29
gcc/expr.c
@ -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
|
||||
constructed. E.g. for union { struct { int a, b; } s; } u
|
||||
= { .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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
variable-sized. */
|
||||
variable-sized. If ALLOW_FLEXARR is true, don't count flexible
|
||||
array member at the end of the structure. */
|
||||
|
||||
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));
|
||||
switch (TREE_CODE (type))
|
||||
@ -4546,7 +4547,7 @@ count_type_elements (tree type)
|
||||
if (telts && host_integerp (telts, 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)
|
||||
return 0;
|
||||
else if (max / n > m)
|
||||
@ -4563,9 +4564,23 @@ count_type_elements (tree type)
|
||||
for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
|
||||
if (TREE_CODE (f) == FIELD_DECL)
|
||||
{
|
||||
t = count_type_elements (TREE_TYPE (f));
|
||||
t = count_type_elements (TREE_TYPE (f), false);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4623,7 +4638,7 @@ mostly_zeros_p (tree exp)
|
||||
if (must_clear)
|
||||
return 1;
|
||||
|
||||
elts = count_type_elements (TREE_TYPE (exp));
|
||||
elts = count_type_elements (TREE_TYPE (exp), false);
|
||||
|
||||
return nz_elts < elts / 4;
|
||||
}
|
||||
|
@ -2706,13 +2706,18 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
|
||||
parts in, then generate code for the non-constant parts. */
|
||||
/* 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 there are "lots" of zeros, then block clear the object first. */
|
||||
if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
|
||||
&& num_nonzero_elements < num_type_elements/4)
|
||||
/* 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. */
|
||||
else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
|
||||
&& num_nonzero_elements < num_type_elements/4)
|
||||
cleared = true;
|
||||
|
||||
/* ??? This bit ought not be needed. For any element not present
|
||||
in the initializer, we should simply set them to zero. Except
|
||||
we'd need to *find* the elements that are not present, and that
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
* gcc.c-torture/execute/ieee/ieee.exp: Load gcc-dg.exp library.
|
||||
|
27
gcc/testsuite/gcc.c-torture/execute/20050613-1.c
Normal file
27
gcc/testsuite/gcc.c-torture/execute/20050613-1.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* 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)
|
||||
: MOVE_RATIO;
|
||||
|
||||
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);
|
||||
|
||||
/* ??? What to do here. If there are two fields, and we've only
|
||||
|
@ -3555,7 +3555,7 @@ extern bool initializer_zerop (tree);
|
||||
|
||||
extern void categorize_ctor_elements (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
|
||||
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. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user