diff options
author | Richard Guenther <rguenther@suse.de> | 2010-05-04 09:53:28 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-05-04 09:53:28 +0000 |
commit | 622d360ecdb6c4dcbe01414f534fa89c61cac451 (patch) | |
tree | ae0c7d98a7e2d25014cb2b82e8242f20d67a00dd /gcc/tree-vrp.c | |
parent | f857e9a46ef3bfbf8e1a42aec86d7033ad343d87 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 33 |
1 files changed, 15 insertions, 18 deletions
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) { |