diff options
author | Richard Guenther <rguenther@suse.de> | 2010-05-25 15:49:34 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-05-25 15:49:34 +0000 |
commit | c946a318432341ea470c5f7540490a87823aaedd (patch) | |
tree | 73a47c9d393c96ebe9abf0772ccfbfc4fc116624 | |
parent | 50ee30d539971a73447f01f61c1e66302c3c91d0 (diff) | |
download | gcc-c946a318432341ea470c5f7540490a87823aaedd.zip gcc-c946a318432341ea470c5f7540490a87823aaedd.tar.gz gcc-c946a318432341ea470c5f7540490a87823aaedd.tar.bz2 |
re PR middle-end/44069 (optimization bug initializing from cast array)
2010-05-25 Richard Guenther <rguenther@suse.de>
PR middle-end/44069
* gimple-fold.c (maybe_fold_stmt_addition): Avoid generating
out-of-bounds array accesses.
* g++.dg/torture/pr44069.C: New testcase.
From-SVN: r159824
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr44069.C | 25 |
4 files changed, 48 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a7e80c..02fb290 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-05-25 Richard Guenther <rguenther@suse.de> + PR middle-end/44069 + * gimple-fold.c (maybe_fold_stmt_addition): Avoid generating + out-of-bounds array accesses. + +2010-05-25 Richard Guenther <rguenther@suse.de> + * lto-wrapper.c (nr, input_names, output_names, makefile): Globalize. (lto_wrapper_exit): Unlink all LTRANS temporary files on error. (run_gcc): Re-organize to make cleanup easier. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 4fb1b3f..e74f524 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -640,6 +640,18 @@ maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1) if (!is_gimple_assign (offset_def)) return NULL_TREE; + /* As we will end up creating a variable index array access + in the outermost array dimension make sure there isn't + a more inner array that the index could overflow to. */ + if (TREE_CODE (TREE_OPERAND (op0, 0)) == ARRAY_REF) + return NULL_TREE; + + /* Do not build array references of something that we can't + see the true number of array dimensions for. */ + if (!DECL_P (TREE_OPERAND (op0, 0)) + && !handled_component_p (TREE_OPERAND (op0, 0))) + return NULL_TREE; + if (gimple_assign_rhs_code (offset_def) == MULT_EXPR && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a65db83..42e23ab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2010-05-25 Richard Guenther <rguenther@suse.de> + PR middle-end/44069 + * g++.dg/torture/pr44069.C: New testcase. + +2010-05-25 Richard Guenther <rguenther@suse.de> + * gcc.dg/tree-ssa/sra-10.c: Do not dump esra details. 2010-05-25 Iain Sandoe <iains@gcc.gnu.org> diff --git a/gcc/testsuite/g++.dg/torture/pr44069.C b/gcc/testsuite/g++.dg/torture/pr44069.C new file mode 100644 index 0000000..99fcd17 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr44069.C @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +template <unsigned R, unsigned C> +class M { +public: + M(const int* arr) { + for (unsigned long r = 0; r < R; ++r) + for (unsigned long c = 0; c < C; ++c) + m[r*C+c] = arr[r*C+c]; + } + int operator()(unsigned r, unsigned c) const + { return m[r*C+c]; } +private: + int m[R*C]; +}; +extern "C" void abort (void); +int main() +{ + int vals[2][2] = { { 1, 2 }, { 5, 6 } }; + M<2,2> m( &(vals[0][0]) ); + if (m(1,0) != 5) + abort (); + return 0; +} + |