tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1 if *poffset + *pmax_size...
authorJakub Jelinek <jakub@redhat.com>
Mon, 2 Oct 2017 15:48:55 +0000 (17:48 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 2 Oct 2017 15:48:55 +0000 (17:48 +0200)
* tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1
if *poffset + *pmax_size overflows in HOST_WIDE_INT.
Set *poffset to 0 and *psize and *pmax_size to -1 if
*poffset + *psize overflows in HOST_WIDE_INT.

* gcc.dg/pr82389.c: New test.

From-SVN: r253357

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr82389.c [new file with mode: 0644]
gcc/tree-dfa.c

index 7ee72e4708e0dd6c69104b897fe13806533ef898..bcd9ddd51ec522e9165216974e38d76a85024369 100644 (file)
@@ -1,5 +1,10 @@
 2017-10-02  Jakub Jelinek  <jakub@redhat.com>
 
+       * tree-dfa.c (get_ref_base_and_extent): Set *pmax_size to -1
+       if *poffset + *pmax_size overflows in HOST_WIDE_INT.
+       Set *poffset to 0 and *psize and *pmax_size to -1 if
+       *poffset + *psize overflows in HOST_WIDE_INT.
+
        PR tree-optimization/82387
        PR tree-optimization/82388
        PR tree-optimization/82389
index 2b75536209a771be0e4103ee992c1367bc9cd853..0d92d3314784213fbe74a2a7b020fed40817b62d 100644 (file)
@@ -1,5 +1,7 @@
 2017-10-02  Jakub Jelinek  <jakub@redhat.com>
 
+       * gcc.dg/pr82389.c: New test.
+
        PR tree-optimization/82387
        PR tree-optimization/82388
        PR tree-optimization/82389
diff --git a/gcc/testsuite/gcc.dg/pr82389.c b/gcc/testsuite/gcc.dg/pr82389.c
new file mode 100644 (file)
index 0000000..eae5957
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR tree-optimization/82389 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-w -O3" } */
+
+struct S { char s[0x40000000]; } s;
+
+void
+foo (struct S *p)
+{
+  char b[0x0ffffffff0000000L];
+  *(struct S *)&b[0x0fffffffef000000L] = s;
+  *p = *(struct S *)&b[0x0fffffffefffffffL];
+}
index 2e65a4443fc2c85ecbf156fab8bd331788e5b682..db69bda32f69bcd853438f523b457b3127bc1ad9 100644 (file)
@@ -654,7 +654,22 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
   if (!wi::fits_shwi_p (maxsize) || wi::neg_p (maxsize))
     *pmax_size = -1;
   else
-    *pmax_size = maxsize.to_shwi ();
+    {
+      *pmax_size = maxsize.to_shwi ();
+      if (*poffset > HOST_WIDE_INT_MAX - *pmax_size)
+       *pmax_size = -1;
+    }
+
+  /* Punt if *POFFSET + *PSIZE overflows in HOST_WIDE_INT, the callers don't
+     check for such overflows individually and assume it works.  */
+  if (*psize != -1 && *poffset > HOST_WIDE_INT_MAX - *psize)
+    {
+      *poffset = 0;
+      *psize = -1;
+      *pmax_size = -1;
+
+      return exp;
+    }
 
   return exp;
 }