diff options
author | Richard Guenther <rguenther@suse.de> | 2007-02-04 15:15:38 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-02-04 15:15:38 +0000 |
commit | 713e3ec92fe123e868f4a7a3ece4f4581106d691 (patch) | |
tree | cada47dcc485f110239acb45110951e3b8d2c8d8 /gcc | |
parent | 5c4f0f47935386fd60e70deb452bb4422480d22f (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/pr30636.C | 17 |
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); + } +} + |