This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix overflows in get_ref_base_and_extent (PR tree-optimization/59779)


Hi Jakub,

Is this change different from the one attached to PR? I have a bootstrap/regtest
going with it.

Dave

On 3/13/2014 1:50 PM, Jakub Jelinek wrote:
Hi!

The outer-1.c testcase apparently fails on 32-bit HWI targets, the problem
is that the int x[10000][10000]; array has bitsize that fits into uhwi, but
not shwi, so we get negative maxsize that isn't -1.

After discussions with Richard on IRC, I've implemented computation of
bitsize and maxsize in double_int.

Bootstrapped/regtested on x86_64-linux and i686-linux, with
bootstrap/regtest time changes in the noise.  Ok for trunk?

John, could you please test this on some 32-bit HWI target with
bootstrap/regtest?

2014-03-13  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/59779
	* tree-dfa.c (get_ref_base_and_extent): Use double_int
	type for bitsize and maxsize instead of HOST_WIDE_INT.

--- gcc/tree-dfa.c.jj	2014-01-03 11:40:57.000000000 +0100
+++ gcc/tree-dfa.c	2014-03-13 12:10:46.367886640 +0100
@@ -389,11 +389,10 @@ get_ref_base_and_extent (tree exp, HOST_
  			 HOST_WIDE_INT *psize,
  			 HOST_WIDE_INT *pmax_size)
  {
-  HOST_WIDE_INT bitsize = -1;
-  HOST_WIDE_INT maxsize = -1;
+  double_int bitsize = double_int_minus_one;
+  double_int maxsize;
    tree size_tree = NULL_TREE;
    double_int bit_offset = double_int_zero;
-  HOST_WIDE_INT hbit_offset;
    bool seen_variable_array_ref = false;
/* First get the final access size from just the outermost expression. */
@@ -407,15 +406,11 @@ get_ref_base_and_extent (tree exp, HOST_
        if (mode == BLKmode)
  	size_tree = TYPE_SIZE (TREE_TYPE (exp));
        else
-	bitsize = GET_MODE_BITSIZE (mode);
-    }
-  if (size_tree != NULL_TREE)
-    {
-      if (! tree_fits_uhwi_p (size_tree))
-	bitsize = -1;
-      else
-	bitsize = tree_to_uhwi (size_tree);
+	bitsize = double_int::from_uhwi (GET_MODE_BITSIZE (mode));
      }
+  if (size_tree != NULL_TREE
+      && TREE_CODE (size_tree) == INTEGER_CST)
+    bitsize = tree_to_double_int (size_tree);
/* Initially, maxsize is the same as the accessed element size.
       In the following it will only grow (or become -1).  */
@@ -448,7 +443,7 @@ get_ref_base_and_extent (tree exp, HOST_
  		   referenced the last field of a struct or a union member
  		   then we have to adjust maxsize by the padding at the end
  		   of our field.  */
-		if (seen_variable_array_ref && maxsize != -1)
+		if (seen_variable_array_ref && !maxsize.is_minus_one ())
  		  {
  		    tree stype = TREE_TYPE (TREE_OPERAND (exp, 0));
  		    tree next = DECL_CHAIN (field);
@@ -459,15 +454,22 @@ get_ref_base_and_extent (tree exp, HOST_
  		      {
  			tree fsize = DECL_SIZE_UNIT (field);
  			tree ssize = TYPE_SIZE_UNIT (stype);
-			if (tree_fits_shwi_p (fsize)
-			    && tree_fits_shwi_p (ssize)
-			    && doffset.fits_shwi ())
-			  maxsize += ((tree_to_shwi (ssize)
-				       - tree_to_shwi (fsize))
-				      * BITS_PER_UNIT
-					- doffset.to_shwi ());
+			if (fsize == NULL
+			    || TREE_CODE (fsize) != INTEGER_CST
+			    || ssize == NULL
+			    || TREE_CODE (ssize) != INTEGER_CST)
+			  maxsize = double_int_minus_one;
  			else
-			  maxsize = -1;
+			  {
+			    double_int tem = tree_to_double_int (ssize)
+					     - tree_to_double_int (fsize);
+			    if (BITS_PER_UNIT == 8)
+			      tem = tem.lshift (3);
+			    else
+			      tem *= double_int::from_uhwi (BITS_PER_UNIT);
+			    tem -= doffset;
+			    maxsize += tem;
+			  }
  		      }
  		  }
  	      }
@@ -477,13 +479,12 @@ get_ref_base_and_extent (tree exp, HOST_
  		/* We need to adjust maxsize to the whole structure bitsize.
  		   But we can subtract any constant offset seen so far,
  		   because that would get us out of the structure otherwise.  */
-		if (maxsize != -1
+		if (!maxsize.is_minus_one ()
  		    && csize
-		    && tree_fits_uhwi_p (csize)
-		    && bit_offset.fits_shwi ())
-		  maxsize = tree_to_uhwi (csize) - bit_offset.to_shwi ();
+		    && TREE_CODE (csize) == INTEGER_CST)
+		  maxsize = tree_to_double_int (csize) - bit_offset;
  		else
-		  maxsize = -1;
+		  maxsize = double_int_minus_one;
  	      }
  	  }
  	  break;
@@ -520,13 +521,12 @@ get_ref_base_and_extent (tree exp, HOST_
  		/* We need to adjust maxsize to the whole array bitsize.
  		   But we can subtract any constant offset seen so far,
  		   because that would get us outside of the array otherwise.  */
-		if (maxsize != -1
+		if (!maxsize.is_minus_one ()
  		    && asize
-		    && tree_fits_uhwi_p (asize)
-		    && bit_offset.fits_shwi ())
-		  maxsize = tree_to_uhwi (asize) - bit_offset.to_shwi ();
+		    && TREE_CODE (asize) == INTEGER_CST)
+		  maxsize = tree_to_double_int (asize) - bit_offset;
  		else
-		  maxsize = -1;
+		  maxsize = double_int_minus_one;
/* Remember that we have seen an array ref with a variable
  		   index.  */
@@ -539,7 +539,7 @@ get_ref_base_and_extent (tree exp, HOST_
  	  break;
case IMAGPART_EXPR:
-	  bit_offset += double_int::from_uhwi (bitsize);
+	  bit_offset += bitsize;
  	  break;
case VIEW_CONVERT_EXPR:
@@ -553,7 +553,7 @@ get_ref_base_and_extent (tree exp, HOST_
  	    {
  	      exp = TREE_OPERAND (TMR_BASE (exp), 0);
  	      bit_offset = double_int_zero;
-	      maxsize = -1;
+	      maxsize = double_int_minus_one;
  	      goto done;
  	    }
  	  /* Fallthru.  */
@@ -569,13 +569,12 @@ get_ref_base_and_extent (tree exp, HOST_
  	     base type boundary.  This needs to include possible trailing
  	     padding that is there for alignment purposes.  */
  	  if (seen_variable_array_ref
-	      && maxsize != -1
-	      && (!bit_offset.fits_shwi ()
-		  || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp)))
-		  || (bit_offset.to_shwi () + maxsize
-		      == (HOST_WIDE_INT) tree_to_uhwi
-		            (TYPE_SIZE (TREE_TYPE (exp))))))
-	    maxsize = -1;
+	      && !maxsize.is_minus_one ()
+	      && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE
+		  || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
+		  || (bit_offset + maxsize
+		      == tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp))))))
+	    maxsize = double_int_minus_one;
/* Hand back the decl for MEM[&decl, off]. */
  	  if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
