From 3fe53000bbaa5024af7ceecb950e0a7fd6b189e3 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Sat, 16 Feb 2019 16:17:17 +0000 Subject: [PATCH] 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 --- gcc/c-family/ChangeLog | 6 +++ gcc/c-family/c-common.c | 13 ++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/wrappers/pr88680.C | 56 +++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/wrappers/pr88680.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7dae7bf530a..ed8026a33e0 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-02-16 David Malcolm + + PR c++/88680 + * c-common.c (shorten_compare): Call fold_for_warn on op0 when + implementing -Wtype-limits. + 2019-02-11 Martin Sebor PR c++/87996 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index ae23e59f652..c6856c9ad10 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 e68f969bcb2..45fbe7c0296 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-16 David Malcolm + + PR c++/88680 + * g++.dg/wrappers/pr88680.C: New test. + 2019-02-17 Thomas Koenig 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 00000000000..5497cda5c9c --- /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; +} -- 2.30.2