2007-02-04 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Feb 2007 15:15:38 +0000 (15:15 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 4 Feb 2007 15:15:38 +0000 (15:15 +0000)
PR middle-end/30636
* fold-const.c (try_move_mult_to_index): Make sure to not
overflow one dimension of a multi-dimensional array access.

* g++.dg/warn/pr30636.C: New testcase.
* g++.dg/tree-ssa/tmmti-2.C: XFAIL parts.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121575 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
gcc/testsuite/g++.dg/warn/pr30636.C [new file with mode: 0644]

index e757d1e..d2c3076 100644 (file)
@@ -1,3 +1,9 @@
+2007-02-04  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/30636
+       * fold-const.c (try_move_mult_to_index): Make sure to not
+       overflow one dimension of a multi-dimensional array access.
+
 2007-02-04  Jan Hubicka  <jh@suse.cz>
 
        * passes.c (init_optimization_passes): Reindent.
index 085fcd8..ee2c469 100644 (file)
@@ -6642,6 +6642,7 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
   tree ref = TREE_OPERAND (addr, 0), pref;
   tree ret, pos;
   tree itype;
+  bool mdim = false;
 
   /* Canonicalize op1 into a possibly non-constant delta
      and an INTEGER_CST s.  */
@@ -6681,6 +6682,10 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
     {
       if (TREE_CODE (ref) == ARRAY_REF)
        {
+         /* Remember if this was a multi-dimensional array.  */
+         if (TREE_CODE (TREE_OPERAND (ref, 0)) == ARRAY_REF)
+           mdim = true;
+
          itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
          if (! itype)
            continue;
@@ -6703,8 +6708,32 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
              delta = tmp;
            }
 
+         /* Only fold here if we can verify we do not overflow one
+            dimension of a multi-dimensional array.  */
+         if (mdim)
+           {
+             tree tmp;
+
+             if (TREE_CODE (TREE_OPERAND (ref, 1)) != INTEGER_CST
+                 || !INTEGRAL_TYPE_P (itype)
+                 || !TYPE_MAX_VALUE (itype)
+                 || TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST)
+               continue;
+
+             tmp = fold_binary (code, itype,
+                                fold_convert (itype,
+                                              TREE_OPERAND (ref, 1)),
+                                fold_convert (itype, delta));
+             if (!tmp
+                 || TREE_CODE (tmp) != INTEGER_CST
+                 || tree_int_cst_lt (TYPE_MAX_VALUE (itype), tmp))
+               continue;
+           }
+
          break;
        }
+      else
+       mdim = false;
 
       if (!handled_component_p (ref))
        return NULL_TREE;
index 2193c95..d53a458 100644 (file)
@@ -1,3 +1,9 @@
+2007-02-04  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/30636
+       * g++.dg/warn/pr30636.C: New testcase.
+       * g++.dg/tree-ssa/tmmti-2.C: XFAIL parts.
+
 2007-02-03  Uros Bizjak  <ubizjak@gmail.com>
 
        PR middle-end/30667
index 9735adc..fc58994 100644 (file)
@@ -17,6 +17,6 @@ double bar(int i)
        return *(&b[0].x + i*2); // b[i].x
 }
 
-/* { dg-final { scan-tree-dump "a\\\[.*i.*\\\]\\\[0\\\]" "optimized" } } */
+/* { dg-final { scan-tree-dump "a\\\[.*i.*\\\]\\\[0\\\]" "optimized" { xfail *-*-* } } } */
 /* { dg-final { scan-tree-dump "b\\\[.*i.*\\\].x" "optimized" } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/warn/pr30636.C b/gcc/testsuite/g++.dg/warn/pr30636.C
new file mode 100644 (file)
index 0000000..32ce6ed
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Warray-bounds" } */
+
+typedef char one_buffer[512];
+static one_buffer emergency_buffer[4];
+
+void free_exception (void *vptr)
+{
+  char *base = (char *) &emergency_buffer[0][0];
+  char *ptr = (char *) vptr;
+  if (ptr >= base && ptr < base + sizeof (emergency_buffer)) /* { dg-bogus "subscript" } */
+    {
+      /* Do something. */
+      __builtin_exit (0);
+    }
+}
+