Message ID | 20101020192808.GP18103@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Oct 20, 2010 at 9:28 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > If an aggregate has flexible array member, field_size will be NULL. > But as flexible array member must come last, we can just assume it covers > the rest of the size. > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Thanks, Richard. > 2010-10-20 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/45919 > * tree-ssa-ccp.c (fold_nonarray_ctor_reference): Handle flexible > array members. > > * gcc.c-torture/compile/pr45919.c: New test. > > --- gcc/tree-ssa-ccp.c.jj 2010-10-07 19:45:22.000000000 +0200 > +++ gcc/tree-ssa-ccp.c 2010-10-20 15:51:34.000000000 +0200 > @@ -1523,23 +1523,30 @@ fold_nonarray_ctor_reference (tree type, > double_int bits_per_unit_cst = uhwi_to_double_int (BITS_PER_UNIT); > double_int bitoffset_end; > > - /* Variable sized objects in static constructors makes no sense. */ > + /* Variable sized objects in static constructors makes no sense, > + but field_size can be NULL for flexible array members. */ > gcc_assert (TREE_CODE (field_offset) == INTEGER_CST > && TREE_CODE (byte_offset) == INTEGER_CST > - && TREE_CODE (field_size) == INTEGER_CST); > + && (field_size != NULL_TREE > + ? TREE_CODE (field_size) == INTEGER_CST > + : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE)); > > /* Compute bit offset of the field. */ > bitoffset = double_int_add (tree_to_double_int (field_offset), > double_int_mul (byte_offset_cst, > bits_per_unit_cst)); > /* Compute bit offset where the field ends. */ > - bitoffset_end = double_int_add (bitoffset, > - tree_to_double_int (field_size)); > + if (field_size != NULL_TREE) > + bitoffset_end = double_int_add (bitoffset, > + tree_to_double_int (field_size)); > + else > + bitoffset_end = double_int_zero; > > /* Is OFFSET in the range (BITOFFSET, BITOFFSET_END)? */ > if (double_int_cmp (uhwi_to_double_int (offset), bitoffset, 0) >= 0 > - && double_int_cmp (uhwi_to_double_int (offset), > - bitoffset_end, 0) < 0) > + && (field_size == NULL_TREE > + || double_int_cmp (uhwi_to_double_int (offset), > + bitoffset_end, 0) < 0)) > { > double_int access_end = double_int_add (uhwi_to_double_int (offset), > uhwi_to_double_int (size)); > --- gcc/testsuite/gcc.c-torture/compile/pr45919.c.jj 2010-10-20 16:40:11.000000000 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr45919.c 2010-10-20 16:40:01.000000000 +0200 > @@ -0,0 +1,9 @@ > +/* PR tree-optimization/45919 */ > + > +const struct S { int a; int b[]; } s = { 0, { 0 }}; > + > +int > +foo (void) > +{ > + return s.b[0]; > +} > > Jakub >
--- gcc/tree-ssa-ccp.c.jj 2010-10-07 19:45:22.000000000 +0200 +++ gcc/tree-ssa-ccp.c 2010-10-20 15:51:34.000000000 +0200 @@ -1523,23 +1523,30 @@ fold_nonarray_ctor_reference (tree type, double_int bits_per_unit_cst = uhwi_to_double_int (BITS_PER_UNIT); double_int bitoffset_end; - /* Variable sized objects in static constructors makes no sense. */ + /* Variable sized objects in static constructors makes no sense, + but field_size can be NULL for flexible array members. */ gcc_assert (TREE_CODE (field_offset) == INTEGER_CST && TREE_CODE (byte_offset) == INTEGER_CST - && TREE_CODE (field_size) == INTEGER_CST); + && (field_size != NULL_TREE + ? TREE_CODE (field_size) == INTEGER_CST + : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE)); /* Compute bit offset of the field. */ bitoffset = double_int_add (tree_to_double_int (field_offset), double_int_mul (byte_offset_cst, bits_per_unit_cst)); /* Compute bit offset where the field ends. */ - bitoffset_end = double_int_add (bitoffset, - tree_to_double_int (field_size)); + if (field_size != NULL_TREE) + bitoffset_end = double_int_add (bitoffset, + tree_to_double_int (field_size)); + else + bitoffset_end = double_int_zero; /* Is OFFSET in the range (BITOFFSET, BITOFFSET_END)? */ if (double_int_cmp (uhwi_to_double_int (offset), bitoffset, 0) >= 0 - && double_int_cmp (uhwi_to_double_int (offset), - bitoffset_end, 0) < 0) + && (field_size == NULL_TREE + || double_int_cmp (uhwi_to_double_int (offset), + bitoffset_end, 0) < 0)) { double_int access_end = double_int_add (uhwi_to_double_int (offset), uhwi_to_double_int (size)); --- gcc/testsuite/gcc.c-torture/compile/pr45919.c.jj 2010-10-20 16:40:11.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr45919.c 2010-10-20 16:40:01.000000000 +0200 @@ -0,0 +1,9 @@ +/* PR tree-optimization/45919 */ + +const struct S { int a; int b[]; } s = { 0, { 0 }}; + +int +foo (void) +{ + return s.b[0]; +}