[PATCH] Deal with variable length arrays ending structures in get_base_and_extent

Richard Guenther rguenther@suse.de
Sat Feb 4 17:54:00 GMT 2006


This fixes a bug in get_base_ref_and_extent where we return an exact
match for

  struct { int a[1]; } a;
  int d;
  a.a[d];

namely offset = 0, size = 32 and maxsize = 32 because we did not deal
with the fact that the array may extend to arbitrary memory.  This
patch fixes it to return maxsize = -1 in this case.

I believe this only applies if the base object is an INDIRECT_REF, but
just to be sure I did not include this optimization.

Bootstrapped and tested on x86_64-unknown-linux-gnu for all languages
including Ada.

Ok for mainline?

Btw, I was not able to construct a (failing) testcase exposing the bug
in PTA or salias - probably because we punt on INDIRECT_REF bases there
anyway.

Thanks,
Richard.

:ADDPATCH alias:

2006-02-04  Richard Guenther  <rguenther@suse.de>

	* tree-dfa.c (get_ref_base_and_extent): When computing maxsize
	deal with structures that end in implicitly variable sized arrays.

Index: tree-dfa.c
===================================================================
*** tree-dfa.c	(revision 110539)
--- tree-dfa.c	(working copy)
*************** get_ref_base_and_extent (tree exp, HOST_
*** 913,920 ****
    HOST_WIDE_INT maxsize = -1;
    tree size_tree = NULL_TREE;
    tree bit_offset = bitsize_zero_node;
! 
!   gcc_assert (!SSA_VAR_P (exp));
  
    /* First get the final access size from just the outermost expression.  */
    if (TREE_CODE (exp) == COMPONENT_REF)
--- 913,919 ----
    HOST_WIDE_INT maxsize = -1;
    tree size_tree = NULL_TREE;
    tree bit_offset = bitsize_zero_node;
!   bool seen_variable_array_ref = false;
  
    /* First get the final access size from just the outermost expression.  */
    if (TREE_CODE (exp) == COMPONENT_REF)
*************** get_ref_base_and_extent (tree exp, HOST_
*** 1004,1009 ****
--- 1003,1011 ----
  				    fold_convert (bitsizetype, index),
  				    bitsize_unit_node);
  		bit_offset = size_binop (PLUS_EXPR, bit_offset, index);
+ 		/* A more outer constant index array ref subsumes any
+ 		   variable array ref seen sofar.  */
+ 		seen_variable_array_ref = false;
  	      }
  	    else
  	      {
*************** get_ref_base_and_extent (tree exp, HOST_
*** 1019,1024 ****
--- 1021,1028 ----
  		  }
  		else
  		  maxsize = -1;
+ 		/* Remember we seen an array ref with a variable index.  */
+ 		seen_variable_array_ref = true;
  	      }
  	  }
  	  break;
*************** get_ref_base_and_extent (tree exp, HOST_
*** 1043,1048 ****
--- 1047,1067 ----
      }
   done:
  
+   /* We need to deal with variable arrays ending structures such as
+        struct { int length; int a[1]; } x;           x.a[d]
+        struct { struct { int a; int b; } a[1]; } x;  x.a[d].a
+        struct { struct { int a[1]; } a[1]; } x;      x.a[0][d], x.a[d][0]
+      where we do not know maxsize for variable index accesses to
+      the array.  The simplest way to conservatively deal with this
+      is to punt in the case that offset + maxsize reaches the
+      base type boundary.  */
+   if (seen_variable_array_ref
+       && maxsize != -1
+       && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+       && TREE_INT_CST_LOW (bit_offset) + maxsize
+ 	 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
+     maxsize = -1;
+ 
    /* ???  Due to negative offsets in ARRAY_REF we can end up with
       negative bit_offset here.  We might want to store a zero offset
       in this case.  */



More information about the Gcc-patches mailing list