diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2009-04-19 11:04:13 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2009-04-19 11:04:13 +0000 |
commit | ca409efd9282623758e9b8f36df75cdd7278a3e1 (patch) | |
tree | bcaf465ab5ba49fd67b08ce44d9d4349c54cc20e /gcc/c-common.c | |
parent | c93c8cf442616849535c5ec3a50d517ad76fe5d3 (diff) | |
download | gcc-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.c | 65 |
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; } } |