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] Make -Wint-in-bool-context warn on suspicious shift ops


Hi!

This patch makes -Wint-in-bool-context warn on suspicious integer left
shifts, when the integer is signed, which is most likely some kind of 
programming error, for instance using "<<" instead of "<".

The warning is motivated by the fact, that an overflow on integer shift
left is undefined behavior, even if gcc won't optimize the shift based
on the undefined behavior.

So in absence of undefined behavior the boolean result does not depend
on the shift value, thus the whole shifting is pointless.


Of course the warning happened to find one bug already.  That is in
cp/parser.c at cp_parser_condition, where we have this:


bool flags = LOOKUP_ONLYCONVERTING;

BUT (cp-tree.h):

#define LOOKUP_ONLYCONVERTING (1 << 2)


So "flags" is actually set to true, which is LOOKUP_PROTECT instead.

Although I tried hard to find a test case where this changes something,
I was not able to construct one.


Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.

Attachment: changelog-bool-context.txt
Description: changelog-bool-context.txt

Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 240437)
+++ gcc/c-family/c-common.c	(working copy)
@@ -4651,6 +4651,19 @@ c_common_truthvalue_conversion (location_t locatio
 	return c_common_truthvalue_conversion (location,
 					       TREE_OPERAND (expr, 0));
 
+    case LSHIFT_EXPR:
+      /* Warn on signed integer left shift, except 0 << 0, 1 << 0.  */
+      if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
+	  && !TYPE_UNSIGNED (TREE_TYPE (expr))
+	  && !(TREE_CODE (TREE_OPERAND (expr, 0)) == INTEGER_CST
+	       && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
+	       && (integer_zerop (TREE_OPERAND (expr, 0))
+		   || integer_onep (TREE_OPERAND (expr, 0)))
+	       && integer_zerop (TREE_OPERAND (expr, 1))))
+	warning_at (EXPR_LOCATION (expr), OPT_Wint_in_bool_context,
+		    "<< on signed integer in boolean context");
+      break;
+
     case COND_EXPR:
       if (warn_int_in_bool_context
 	  && !from_macro_definition_at (EXPR_LOCATION (expr)))
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 240437)
+++ gcc/cp/parser.c	(working copy)
@@ -11172,7 +11172,7 @@ cp_parser_condition (cp_parser* parser)
 	{
 	  tree pushed_scope;
 	  bool non_constant_p;
-	  bool flags = LOOKUP_ONLYCONVERTING;
+	  int flags = LOOKUP_ONLYCONVERTING;
 
 	  /* Create the declaration.  */
 	  decl = start_decl (declarator, &type_specifiers,
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 240437)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5927,7 +5927,8 @@ of the C++ standard.
 @opindex Wno-int-in-bool-context
 Warn for suspicious use of integer values where boolean values are expected,
 such as conditional expressions (?:) using non-boolean integer constants in
-boolean context, like @code{if (a <= b ? 2 : 3)}.
+boolean context, like @code{if (a <= b ? 2 : 3)}.  Or left shifting of a
+signed integer in boolean context, like @code{for (a = 0; 1 << a; a++);}.
 This warning is enabled by @option{-Wall}.
 
 @item -Wno-int-to-pointer-cast
Index: gcc/testsuite/c-c++-common/Wint-in-bool-context.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-in-bool-context.c	(revision 240437)
+++ gcc/testsuite/c-c++-common/Wint-in-bool-context.c	(working copy)
@@ -25,5 +25,7 @@ int foo (int a, int b)
   if (b ? 1+1 : 1) /* { dg-warning "boolean context" } */
     return 7;
 
+  for (a = 0; 1 << a; a++); /* { dg-warning "boolean context" } */
+
   return 0;
 }

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