PR c++/88680 reports excess warnings from -Wtype-limits after the C++
FE's use of location wrappers was extended in r267272 for cases such as:

  const unsigned n = 8;
  static_assert (n >= 0 && n % 2 == 0, "");

t.C:3:18: warning: comparison of unsigned expression >= 0 is always true
  [-Wtype-limits]
    3 | static_assert (n >= 0 && n % 2 == 0, "");
      |                ~~^~~~

The root cause is that the location wrapper around "n" breaks the
suppression of the warning for the "if OP0 is a constant that is >= 0"
case.

This patch fixes it by calling fold_for_warn on OP0, extracting the
constant.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/c-family/ChangeLog:
        PR c++/88680
        * c-common.c (shorten_compare): Call fold_for_warn on op0 when
        implementing -Wtype-limits.

gcc/testsuite/ChangeLog:
        PR c++/88680
        * g++.dg/wrappers/pr88680.C: New test.
---
 gcc/c-family/c-common.c                 |  2 +-
 gcc/testsuite/g++.dg/wrappers/pr88680.C | 47 +++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/wrappers/pr88680.C

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d3b5879..5813e0a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3114,7 +3114,7 @@ shorten_compare (location_t loc, tree *op0_ptr, tree 
*op1_ptr,
       /* Here we must do the comparison on the nominal type
         using the args exactly as we received them.  */
       type = *restype_ptr;
-      primop0 = op0;
+      primop0 = fold_for_warn (op0);
       primop1 = op1;
 
       if (!real1 && !real2 && integer_zerop (primop1)
diff --git a/gcc/testsuite/g++.dg/wrappers/pr88680.C 
b/gcc/testsuite/g++.dg/wrappers/pr88680.C
new file mode 100644
index 0000000..86945db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/wrappers/pr88680.C
@@ -0,0 +1,47 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wtype-limits" }
+
+const unsigned N = 8;
+const unsigned P = 0;
+
+enum { FOO, BAR };
+
+static_assert (N >= 0 && N % 2 == 0, "");
+static_assert (FOO >= 0, "");
+static_assert (FOO >= FOO, "");
+static_assert (FOO >= P, "");
+static_assert (BAR >= P, "");
+static_assert (N >= FOO, "");
+
+void test(unsigned n)
+{
+  if (N >= 0 && N % 2 == 0, "")
+    return;
+  if (FOO >= 0, "")
+    return;
+  if (FOO >= FOO, "")
+    return;
+  if (FOO >= P, "")
+    return;
+  if (BAR >= P)
+    return;
+  if (N >= FOO, "")
+    return;
+  if (n >= 0) // { dg-warning ">= 0 is always true" }
+    return;
+  if (n < 0) // { dg-warning "< 0 is always false" }
+    return;
+  if (n >= FOO)
+    return;
+  if (n < FOO)
+    return;
+  if (N >= 0)
+    return;
+  if (N < 0)
+    return;
+  if (N >= FOO)
+    return;
+  if (N < FOO)
+    return;
+
+}
-- 
1.8.5.3

Reply via email to