Patchwork Fix fold_nonarray_ctor_reference for flexible array members (PR tree-optimization/45919)

login
register
mail settings
Submitter Jakub Jelinek
Date Oct. 20, 2010, 7:28 p.m.
Message ID <20101020192808.GP18103@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/68468/
State New
Headers show

Comments

Jakub Jelinek - Oct. 20, 2010, 7:28 p.m.
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?

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.


	Jakub
Richard Guenther - Oct. 20, 2010, 8:57 p.m.
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
>

Patch

--- 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];
+}