diff options
author | Marek Polacek <polacek@redhat.com> | 2014-08-19 18:50:00 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-08-19 18:50:00 +0000 |
commit | 04159acfd818cbc29a9d12dfa2e83716c106f2c7 (patch) | |
tree | c01c9d77dc28f6a4d017760a2f0f57809574d010 /gcc/c-family | |
parent | 8a2e8325e4b35265ea983561eca4a23a13630b07 (diff) | |
download | gcc-04159acfd818cbc29a9d12dfa2e83716c106f2c7.zip gcc-04159acfd818cbc29a9d12dfa2e83716c106f2c7.tar.gz gcc-04159acfd818cbc29a9d12dfa2e83716c106f2c7.tar.bz2 |
re PR c++/62153 (warn for bool expression compared with integer different from 0/1)
PR c++/62153
* doc/invoke.texi: Document -Wbool-compare.
c-family/
* c-common.c (maybe_warn_bool_compare): New function.
* c-common.h (maybe_warn_bool_compare): Declare.
* c.opt (Wbool-compare): New option.
c/
* c-typeck.c (build_binary_op): If either operand of a comparison
is a boolean expression, call maybe_warn_bool_compare.
cp/
* call.c (build_new_op_1): Remember the type of arguments for
a comparison. If either operand of a comparison is a boolean
expression, call maybe_warn_bool_compare.
testsuite/
* c-c++-common/Wbool-compare-1.c: New test.
From-SVN: r214183
Diffstat (limited to 'gcc/c-family')
-rw-r--r-- | gcc/c-family/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 33 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c-family/c.opt | 4 |
4 files changed, 45 insertions, 0 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e25f1d8..e458f5e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,5 +1,12 @@ 2014-08-19 Marek Polacek <polacek@redhat.com> + PR c++/62153 + * c-common.c (maybe_warn_bool_compare): New function. + * c-common.h (maybe_warn_bool_compare): Declare. + * c.opt (Wbool-compare): New option. + +2014-08-19 Marek Polacek <polacek@redhat.com> + * c.opt (Wc99-c11-compat): New option. 2014-08-19 Marek Polacek <polacek@redhat.com> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index acc9a20..901a5ed 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -11612,6 +11612,39 @@ maybe_warn_unused_local_typedefs (void) vec_free (l->local_typedefs); } +/* Warn about boolean expression compared with an integer value different + from true/false. Warns also e.g. about "(i1 == i2) == 2". + LOC is the location of the comparison, CODE is its code, OP0 and OP1 + are the operands of the comparison. The caller must ensure that + either operand is a boolean expression. */ + +void +maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0, + tree op1) +{ + if (TREE_CODE_CLASS (code) != tcc_comparison) + return; + + tree cst = (TREE_CODE (op0) == INTEGER_CST) + ? op0 : (TREE_CODE (op1) == INTEGER_CST) ? op1 : NULL_TREE; + if (!cst) + return; + + if (!integer_zerop (cst) && !integer_onep (cst)) + { + int sign = (TREE_CODE (op0) == INTEGER_CST) + ? tree_int_cst_sgn (cst) : -tree_int_cst_sgn (cst); + if (code == EQ_EXPR + || ((code == GT_EXPR || code == GE_EXPR) && sign < 0) + || ((code == LT_EXPR || code == LE_EXPR) && sign > 0)) + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE " + "with boolean expression is always false", cst); + else + warning_at (loc, OPT_Wbool_compare, "comparison of constant %qE " + "with boolean expression is always true", cst); + } +} + /* The C and C++ parsers both use vectors to hold function arguments. For efficiency, we keep a cache of unused vectors. This is the cache. */ diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 26aaee2..995bc8c 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1015,6 +1015,7 @@ extern void record_types_used_by_current_var_decl (tree); extern void record_locally_defined_typedef (tree); extern void maybe_record_typedef_use (tree); extern void maybe_warn_unused_local_typedefs (void); +extern void maybe_warn_bool_compare (location_t, enum tree_code, tree, tree); extern vec<tree, va_gc> *make_tree_vector (void); extern void release_tree_vector (vec<tree, va_gc> *); extern vec<tree, va_gc> *make_tree_vector_single (tree); diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 4848399..f97a11a 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -287,6 +287,10 @@ Wbad-function-cast C ObjC Var(warn_bad_function_cast) Warning Warn about casting functions to incompatible types +Wbool-compare +C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) +Warn about boolean expression compared with an integer value different from true/false + Wbuiltin-macro-redefined C ObjC C++ ObjC++ Warning Warn when a built-in preprocessor macro is undefined or redefined |