aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-08-19 18:50:00 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2014-08-19 18:50:00 +0000
commit04159acfd818cbc29a9d12dfa2e83716c106f2c7 (patch)
treec01c9d77dc28f6a4d017760a2f0f57809574d010 /gcc/c-family
parent8a2e8325e4b35265ea983561eca4a23a13630b07 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c33
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c.opt4
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