@@ -606,25 +605,32 @@ get_ref_base_and_extent (tree exp, HOST_
/* We need to deal with variable arrays ending structures. */
    if (seen_variable_array_ref
-      && maxsize != -1
-      && (!bit_offset.fits_shwi ()
-	  || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp)))
-	  || (bit_offset.to_shwi () + maxsize
-	      == (HOST_WIDE_INT) tree_to_uhwi
-	           (TYPE_SIZE (TREE_TYPE (exp))))))
-    maxsize = -1;
+      && !maxsize.is_minus_one ()
+      && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE
+	  || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
+	  || (bit_offset + maxsize
+	      == tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp))))))
+    maxsize = double_int_minus_one;
done:
-  if (!bit_offset.fits_shwi ())
+  if (!bitsize.fits_shwi () || bitsize.is_negative ())
      {
        *poffset = 0;
-      *psize = bitsize;
+      *psize = -1;
        *pmax_size = -1;
return exp;
      }
- hbit_offset = bit_offset.to_shwi ();
+  *psize = bitsize.to_shwi ();
+
+  if (!bit_offset.fits_shwi ())
+    {
+      *poffset = 0;
+      *pmax_size = -1;
+
+      return exp;
+    }
/* In case of a decl or constant base object we can do better. */ @@ -632,25 +638,30 @@ get_ref_base_and_extent (tree exp, HOST_
      {
        /* If maxsize is unknown adjust it according to the size of the
           base decl.  */
-      if (maxsize == -1
-	  && tree_fits_uhwi_p (DECL_SIZE (exp)))
-	maxsize = tree_to_uhwi (DECL_SIZE (exp)) - hbit_offset;
+      if (maxsize.is_minus_one ()
+	  && DECL_SIZE (exp)
+	  && TREE_CODE (DECL_SIZE (exp)) == INTEGER_CST)
+	maxsize = tree_to_double_int (DECL_SIZE (exp)) - bit_offset;
      }
    else if (CONSTANT_CLASS_P (exp))
      {
        /* If maxsize is unknown adjust it according to the size of the
           base type constant.  */
-      if (maxsize == -1
-	  && tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))))
-	maxsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (exp))) - hbit_offset;
+      if (maxsize.is_minus_one ()
+	  && TYPE_SIZE (TREE_TYPE (exp))
+	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST)
+	maxsize = tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp)))
+		  - bit_offset;
      }
/* ??? 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.  */
-  *poffset = hbit_offset;
-  *psize = bitsize;
-  *pmax_size = maxsize;
+  *poffset = bit_offset.to_shwi ();
+  if (!maxsize.fits_shwi () || maxsize.is_negative ())
+    *pmax_size = -1;
+  else
+    *pmax_size = maxsize.to_shwi ();
return exp;
  }

	Jakub




--
John David Anglin    dave.anglin@bell.net


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]