re PR c/65120 (Wlogical-not-parentheses should not warn about double exclamation !!)
authorJakub Jelinek <jakub@redhat.com>
Tue, 10 Mar 2015 06:38:57 +0000 (07:38 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 10 Mar 2015 06:38:57 +0000 (07:38 +0100)
PR c/65120
* c-common.c (warn_logical_not_parentheses): Don't warn for
!x == 0 or !x != 0.

* c-typeck.c (parser_build_binary_op): Check for tcc_comparison
before preparing arguments to warn_logical_not_parentheses.

* parser.c (cp_parser_binary_expression): Check for tcc_comparison
before preparing arguments to warn_logical_not_parentheses.
Use maybe_constant_value on rhs.

* c-c++-common/pr49706.c (fn2): Don't expect warning if enumerator
on rhs is 0.
(fn4): New test.
* c-c++-common/pr65120.c: New test.

From-SVN: r221299

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr49706.c
gcc/testsuite/c-c++-common/pr65120.c [new file with mode: 0644]

index 6bd5a28fa8bdc383573012f1749a2058d3bbc2bd..3420c96aff12e566831a085118bb1152be70bb5b 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/65120
+       * c-common.c (warn_logical_not_parentheses): Don't warn for
+       !x == 0 or !x != 0.
+
 2015-03-07  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/65280
index 8c23e0919626561fb129b7d2f430fa7ce959a78f..7e84eb194b21607154c7c6deb69a69fd07a741b6 100644 (file)
@@ -1800,6 +1800,12 @@ warn_logical_not_parentheses (location_t location, enum tree_code code,
       || TREE_CODE (TREE_TYPE (rhs)) == BOOLEAN_TYPE)
     return;
 
+  /* Don't warn for !x == 0 or !y != 0, those are equivalent to
+     !(x == 0) or !(y != 0).  */
+  if ((code == EQ_EXPR || code == NE_EXPR)
+      && integer_zerop (rhs))
+    return;
+
   warning_at (location, OPT_Wlogical_not_parentheses,
              "logical not is only applied to the left hand side of "
              "comparison");
index 7b81080a34f0d68ae14da6a27dd70a88806d9cbf..c15b86f5540b2990416340aa03d2fdd0beb49d50 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/65120
+       * c-typeck.c (parser_build_binary_op): Check for tcc_comparison
+       before preparing arguments to warn_logical_not_parentheses.
+
 2015-03-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/65120
index 98bff32f17e3e8b229f3fc2b75a8ade79d098d45..ebe4c7358917c5843b77fca4d69576281e29c5be 100644 (file)
@@ -3459,6 +3459,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
                           code1, arg1.value, code2, arg2.value);
 
   if (warn_logical_not_paren
+      && TREE_CODE_CLASS (code) == tcc_comparison
       && code1 == TRUTH_NOT_EXPR
       && code2 != TRUTH_NOT_EXPR
       /* Avoid warning for !!x == y.  */
index 67aa184bcb1f9d641787c178bdb15d12dd7751af..d354e07d2792d802b579d9c80350484db2e6611d 100644 (file)
@@ -1,3 +1,10 @@
+2015-03-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/65120
+       * parser.c (cp_parser_binary_expression): Check for tcc_comparison
+       before preparing arguments to warn_logical_not_parentheses.
+       Use maybe_constant_value on rhs.
+
 2015-03-09  Jason Merrill  <jason@redhat.com>
 
        PR c++/65339
index 2a3578fee3c52d7552395c05dbd29ad9651db533..ad132b1850f2a10509661e3c61a5dbb6e9fb1265 100644 (file)
@@ -8270,6 +8270,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
        c_inhibit_evaluation_warnings -= current.lhs == truthvalue_true_node;
 
       if (warn_logical_not_paren
+         && TREE_CODE_CLASS (current.tree_type) == tcc_comparison
          && current.lhs_type == TRUTH_NOT_EXPR
          /* Avoid warning for !!x == y.  */
          && (TREE_CODE (current.lhs) != NE_EXPR
@@ -8284,7 +8285,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
          && (!DECL_P (current.lhs)
              || TREE_TYPE (current.lhs) == NULL_TREE
              || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
-       warn_logical_not_parentheses (current.loc, current.tree_type, rhs);
+       warn_logical_not_parentheses (current.loc, current.tree_type,
+                                     maybe_constant_value (rhs));
 
       overload = NULL;
       /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
index 6c9ae2ca96e41df8179f2e084eb6d8b0dc247a97..8c087eda1f62c77bee991788fc3ae6a18611ca66 100644 (file)
@@ -1,5 +1,11 @@
 2015-03-10  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c/65120
+       * c-c++-common/pr49706.c (fn2): Don't expect warning if enumerator
+       on rhs is 0.
+       (fn4): New test.
+       * c-c++-common/pr65120.c: New test.
+
        PR rtl-optimization/65321
        * gcc.dg/pr65321.c: New test.
 
index f41fa8bb5ff9e3a0b91670b32914a1237174819e..56272add7da3472ba044941a6badbca423ee3904 100644 (file)
@@ -107,9 +107,9 @@ fn2 (enum E e)
   b = foo_e () == A;
   b = foo_e () == foo_e ();
 
-  b = !e == A; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  b = !e == A;
   b = !e == foo_e (); /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
-  b = !foo_e () == A; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  b = !foo_e () == A;
   b = !foo_e () == foo_e (); /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
 
   b = !(e == A);
@@ -163,3 +163,27 @@ fn3 (int i1, float f2)
   b = !!i1 <= f2; /* { dg-bogus "logical not is only applied to the left hand side of comparison" } */
   b = !!i1 >= f2; /* { dg-bogus "logical not is only applied to the left hand side of comparison" } */
 }
+
+void
+fn4 (enum E e)
+{
+  b = e == A;
+  b = e == foo_e ();
+  b = foo_e () == B;
+  b = foo_e () == foo_e ();
+
+  b = !e == B; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  b = !e == foo_e (); /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  b = !foo_e () == B; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  b = !foo_e () == foo_e (); /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+
+  b = !(e == B);
+  b = !(e == foo_e ());
+  b = !(foo_e () == B);
+  b = !(foo_e () == foo_e ());
+
+  b = (!e) == B;
+  b = (!e) == foo_e ();
+  b = (!foo_e ()) == B;
+  b = (!foo_e ()) == foo_e ();
+}
diff --git a/gcc/testsuite/c-c++-common/pr65120.c b/gcc/testsuite/c-c++-common/pr65120.c
new file mode 100644 (file)
index 0000000..c9c1f5f
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-not-parentheses" } */
+
+/* Test that we don't warn if rhs is 0 and comparison is == or !=.  */
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
+bool r;
+
+int
+f1 (int a)
+{
+  r = !a == 0;
+  r = !a != 0;
+  r = !a == 1; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a != 1; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+}
+
+int
+f2 (int a)
+{
+  r = !a > 0;  /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a >= 0; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a < 0;  /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a <= 0; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a > 1;  /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a >= 1; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a < 1;  /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+  r = !a <= 1; /* { dg-warning "logical not is only applied to the left hand side of comparison" } */
+}