c-common.c (warn_logical_not_parentheses): Print fixit hints.
authorMarek Polacek <polacek@redhat.com>
Thu, 25 Aug 2016 12:48:34 +0000 (12:48 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 25 Aug 2016 12:48:34 +0000 (12:48 +0000)
* c-common.c (warn_logical_not_parentheses): Print fixit hints.
* c-common.h (warn_logical_not_parentheses): Update declaration.

* c-typeck.c (parser_build_binary_op): Pass LHS to
warn_logical_not_parentheses.

* parser.c (cp_parser_binary_expression): Pass LHS to
warn_logical_not_parentheses.

* c-c++-common/Wlogical-not-parentheses-2.c: New test.

Co-Authored-By: David Malcolm <dmalcolm@redhat.com>
From-SVN: r239756

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wlogical-not-parentheses-2.c [new file with mode: 0644]

index fe98090ba02507e7d5101016d2bc2ea4997adeb2..f8a7425548c29ea5780e4f151fe4e6399d188af9 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-25  Marek Polacek  <polacek@redhat.com>
+           David Malcolm  <dmalcolm@redhat.com>
+
+       * c-common.c (warn_logical_not_parentheses): Print fixit hints.
+       * c-common.h (warn_logical_not_parentheses): Update declaration.
+
 2016-08-22  Marek Polacek  <polacek@redhat.com>
 
        PR c++/77321
index 3feb910f09fa966981a772861b8bc7e98bc836ea..001070d58bc971c5aa675f72e563880f8389f685 100644 (file)
@@ -1485,7 +1485,7 @@ warn_tautological_cmp (location_t loc, enum tree_code code, tree lhs, tree rhs)
 
 void
 warn_logical_not_parentheses (location_t location, enum tree_code code,
-                             tree rhs)
+                             tree lhs, tree rhs)
 {
   if (TREE_CODE_CLASS (code) != tcc_comparison
       || TREE_TYPE (rhs) == NULL_TREE
@@ -1498,9 +1498,21 @@ warn_logical_not_parentheses (location_t location, enum tree_code code,
       && integer_zerop (rhs))
     return;
 
-  warning_at (location, OPT_Wlogical_not_parentheses,
-             "logical not is only applied to the left hand side of "
-             "comparison");
+  if (warning_at (location, OPT_Wlogical_not_parentheses,
+                 "logical not is only applied to the left hand side of "
+                 "comparison")
+      && EXPR_HAS_LOCATION (lhs))
+    {
+      location_t lhs_loc = EXPR_LOCATION (lhs);
+      rich_location richloc (line_table, lhs_loc);
+      richloc.add_fixit_insert (lhs_loc, "(");
+      location_t finish = get_finish (lhs_loc);
+      location_t next_loc
+       = linemap_position_for_loc_and_offset (line_table, finish, 1);
+      richloc.add_fixit_insert (next_loc, ")");
+      inform_at_rich_loc (&richloc, "add parentheses around left hand side "
+                         "expression to silence this warning");
+    }
 }
 
 /* Warn if EXP contains any computations whose results are not used.
index bc22baa26b8bb26559d7d9131c3d66c281a9432f..42ce9698bdbdf2aabbbf95f0c2c5a18f0e66f51c 100644 (file)
@@ -847,7 +847,8 @@ extern void overflow_warning (location_t, tree);
 extern bool warn_if_unused_value (const_tree, location_t);
 extern void warn_logical_operator (location_t, enum tree_code, tree,
                                   enum tree_code, tree, enum tree_code, tree);
-extern void warn_logical_not_parentheses (location_t, enum tree_code, tree);
+extern void warn_logical_not_parentheses (location_t, enum tree_code, tree,
+                                         tree);
 extern void warn_tautological_cmp (location_t, enum tree_code, tree, tree);
 extern void check_main_parameter_types (tree decl);
 extern bool c_determine_visibility (tree);
index dc863bb4a1b38a6e6280ecc576e7848de2f44c3f..774e5804ca2962798082a91d8fe77def5ae00958 100644 (file)
@@ -1,3 +1,8 @@
+2016-08-25  Marek Polacek  <polacek@redhat.com>
+
+       * c-typeck.c (parser_build_binary_op): Pass LHS to
+       warn_logical_not_parentheses.
+
 2016-08-25  Marek Polacek  <polacek@redhat.com>
 
        PR c/77323
index bc8728a49b661b9f62e0f7f9340b83134d6a0ddb..2f8d611c8ed08e9e69474ff3dad9e02cd6be1e2f 100644 (file)
@@ -3696,7 +3696,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
          while (1);
        }
       if (TREE_CODE (TREE_TYPE (t)) != BOOLEAN_TYPE)
-       warn_logical_not_parentheses (location, code, arg2.value);
+       warn_logical_not_parentheses (location, code, arg1.value, arg2.value);
     }
 
   /* Warn about comparisons against string literals, with the exception
index 705a0346452b89c1c4a8a741b1637d0ea79e89a0..491771969854ff62c556dfa6dfd1557ed210e8d7 100644 (file)
@@ -1,3 +1,8 @@
+2016-08-25  Marek Polacek  <polacek@redhat.com>
+
+       * parser.c (cp_parser_binary_expression): Pass LHS to
+       warn_logical_not_parentheses.
+
 2016-08-18  Marek Polacek  <polacek@redhat.com>
 
        PR c/7652
index 690e92846a83bdfa638452c3863b0a054bb54951..d54cf8ad47330b267f8e8079dd4c5424c3ff6a1a 100644 (file)
@@ -8922,7 +8922,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
              || TREE_TYPE (current.lhs) == NULL_TREE
              || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
        warn_logical_not_parentheses (current.loc, current.tree_type,
-                                     maybe_constant_value (rhs));
+                                     current.lhs, maybe_constant_value (rhs));
 
       overload = NULL;
 
index f4dddd8bea3c3c893751696d8c2343a16d20eb00..caeaa7e5fe1a34d2483f2940295181026d90dbff 100644 (file)
@@ -1,3 +1,7 @@
+2016-08-25  Marek Polacek  <polacek@redhat.com>
+
+       * c-c++-common/Wlogical-not-parentheses-2.c: New test.
+
 2016-08-25  Marek Polacek  <polacek@redhat.com>
 
        PR c/77323
diff --git a/gcc/testsuite/c-c++-common/Wlogical-not-parentheses-2.c b/gcc/testsuite/c-c++-common/Wlogical-not-parentheses-2.c
new file mode 100644 (file)
index 0000000..ba8dce8
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-not-parentheses -fdiagnostics-show-caret" } */
+
+ /* Test fixit hints.  */
+
+int
+foo (int aaa, int bbb)
+{
+  int r = 0;
+  r += (!aaa) == bbb;
+  r += !aaa == bbb; /* { dg-warning "logical not is only applied" } */
+/* { dg-begin-multiline-output "" }
+   r += !aaa == bbb;
+             ^~
+   r += !aaa == bbb;
+        ^~~~
+        (   )
+   { dg-end-multiline-output "" } */
+  return r;
+}