c-common.c (c_common_truthvalue_conversion): Warn only for signed integer shift ops...
authorBernd Edlinger <edlinger@gcc.gnu.org>
Wed, 19 Oct 2016 21:00:39 +0000 (21:00 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Wed, 19 Oct 2016 21:00:39 +0000 (21:00 +0000)
2016-10-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * c-common.c (c_common_truthvalue_conversion): Warn only for signed
        integer shift ops in boolean context.

testsuite:
2016-10-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * c-c++-common/Wint-in-bool-context-2.c: New test.

From-SVN: r241354

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wint-in-bool-context-2.c [new file with mode: 0644]

index f305593006527c840fe63b6a8ce09b7dbb5cb342..0ef8ef7aad9ea69bd86a8a77fa5dca8e221cab4f 100644 (file)
@@ -1,4 +1,9 @@
-2016-06-16  Aldy Hernandez  <aldyh@redhat.com>
+2016-10-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       * c-common.c (c_common_truthvalue_conversion): Warn only for signed
+       integer shift ops in boolean context.
+
+2016-10-18  Aldy Hernandez  <aldyh@redhat.com>
 
        * c.opt (Walloca): New.
        (Walloca-larger-than=): New.
index 326ff6f49e2083bc9c3afe7edf75c0d8c51af18a..8af3ad53a3dde1d0e3e4cc798e39001f3c4ff7ba 100644 (file)
@@ -3328,8 +3328,15 @@ c_common_truthvalue_conversion (location_t location, tree expr)
                                               TREE_OPERAND (expr, 0));
 
     case LSHIFT_EXPR:
-      warning_at (EXPR_LOCATION (expr), OPT_Wint_in_bool_context,
-                 "<< in boolean context, did you mean '<' ?");
+      /* We will only warn on unsigned shifts here, because the majority of
+        false positive warnings happen in code where unsigned arithmetic
+        was used in anticipation of a possible overflow.
+        Furthermore, if we see an unsigned type here we know that the
+        result of the shift is not subject to integer promotion rules.  */
+      if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
+         && !TYPE_UNSIGNED (TREE_TYPE (expr)))
+       warning_at (EXPR_LOCATION (expr), OPT_Wint_in_bool_context,
+                   "<< in boolean context, did you mean '<' ?");
       break;
 
     case COND_EXPR:
index 1e83325376184c4d0ed8a77f2b39267dc6af588b..8f5230f515ab7b5ba7e2088f51184247ae7d6e69 100644 (file)
@@ -1,3 +1,7 @@
+2016-10-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       * c-c++-common/Wint-in-bool-context-2.c: New test.
+
 2016-10-19  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        * gfortran.dg/dtio_17.f90: Fix test.
diff --git a/gcc/testsuite/c-c++-common/Wint-in-bool-context-2.c b/gcc/testsuite/c-c++-common/Wint-in-bool-context-2.c
new file mode 100644 (file)
index 0000000..04c064d
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-options "-Wint-in-bool-context" } */
+/* { dg-do compile } */
+
+typedef unsigned u32;
+typedef unsigned char u8;
+#define KEYLENGTH 8
+
+int foo (u8 plen, u32 key)
+{
+  if ((plen < KEYLENGTH) && (key << plen)) /* { dg-bogus "boolean context" } */
+    return -1;
+
+  if ((plen << KEYLENGTH) && (key < plen)) /* { dg-warning "boolean context" } */
+    return -2;
+
+  return 0;
+}