diff options
| author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-04 15:15:38 +0000 |
|---|---|---|
| committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-04 15:15:38 +0000 |
| commit | 98f4d3829ca389b235a5f39361ac9dccc3d930b7 (patch) | |
| tree | cada47dcc485f110239acb45110951e3b8d2c8d8 /gcc | |
| parent | 560b9c9b0713f5e7019e2bf994be9f488b5df773 (diff) | |
| download | ppe42-gcc-98f4d3829ca389b235a5f39361ac9dccc3d930b7.tar.gz ppe42-gcc-98f4d3829ca389b235a5f39361ac9dccc3d930b7.zip | |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121575 138bc75d-0d04-0410-961f-82ee72b054a4
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 e757d1e8f74..d2c30766fac 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 085fcd8275b..ee2c469921c 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 2193c956386..d53a458a6e4 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 9735adc6c7d..fc5899465af 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 00000000000..32ce6edbd61 --- /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); + } +} + |

