diff options
author | Jan Hubicka <jh@suse.cz> | 2008-01-13 12:18:08 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2008-01-13 11:18:08 +0000 |
commit | 3097760b308aff6ac9f037495a1ea06255409e15 (patch) | |
tree | 596610cc643347fdf39f40dd6b346e3ca41a7aab /gcc | |
parent | 42b22da88490c789d74d643de6fe928e3e6ebd83 (diff) | |
download | gcc-3097760b308aff6ac9f037495a1ea06255409e15.zip gcc-3097760b308aff6ac9f037495a1ea06255409e15.tar.gz gcc-3097760b308aff6ac9f037495a1ea06255409e15.tar.bz2 |
re PR middle-end/32135 (bogus array-ref fold triggering array overflow warning)
PR middle-end/32135
* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Do not construct
references above array bounds. This might trigger bounds checks for
pointers to arrays.
From-SVN: r131502
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr32135.c | 11 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 24 |
4 files changed, 45 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 045118a..6cd0af8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-01-12 Jan Hubicka <jh@suse.cz> + + PR middle-end/32135 + * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Do not construct + references above array bounds. This might trigger bounds checks for + pointers to arrays. + 2008-01-12 Sebastian Pop <sebastian.pop@amd.com> * tree-ssa-ter.c (free_temp_expr_table): Free num_in_part and diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 34b4ec1..b067970 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-01-13 Jan Hubicka <jh@suse.cz> + + PR middle-end/32135 + * gcc.dg/pr32135.c: new. + 2008-01-12 Doug Kwan <dougkwan@google.com> * gcc.dg/qual-return-1.c: Add -Wignored-qualifiers. diff --git a/gcc/testsuite/gcc.dg/pr32135.c b/gcc/testsuite/gcc.dg/pr32135.c new file mode 100644 index 0000000..4459656 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr32135.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Warray-bounds -O2" } */ +struct PhaseEntryType +{ + char raw_field[50 + 1]; +}; +int +ParsePhase (char in_cols[15][250], struct PhaseEntryType *P) +{ + __builtin_strncpy (P->raw_field, in_cols[2], 50); +} diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 15f14c4..f9f1217 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1588,6 +1588,7 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) { tree min_idx, idx, idx_type, elt_offset = integer_zero_node; tree array_type, elt_type, elt_size; + tree domain_type; /* If BASE is an ARRAY_REF, we can pick up another offset (this time measured in units of the size of elements type) from that ARRAY_REF). @@ -1659,9 +1660,10 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) low bound, if any, convert the index into that type, and add the low bound. */ min_idx = build_int_cst (idx_type, 0); - if (TYPE_DOMAIN (array_type)) + domain_type = TYPE_DOMAIN (array_type); + if (domain_type) { - idx_type = TYPE_DOMAIN (array_type); + idx_type = domain_type; if (TYPE_MIN_VALUE (idx_type)) min_idx = TYPE_MIN_VALUE (idx_type); else @@ -1681,6 +1683,24 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) /* Make sure to possibly truncate late after offsetting. */ idx = fold_convert (idx_type, idx); + /* We don't want to construct access past array bounds. For example + char *(c[4]); + + c[3][2]; should not be simplified into (*c)[14] or tree-vrp will give false + warning. */ + if (domain_type && TYPE_MAX_VALUE (domain_type) + && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST) + { + tree up_bound = TYPE_MAX_VALUE (domain_type); + + if (tree_int_cst_lt (up_bound, idx) + /* Accesses after the end of arrays of size 0 (gcc + extension) and 1 are likely intentional ("struct + hack"). */ + && compare_tree_int (up_bound, 1) > 0) + return NULL_TREE; + } + return build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE); } |