aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-05-04 09:53:28 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-05-04 09:53:28 +0000
commit622d360ecdb6c4dcbe01414f534fa89c61cac451 (patch)
treeae0c7d98a7e2d25014cb2b82e8242f20d67a00dd
parentf857e9a46ef3bfbf8e1a42aec86d7033ad343d87 (diff)
downloadgcc-622d360ecdb6c4dcbe01414f534fa89c61cac451.zip
gcc-622d360ecdb6c4dcbe01414f534fa89c61cac451.tar.gz
gcc-622d360ecdb6c4dcbe01414f534fa89c61cac451.tar.bz2
re PR tree-optimization/43949 (bogus warning: array subscript is above array bounds)
2010-05-04 Richard Guenther <rguenther@suse.de> PR tree-optimization/43949 * tree-vrp.c (extract_range_from_binary_expr): Only handle TRUNC_MOD_EXPR. From-SVN: r159020
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-vrp.c33
2 files changed, 21 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 30f3ea1..4195d9d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/43949
+ * tree-vrp.c (extract_range_from_binary_expr): Only handle
+ TRUNC_MOD_EXPR.
+
2010-04-26 Jason Merrill <jason@redhat.com>
* c.opt (-fstrict-enums): New.
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 83ff665..8cac4df 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -2084,9 +2084,6 @@ extract_range_from_binary_expr (value_range_t *vr,
&& 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
@@ -2156,9 +2153,6 @@ extract_range_from_binary_expr (value_range_t *vr,
&& 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
@@ -2509,27 +2503,30 @@ 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)
+ else if (code == TRUNC_MOD_EXPR)
{
bool sop = false;
- if (vr0.type == VR_ANTI_RANGE
- || vr1.type != VR_RANGE
+ if (vr1.type != VR_RANGE
|| symbolic_range_p (&vr1)
- || range_includes_zero_p (&vr1))
+ || range_includes_zero_p (&vr1)
+ || vrp_val_is_min (vr1.min))
{
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);
+ /* Compute MAX <|vr1.min|, |vr1.max|> - 1. */
+ max = fold_unary_to_constant (ABS_EXPR, TREE_TYPE (vr1.min), vr1.min);
+ if (tree_int_cst_lt (max, vr1.max))
+ max = vr1.max;
+ max = int_const_binop (MINUS_EXPR, max, integer_one_node, 0);
+ /* If the dividend is non-negative the modulus will be
+ non-negative as well. */
+ if (TYPE_UNSIGNED (TREE_TYPE (max))
+ || (vrp_expr_computes_nonnegative (op0, &sop) && !sop))
+ min = build_int_cst (TREE_TYPE (max), 0);
else
- min = fold_unary (NEGATE_EXPR, TREE_TYPE (max), max);
+ min = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (max), max);
}
else if (code == MINUS_EXPR)
{