From 1fd8906045746e33fbb2a14f8d6dbaa67045dc5b Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sat, 15 Mar 2008 14:27:55 +0000 Subject: [PATCH] re PR middle-end/35593 (spurious warning "array subscript is below array bounds" with void* function argument plus -O2) 2008-03-15 Richard Guenther PR middle-end/35593 * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Make sure to not produce negative array indices if not allowed. Add parameter to indicate that. (maybe_fold_offset_to_component_ref): Allow negative array indices only for the first member of a structure. (maybe_fold_offset_to_reference): Allow negative array indices. (maybe_fold_stmt_addition): Likewise. * g++.dg/warn/Warray-bounds-3.C: New testcase. From-SVN: r133249 --- gcc/ChangeLog | 11 ++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/warn/Warray-bounds-3.C | 15 ++++++++ gcc/tree-ssa-ccp.c | 38 +++++++++++++++------ 4 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Warray-bounds-3.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c97c1a394a6..b0e25a461bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-03-15 Richard Guenther + + PR middle-end/35593 + * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Make sure + to not produce negative array indices if not allowed. Add + parameter to indicate that. + (maybe_fold_offset_to_component_ref): Allow negative array + indices only for the first member of a structure. + (maybe_fold_offset_to_reference): Allow negative array indices. + (maybe_fold_stmt_addition): Likewise. + 2008-03-15 Bjoern Haase Anatoly Sokolov diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab02e686fc7..f453ce1c2c3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-15 Richard Guenther + + PR middle-end/35593 + * g++.dg/warn/Warray-bounds-3.C: New testcase. + 2008-03-15 Jerry DeLisle PR testsuite/35478 diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-3.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-3.C new file mode 100644 index 00000000000..a8585717988 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-3.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +extern void function(void * x); + +struct A { + long x; + char d[0]; +}; + + +void test(A * a) { + function((char *)a - 4); /* { dg-bogus "below array bounds" } */ +} + diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 7cefbf83893..8b8a902169e 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1593,7 +1593,8 @@ widen_bitfield (tree val, tree field, tree var) is the desired result type. */ static tree -maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) +maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type, + bool allow_negative_idx) { tree min_idx, idx, idx_type, elt_offset = integer_zero_node; tree array_type, elt_type, elt_size; @@ -1693,11 +1694,15 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) 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) + char *(c[4]); + c[3][2]; + should not be simplified into (*c)[14] or tree-vrp will + give false warnings. The same is true for + struct A { long x; char d[0]; } *a; + (char *)a - 4; + which should be not folded to &a->d[-8]. */ + 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); @@ -1709,6 +1714,17 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) && compare_tree_int (up_bound, 1) > 0) return NULL_TREE; } + if (domain_type + && TYPE_MIN_VALUE (domain_type)) + { + if (!allow_negative_idx + && TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST + && tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type))) + return NULL_TREE; + } + else if (!allow_negative_idx + && compare_tree_int (idx, 0) < 0) + return NULL_TREE; return build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE); } @@ -1805,7 +1821,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE); /* Recurse to possibly find the match. */ - ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type); + ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type, + f == TYPE_FIELDS (record_type)); if (ret) return ret; ret = maybe_fold_offset_to_component_ref (field_type, new_base, t, @@ -1827,7 +1844,8 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, base = build1 (INDIRECT_REF, record_type, base); base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE); - t = maybe_fold_offset_to_array_ref (base, offset, orig_type); + t = maybe_fold_offset_to_array_ref (base, offset, orig_type, + f == TYPE_FIELDS (record_type)); if (t) return t; return maybe_fold_offset_to_component_ref (field_type, base, offset, @@ -1893,7 +1911,7 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type) { if (base_is_ptr) base = build1 (INDIRECT_REF, type, base); - ret = maybe_fold_offset_to_array_ref (base, offset, orig_type); + ret = maybe_fold_offset_to_array_ref (base, offset, orig_type, true); } return ret; } @@ -2070,7 +2088,7 @@ maybe_fold_stmt_addition (tree expr) ptd_type = TREE_TYPE (ptr_type); /* At which point we can try some of the same things as for indirects. */ - t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type); + t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true); if (!t) t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1, ptd_type, false); -- 2.30.2