This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] warn for always-false bitwise and
- From: John Levon <levon at movementarian dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Mar 2003 04:07:23 +0000
- Subject: [PATCH][RFC] warn for always-false bitwise and
This catches precedence cockups like "if (!something & 0x8)". I
made it part of -Wall since any such case could trivially be replaced
with literal 0. There's also the possibility of a wider tests for
bit-ops on boolean values, but that will have lots of false positives.
Can someone explain why it doesn't work for C++ bool types please,
and I'll try to fix it ? I would have thought the BOOLEAN_TYPE test
would have caught it.
If this is the right way to go about it, I'll do all the rest (testsuite
etc.) and port it to CVS (this is a diff against 3.3 branch since CVS
head is unusable for testing).
regards
john
Index: c-common.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.393.2.1
diff -u -r1.393.2.1 c-common.c
--- c-common.c 19 Feb 2003 02:07:56 -0000 1.393.2.1
+++ c-common.c 4 Mar 2003 02:33:30 -0000
@@ -369,6 +369,10 @@
int warn_bad_function_cast;
+/* Warn about always-false bitwise and with != 1 on a boolean value */
+
+int warn_boolean_bitwise_and;
+
/* Warn about traditional constructs whose meanings changed in ANSI C. */
int warn_traditional;
Index: c-common.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.164
diff -u -r1.164 c-common.h
--- c-common.h 1 Dec 2002 17:51:44 -0000 1.164
+++ c-common.h 4 Mar 2003 02:33:33 -0000
@@ -538,6 +538,10 @@
extern int warn_bad_function_cast;
+/* Warn about always-false bitwise and with != 1 on a boolean value */
+
+extern int warn_boolean_bitwise_and;
+
/* Warn about traditional constructs whose meanings changed in ANSI C. */
extern int warn_traditional;
Index: c-opts.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.24.6.1
diff -u -r1.24.6.1 c-opts.c
--- c-opts.c 21 Feb 2003 06:12:58 -0000 1.24.6.1
+++ c-opts.c 4 Mar 2003 02:33:35 -0000
@@ -127,6 +127,7 @@
OPT("Wabi", CL_CXX, OPT_Wabi) \
OPT("Wall", CL_ALL, OPT_Wall) \
OPT("Wbad-function-cast", CL_C, OPT_Wbad_function_cast) \
+ OPT("Wboolean-bitwise-and", CL_ALL, OPT_Wboolean_bitwise_and) \
OPT("Wcast-qual", CL_ALL, OPT_Wcast_qual) \
OPT("Wchar-subscripts", CL_ALL, OPT_Wchar_subscripts) \
OPT("Wcomment", CL_ALL, OPT_Wcomment) \
@@ -702,6 +703,7 @@
warn_sign_compare = on; /* Was C++ only. */
warn_switch = on;
warn_strict_aliasing = on;
+ warn_boolean_bitwise_and = on;
/* Only warn about unknown pragmas that are not in system
headers. */
@@ -734,6 +736,10 @@
case OPT_Wbad_function_cast:
warn_bad_function_cast = on;
+ break;
+
+ case OPT_Wboolean_bitwise_and:
+ warn_boolean_bitwise_and = on;
break;
case OPT_Wcast_qual:
Index: c-typeck.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.213.2.2
diff -u -r1.213.2.2 c-typeck.c
--- c-typeck.c 9 Jan 2003 12:11:34 -0000 1.213.2.2
+++ c-typeck.c 4 Mar 2003 02:33:42 -0000
@@ -2007,6 +2007,19 @@
break;
case BIT_AND_EXPR:
+ /* give a warning for (!blah & 0x4) and similar cases */
+ if (warn_boolean_bitwise_and)
+ {
+ int op0not1 = TREE_CODE(op0) == INTEGER_CST && !integer_onep(op0);
+ int op1not1 = TREE_CODE(op1) == INTEGER_CST && !integer_onep(op1);
+ int op0bool = truth_value_p(TREE_CODE(op0)) || code0 == BOOLEAN_TYPE;
+ int op1bool = truth_value_p(TREE_CODE(op1)) || code1 == BOOLEAN_TYPE;
+ if ((op0not1 && op1bool) || (op1not1 && op0bool))
+ warning("bitwise and expression is always false");
+ }
+
+ /* fallthrough */
+
case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
Index: fold-const.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.227.2.1
diff -u -r1.227.2.1 fold-const.c
--- fold-const.c 16 Feb 2003 08:25:20 -0000 1.227.2.1
+++ fold-const.c 4 Mar 2003 02:33:51 -0000
@@ -74,7 +74,6 @@
static enum tree_code swap_tree_comparison PARAMS ((enum tree_code));
static int comparison_to_compcode PARAMS ((enum tree_code));
static enum tree_code compcode_to_comparison PARAMS ((int));
-static int truth_value_p PARAMS ((enum tree_code));
static int operand_equal_for_comparison_p PARAMS ((tree, tree, tree));
static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *));
static tree eval_subst PARAMS ((tree, tree, tree, tree, tree));
@@ -1771,7 +1770,7 @@
/* Return nonzero if CODE is a tree code that represents a truth value. */
-static int
+int
truth_value_p (code)
enum tree_code code;
{
Index: toplev.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.690.2.8
diff -u -r1.690.2.8 toplev.c
--- toplev.c 3 Mar 2003 18:26:12 -0000 1.690.2.8
+++ toplev.c 4 Mar 2003 02:33:56 -0000
@@ -1255,6 +1255,9 @@
{ "-Wbad-function-cast",
N_("Warn about casting functions to incompatible types") },
{ "-Wno-bad-function-cast", "" },
+ { "-Wboolean-bitwise-and",
+ N_("Warn about bitwise and expressions on boolean values that are always false") },
+ { "-Wno-boolean-bitwise-and", "" },
{ "-Wmissing-format-attribute",
N_("Warn about functions which might be candidates for format attributes") },
{ "-Wno-missing-format-attribute", "" },
Index: tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/tree.h,v
retrieving revision 1.367.2.1
diff -u -r1.367.2.1 tree.h
--- tree.h 9 Jan 2003 12:11:38 -0000 1.367.2.1
+++ tree.h 4 Mar 2003 02:34:01 -0000
@@ -2915,6 +2915,8 @@
extern tree build_range_type PARAMS ((tree, tree, tree));
+extern int truth_value_p PARAMS ((enum tree_code));
+
/* In alias.c */
extern void record_component_aliases PARAMS ((tree));
extern HOST_WIDE_INT get_alias_set PARAMS ((tree));
Index: cp/typeck.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.436.2.2
diff -u -r1.436.2.2 typeck.c
--- cp/typeck.c 22 Jan 2003 19:17:15 -0000 1.436.2.2
+++ cp/typeck.c 4 Mar 2003 02:34:13 -0000
@@ -3155,6 +3155,19 @@
break;
case BIT_AND_EXPR:
+ /* give a warning for (!blah & 0x4) and similar cases */
+ if (warn_boolean_bitwise_and)
+ {
+ int op0not1 = TREE_CODE(op0) == INTEGER_CST && !integer_onep(op0);
+ int op1not1 = TREE_CODE(op1) == INTEGER_CST && !integer_onep(op1);
+ int op0bool = truth_value_p(TREE_CODE(op0)) || code0 == BOOLEAN_TYPE;
+ int op1bool = truth_value_p(TREE_CODE(op1)) || code1 == BOOLEAN_TYPE;
+ if ((op0not1 && op1bool) || (op1not1 && op0bool))
+ warning("bitwise and expression is always false");
+ }
+
+ /* fallthrough */
+
case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR: