diff options
author | Diego Novillo <dnovillo@google.com> | 2008-02-24 11:40:32 -0500 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2008-02-24 11:40:32 -0500 |
commit | faebccf9b6ec3f4bfdcc268fc55cf58c397bed6c (patch) | |
tree | 771c35c481fdb2bb880ce72ab481848d5c8a4fa6 /gcc/tree-vrp.c | |
parent | 88c7f01b6c31f28392eacfda320c90835a50199a (diff) | |
download | gcc-faebccf9b6ec3f4bfdcc268fc55cf58c397bed6c.zip gcc-faebccf9b6ec3f4bfdcc268fc55cf58c397bed6c.tar.gz gcc-faebccf9b6ec3f4bfdcc268fc55cf58c397bed6c.tar.bz2 |
http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01094.html
PR 33738
* tree-vrp.c (vrp_evaluate_conditional): With
-Wtype-limits, emit a warning when comparing against a
constant outside the natural range of OP0's type.
* c.opt (Wtype-limits): Move ...
* common.opt (Wtype-limits): ... here.
testsuite/ChangeLog
PR 33738
* g++.dg/warn/pr33738.C: New.
From-SVN: r132591
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f9615d1..eaeaea0 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5077,6 +5077,48 @@ vrp_evaluate_conditional (tree cond, tree stmt) } } + if (warn_type_limits + && ret + && TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison) + { + /* If the comparison is being folded and the operand on the LHS + is being compared against a constant value that is outside of + the natural range of OP0's type, then the predicate will + always fold regardless of the value of OP0. If -Wtype-limits + was specified, emit a warning. */ + const char *warnmsg = NULL; + tree op0 = TREE_OPERAND (cond, 0); + tree op1 = TREE_OPERAND (cond, 1); + tree type = TREE_TYPE (op0); + value_range_t *vr0 = get_value_range (op0); + + if (vr0->type != VR_VARYING + && INTEGRAL_TYPE_P (type) + && vrp_val_is_min (vr0->min) + && vrp_val_is_max (vr0->max) + && is_gimple_min_invariant (op1)) + { + if (integer_zerop (ret)) + warnmsg = G_("comparison always false due to limited range of " + "data type"); + else + warnmsg = G_("comparison always true due to limited range of " + "data type"); + } + + if (warnmsg) + { + location_t locus; + + if (!EXPR_HAS_LOCATION (stmt)) + locus = input_location; + else + locus = EXPR_LOCATION (stmt); + + warning (OPT_Wtype_limits, "%H%s", &locus, warnmsg); + } + } + return ret; } |