re PR c/80525 (-Wlogical-op confused by undefined integer overflow)
authorMarek Polacek <polacek@redhat.com>
Tue, 9 May 2017 11:21:14 +0000 (11:21 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Tue, 9 May 2017 11:21:14 +0000 (11:21 +0000)
PR c/80525
* c-warn.c (unwrap_c_maybe_const): New.
(warn_logical_operator): Call it.

* c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore.
* c-c++-common/Wlogical-op-2.c: New test.

From-SVN: r247786

gcc/c-family/ChangeLog
gcc/c-family/c-warn.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wlogical-op-1.c
gcc/testsuite/c-c++-common/Wlogical-op-2.c [new file with mode: 0644]

index 6409442060b530bd86ba5efd90bdb2c216edeea3..e76a6289cc477998fa8dd9b124f2ff181493ffbd 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-09  Marek Polacek  <polacek@redhat.com>
+
+       PR c/80525
+       * c-warn.c (unwrap_c_maybe_const): New.
+       (warn_logical_operator): Call it.
+
 2017-05-09  Nathan Sidwell  <nathan@acm.org>
 
        * c-common.c (c_register_builtin_type): Use pushdecl lang_hook.
index 45dd583111ef68481b3782f5796276af206333c8..aa0cfa97b047c5600b7ab2be6f98ad107faacaa9 100644 (file)
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "asan.h"
 #include "gcc-rich-location.h"
+#include "gimplify.h"
 
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
@@ -112,6 +113,21 @@ overflow_warning (location_t loc, tree value)
     }
 }
 
+/* Helper function for walk_tree.  Unwrap C_MAYBE_CONST_EXPRs in an expression
+   pointed to by TP.  */
+
+static tree
+unwrap_c_maybe_const (tree *tp, int *walk_subtrees, void *)
+{
+  if (TREE_CODE (*tp) == C_MAYBE_CONST_EXPR)
+    {
+      *tp = C_MAYBE_CONST_EXPR_EXPR (*tp);
+      /* C_MAYBE_CONST_EXPRs don't nest.  */
+      *walk_subtrees = false;
+    }
+  return NULL_TREE;
+}
+
 /* Warn about uses of logical || / && operator in a context where it
    is likely that the bitwise equivalent was intended by the
    programmer.  We have seen an expression in which CODE is a binary
@@ -189,11 +205,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
      (with OR) or trivially false (with AND).  If so, do not warn.
      This is a common idiom for testing ranges of data types in
      portable code.  */
+  op_left = unshare_expr (op_left);
+  walk_tree_without_duplicates (&op_left, unwrap_c_maybe_const, NULL);
   lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
   if (!lhs)
     return;
-  if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
-    lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
 
   /* If this is an OR operation, invert both sides; now, the result
      should be always false to get a warning.  */
@@ -204,11 +220,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
   if (tem && integer_zerop (tem))
     return;
 
+  op_right = unshare_expr (op_right);
+  walk_tree_without_duplicates (&op_right, unwrap_c_maybe_const, NULL);
   rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
   if (!rhs)
     return;
-  if (TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
-    rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
 
   /* If this is an OR operation, invert both sides; now, the result
      should be always false to get a warning.  */
index af1e6deb648a349b867bf50d9e4efacff38ca73a..98552a87fcdab51da033fa09d57aae372929f789 100644 (file)
@@ -1,3 +1,9 @@
+2017-05-09  Marek Polacek  <polacek@redhat.com>
+
+       PR c/80525
+       * c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore.
+       * c-c++-common/Wlogical-op-2.c: New test.
+
 2017-05-09  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        * gcc.dg/tree-ssa/cunroll-13.c: Use __INT32_TYPE__ for
index e89a35a5e8f0709459b676be43e066ba9ce80aa1..c5f992a400706a105b9fabf681ab475672ce6f25 100644 (file)
@@ -1,8 +1,6 @@
 /* PR c/63357 */
 /* { dg-do compile } */
-/* For -fwrapv see PR80525, xfailing the subtest isn't possible as it passes
-   with the C++ FE which doesn't have maybe_const_expr.  */
-/* { dg-options "-fwrapv -Wlogical-op" } */
+/* { dg-options "-Wlogical-op" } */
 
 #ifndef __cplusplus
 # define bool _Bool
diff --git a/gcc/testsuite/c-c++-common/Wlogical-op-2.c b/gcc/testsuite/c-c++-common/Wlogical-op-2.c
new file mode 100644 (file)
index 0000000..6360ef9
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR c/80525 */
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-op" } */
+
+int
+fn (int a, int b)
+{
+  if ((a + 1) && (a + 1)) /* { dg-warning "logical .and. of equal expressions" } */
+    return a;
+  if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */
+    return b;
+}