aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2009-04-19 11:04:13 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2009-04-19 11:04:13 +0000
commitca409efd9282623758e9b8f36df75cdd7278a3e1 (patch)
treebcaf465ab5ba49fd67b08ce44d9d4349c54cc20e /gcc/c-common.c
parentc93c8cf442616849535c5ec3a50d517ad76fe5d3 (diff)
downloadgcc-ca409efd9282623758e9b8f36df75cdd7278a3e1.zip
gcc-ca409efd9282623758e9b8f36df75cdd7278a3e1.tar.gz
gcc-ca409efd9282623758e9b8f36df75cdd7278a3e1.tar.bz2
re PR c/32061 ((Wlogical-op) wording of warning of constant logicials need improvement)
2009-04-19 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c/32061 PR c++/36954 * doc/invoke.texi: Add -Wlogical-op to -Wextra. * common.opt (Wlogical-op): Move from here... * c.opt (Wlogical-op): ... to here. * c-typeck.c (parser_build_binary_op): Update call to warn_logical_operator. * c-opts.c (c_common_post_options): Enable warn_logical_op with extra_warnings. * c-common.c (warn_logical_op): Update. * c-common.h (warn_logical_op): Update declaration. cp/ * call.c (build_new_op): Save the original codes of operands before folding. testsuite/ * gcc.dg/pr32061.c: New. * gcc.dg/Wlogical-op-1.c: Update. * g++.dg/warn/Wlogical-op-1.C: Update. * g++.dg/warn/pr36954.C: New. From-SVN: r146344
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c65
1 files changed, 35 insertions, 30 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 77f7ebc..735c8e0 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1712,38 +1712,43 @@ overflow_warning (tree value)
}
}
-
-/* Warn about use of a logical || / && operator being used in a
- context where it is likely that the bitwise equivalent was intended
- by the programmer. CODE is the TREE_CODE of the operator, ARG1
- and ARG2 the arguments. */
+/* Warn about uses of logical || / && operator in a context where it
+ is likely that the bitwise equivalent was intended by the
+ programmer. We have seen an expression in which CODE is a binary
+ operator used to combine expressions OP_LEFT and OP_RIGHT, which
+ before folding had CODE_LEFT and CODE_RIGHT. */
void
-warn_logical_operator (enum tree_code code, tree arg1, tree
- arg2)
-{
- switch (code)
- {
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_AND_EXPR:
- if (!TREE_NO_WARNING (arg1)
- && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
- && !CONSTANT_CLASS_P (arg1)
- && TREE_CODE (arg2) == INTEGER_CST
- && !integer_zerop (arg2))
- {
- warning (OPT_Wlogical_op,
- "logical %<%s%> with non-zero constant "
- "will always evaluate as true",
- ((code == TRUTH_ANDIF_EXPR)
- || (code == TRUTH_AND_EXPR)) ? "&&" : "||");
- TREE_NO_WARNING (arg1) = true;
- }
- break;
- default:
- break;
+warn_logical_operator (location_t location, enum tree_code code,
+ enum tree_code code_left, tree op_left,
+ enum tree_code ARG_UNUSED (code_right), tree op_right)
+{
+ if (code != TRUTH_ANDIF_EXPR
+ && code != TRUTH_AND_EXPR
+ && code != TRUTH_ORIF_EXPR
+ && code != TRUTH_OR_EXPR)
+ return;
+
+ /* Warn if &&/|| are being used in a context where it is
+ likely that the bitwise equivalent was intended by the
+ programmer. That is, an expression such as op && MASK
+ where op should not be any boolean expression, nor a
+ constant, and mask seems to be a non-boolean integer constant. */
+ if (!truth_value_p (code_left)
+ && INTEGRAL_TYPE_P (TREE_TYPE (op_left))
+ && !CONSTANT_CLASS_P (op_left)
+ && !TREE_NO_WARNING (op_left)
+ && TREE_CODE (op_right) == INTEGER_CST
+ && !integer_zerop (op_right)
+ && !integer_onep (op_right))
+ {
+ if (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR)
+ warning_at (location, OPT_Wlogical_op, "logical %<or%>"
+ " applied to non-boolean constant");
+ else
+ warning_at (location, OPT_Wlogical_op, "logical %<and%>"
+ " applied to non-boolean constant");
+ TREE_NO_WARNING (op_left) = true;
}
}