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/fold-const.c | |
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/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 29 |
1 files changed, 29 insertions, 0 deletions
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; |