aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-02-04 15:15:38 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-02-04 15:15:38 +0000
commit713e3ec92fe123e868f4a7a3ece4f4581106d691 (patch)
treecada47dcc485f110239acb45110951e3b8d2c8d8 /gcc
parent5c4f0f47935386fd60e70deb452bb4422480d22f (diff)
downloadgcc-713e3ec92fe123e868f4a7a3ece4f4581106d691.zip
gcc-713e3ec92fe123e868f4a7a3ece4f4581106d691.tar.gz
gcc-713e3ec92fe123e868f4a7a3ece4f4581106d691.tar.bz2
re PR middle-end/30636 (incorrect array bounds warning on multi-dimensional arrays)
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. * g++.dg/warn/pr30636.C: New testcase. * g++.dg/tree-ssa/tmmti-2.C: XFAIL parts. From-SVN: r121575
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c29
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/pr30636.C17
5 files changed, 59 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e757d1e..d2c3076 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 085fcd8..ee2c469 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2193c95..d53a458 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
index 9735adc..fc58994 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C
@@ -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
index 0000000..32ce6ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr30636.C
@@ -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);
+ }
+}
+