aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-03-18 23:48:50 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-03-18 17:48:50 -0600
commitc46c9745aaa1a6e7df1d2421ad906d2a6a30d465 (patch)
tree1e375010fc08fedcfa5a5fce2bf640b561071291 /gcc/tree-vrp.c
parenteea4e2ff0a3f5e7f37df204c070cc5d9ef339e6e (diff)
downloadgcc-c46c9745aaa1a6e7df1d2421ad906d2a6a30d465.zip
gcc-c46c9745aaa1a6e7df1d2421ad906d2a6a30d465.tar.gz
gcc-c46c9745aaa1a6e7df1d2421ad906d2a6a30d465.tar.bz2
PR tree-optimization/89720 - Spurious -Warray-bounds warning on a range with max < min
gcc/ChangeLog: PR tree-optimization/89720 * tree-vrp.c (vrp_prop::check_mem_ref): Treat range with max < min more conservatively, the same as anti-range. gcc/testsuite/ChangeLog: PR tree-optimization/89720 * gcc.dg/Warray-bounds-42.c: New test. From-SVN: r269785
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c33
1 files changed, 14 insertions, 19 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 1092fe0..0a17271 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4546,9 +4546,9 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
const value_range *vr = NULL;
/* Determine the offsets and increment OFFRANGE for the bounds of each.
- The loop computes the the range of the final offset for expressions
- such as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs
- in some range. */
+ The loop computes the range of the final offset for expressions such
+ as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in
+ some range. */
while (TREE_CODE (arg) == SSA_NAME)
{
gimple *def = SSA_NAME_DEF_STMT (arg);
@@ -4583,26 +4583,21 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
if (vr->kind () == VR_RANGE)
{
- if (tree_int_cst_lt (vr->min (), vr->max ()))
+ offset_int min
+ = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
+ offset_int max
+ = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
+ if (min < max)
{
- offset_int min
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
- offset_int max
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
- if (min < max)
- {
- offrange[0] += min;
- offrange[1] += max;
- }
- else
- {
- offrange[0] += max;
- offrange[1] += min;
- }
+ offrange[0] += min;
+ offrange[1] += max;
}
else
{
- /* Conservatively add [-MAXOBJSIZE -1, MAXOBJSIZE]
+ /* When MIN >= MAX, the offset is effectively in a union
+ of two ranges: [-MAXOBJSIZE -1, MAX] and [MIN, MAXOBJSIZE].
+ Since there is no way to represent such a range across
+ additions, conservatively add [-MAXOBJSIZE -1, MAXOBJSIZE]
to OFFRANGE. */
offrange[0] += arrbounds[0];
offrange[1] += arrbounds[1];