aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-02-16 16:17:17 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2019-02-16 16:17:17 +0000
commit3fe53000bbaa5024af7ceecb950e0a7fd6b189e3 (patch)
treed4ce7caa5c4014625f6fccf5e7a10714d8b7e302 /gcc
parent9dbdefbb201dd67cd1ce795e969c3ae1a850c31d (diff)
downloadgcc-3fe53000bbaa5024af7ceecb950e0a7fd6b189e3.zip
gcc-3fe53000bbaa5024af7ceecb950e0a7fd6b189e3.tar.gz
gcc-3fe53000bbaa5024af7ceecb950e0a7fd6b189e3.tar.bz2
Fix excess warnings from -Wtype-limits with location wrappers (PR c++/88680)
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. 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. From-SVN: r268961
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/wrappers/pr88680.C56
4 files changed, 77 insertions, 3 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 7dae7bf..ed8026a 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2019-02-16 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/88680
+ * c-common.c (shorten_compare): Call fold_for_warn on op0 when
+ implementing -Wtype-limits.
+
2019-02-11 Martin Sebor <msebor@redhat.com>
PR c++/87996
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index ae23e59..c6856c9 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3117,6 +3117,12 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
primop0 = op0;
primop1 = op1;
+ /* We want to fold unsigned comparisons of >= and < against zero.
+ For these, we may also issue a warning if we have a non-constant
+ compared against zero, where the zero was spelled as "0" (rather
+ than merely folding to it).
+ If we have at least one constant, then op1 is constant
+ and we may have a non-constant expression as op0. */
if (!real1 && !real2 && integer_zerop (primop1)
&& TYPE_UNSIGNED (*restype_ptr))
{
@@ -3125,13 +3131,14 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
if OP0 is a constant that is >= 0, the signedness of
the comparison isn't an issue, so suppress the
warning. */
+ tree folded_op0 = fold_for_warn (op0);
bool warn =
warn_type_limits && !in_system_header_at (loc)
- && !(TREE_CODE (primop0) == INTEGER_CST
+ && !(TREE_CODE (folded_op0) == INTEGER_CST
&& !TREE_OVERFLOW (convert (c_common_signed_type (type),
- primop0)))
+ folded_op0)))
/* Do not warn for enumeration types. */
- && (TREE_CODE (expr_original_type (primop0)) != ENUMERAL_TYPE);
+ && (TREE_CODE (expr_original_type (folded_op0)) != ENUMERAL_TYPE);
switch (code)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e68f969..45fbe7c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-02-16 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/88680
+ * g++.dg/wrappers/pr88680.C: New test.
+
2019-02-17 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/71066
diff --git a/gcc/testsuite/g++.dg/wrappers/pr88680.C b/gcc/testsuite/g++.dg/wrappers/pr88680.C
new file mode 100644
index 0000000..5497cda
--- /dev/null
+++ b/gcc/testsuite/g++.dg/wrappers/pr88680.C
@@ -0,0 +1,56 @@
+// { 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;
+ if (0 <= FOO)
+ return;
+ if (0 <= n) // { dg-warning ">= 0 is always true" }
+ return;
+ if (0 > n) // { dg-warning "< 0 is always false" }
+ return;
+ if (N <= FOO)
+ return;
+ if (N <= n)
+ return;
+}