aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2012-05-05 11:30:57 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2012-05-05 11:30:57 +0000
commitf2c4a78515ebfcb43cd795e3d438f5bdf72d3f07 (patch)
tree20d0c64546a01ae4f6d3632809e6072d97f540a1 /gcc/c-family
parent8f75db9fd35e5bd43305c37896d143b7947455a5 (diff)
downloadgcc-f2c4a78515ebfcb43cd795e3d438f5bdf72d3f07.zip
gcc-f2c4a78515ebfcb43cd795e3d438f5bdf72d3f07.tar.gz
gcc-f2c4a78515ebfcb43cd795e3d438f5bdf72d3f07.tar.bz2
re PR c/43772 (Errant -Wlogical-op warning when testing limits)
2012-05-05 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c/43772 c-family/ * c-common.c (warn_logical_operator): Do not warn if either side is already true or false. testsuite/ * c-c++-common/pr43772.c: New. From-SVN: r187194
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c47
2 files changed, 39 insertions, 14 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1c805e8..accb985 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2012-05-05 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/43772
+ * c-common.c (warn_logical_operator): Do not warn if either side
+ is already true or false.
+
2012-05-04 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/51712
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index f3a6746..04a265f 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1612,31 +1612,50 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
|| INTEGRAL_TYPE_P (TREE_TYPE (op_right))))
return;
- lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
- rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
- if (lhs && TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
+ /* We first test whether either side separately is trivially true
+ (with OR) or trivially false (with AND). If so, do not warn.
+ This is a common idiom for testing ranges of data types in
+ portable code. */
+ lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
+ if (!lhs)
+ return;
+ if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
- if (rhs && TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
+ /* If this is an OR operation, invert both sides; now, the result
+ should be always false to get a warning. */
+ if (or_op)
+ in0_p = !in0_p;
+
+ tem = build_range_check (UNKNOWN_LOCATION, type, lhs, in0_p, low0, high0);
+ if (integer_zerop (tem))
+ return;
+
+ rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
+ if (!rhs)
+ return;
+ if (TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
- /* If this is an OR operation, invert both sides; we will invert
- again at the end. */
+ /* If this is an OR operation, invert both sides; now, the result
+ should be always false to get a warning. */
if (or_op)
- in0_p = !in0_p, in1_p = !in1_p;
+ in1_p = !in1_p;
- /* If both expressions are the same, if we can merge the ranges, and we
- can build the range test, return it or it inverted. */
- if (lhs && rhs && operand_equal_p (lhs, rhs, 0)
+ tem = build_range_check (UNKNOWN_LOCATION, type, rhs, in1_p, low1, high1);
+ if (integer_zerop (tem))
+ return;
+
+ /* If both expressions have the same operand, if we can merge the
+ ranges, and if the range test is always false, then warn. */
+ if (operand_equal_p (lhs, rhs, 0)
&& merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
in1_p, low1, high1)
&& 0 != (tem = build_range_check (UNKNOWN_LOCATION,
- type, lhs, in_p, low, high)))
+ type, lhs, in_p, low, high))
+ && integer_zerop (tem))
{
- if (TREE_CODE (tem) != INTEGER_CST)
- return;
-
if (or_op)
warning_at (location, OPT_Wlogical_op,
"logical %<or%> "