From 98f4d3829ca389b235a5f39361ac9dccc3d930b7 Mon Sep 17 00:00:00 2001 From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Sun, 4 Feb 2007 15:15:38 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++++ gcc/fold-const.c | 29 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C | 2 +- gcc/testsuite/g++.dg/warn/pr30636.C | 17 +++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/pr30636.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e757d1e8f74c..d2c30766facb 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 085fcd8275be..ee2c469921c5 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 2193c9563861..d53a458a6e41 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 9735adc6c7db..fc5899465af2 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 000000000000..32ce6edbd61c --- /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); + } +} + -- GitLab