aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-05-01 21:30:26 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-05-01 21:30:26 +0000
commitbab4d587a04002521bf2d39932fa3e30bd6a7a94 (patch)
tree97f124b29810b764f35f68f70433b948f8558b80 /gcc/tree-vrp.c
parent8d825422c0a49237db41221f5731351a416ada89 (diff)
downloadgcc-bab4d587a04002521bf2d39932fa3e30bd6a7a94.zip
gcc-bab4d587a04002521bf2d39932fa3e30bd6a7a94.tar.gz
gcc-bab4d587a04002521bf2d39932fa3e30bd6a7a94.tar.bz2
re PR tree-optimization/43949 (bogus warning: array subscript is above array bounds)
2010-05-01 Richard Guenther <rguenther@suse.de> PR tree-optimization/43949 * tree-vrp.c (ssa_name_nonnegative_p): Return true for unsigned types. (extract_range_from_binary_expr): Handle *_MOD_EXPR. * g++.dg/warn/Warray-bounds-5.C: New testcase. From-SVN: r158965
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index d8ebbe8..83ff665 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1364,6 +1364,10 @@ ssa_name_nonnegative_p (const_tree t)
{
value_range_t *vr = get_value_range (t);
+ if (INTEGRAL_TYPE_P (t)
+ && TYPE_UNSIGNED (t))
+ return true;
+
if (!vr)
return false;
@@ -2079,6 +2083,10 @@ extract_range_from_binary_expr (value_range_t *vr,
&& code != CEIL_DIV_EXPR
&& code != EXACT_DIV_EXPR
&& code != ROUND_DIV_EXPR
+ && code != TRUNC_MOD_EXPR
+ && code != FLOOR_MOD_EXPR
+ && code != CEIL_MOD_EXPR
+ && code != ROUND_MOD_EXPR
&& code != RSHIFT_EXPR
&& code != MIN_EXPR
&& code != MAX_EXPR
@@ -2147,6 +2155,10 @@ extract_range_from_binary_expr (value_range_t *vr,
&& code != CEIL_DIV_EXPR
&& code != EXACT_DIV_EXPR
&& code != ROUND_DIV_EXPR
+ && code != TRUNC_MOD_EXPR
+ && code != FLOOR_MOD_EXPR
+ && code != CEIL_MOD_EXPR
+ && code != ROUND_MOD_EXPR
&& (vr0.type == VR_VARYING
|| vr1.type == VR_VARYING
|| vr0.type != vr1.type
@@ -2497,6 +2509,28 @@ extract_range_from_binary_expr (value_range_t *vr,
}
}
}
+ else if (code == TRUNC_MOD_EXPR
+ || code == FLOOR_MOD_EXPR
+ || code == CEIL_MOD_EXPR
+ || code == ROUND_MOD_EXPR)
+ {
+ bool sop = false;
+ if (vr0.type == VR_ANTI_RANGE
+ || vr1.type != VR_RANGE
+ || symbolic_range_p (&vr1)
+ || range_includes_zero_p (&vr1))
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+ type = VR_RANGE;
+ max = int_const_binop (MINUS_EXPR, vr1.max, integer_one_node, 0);
+ if (vrp_expr_computes_nonnegative (op0, &sop)
+ && vrp_expr_computes_nonnegative (op1, &sop) && !sop)
+ min = build_int_cst (TREE_TYPE (vr1.max), 0);
+ else
+ min = fold_unary (NEGATE_EXPR, TREE_TYPE (max), max);
+ }
else if (code == MINUS_EXPR)
{
/* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to