Commit 3fe53000 by David Malcolm Committed by David Malcolm

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
parent 9dbdefbb
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
......
......@@ -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)
{
......
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
......
// { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment