This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]