https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79929

--- Comment #13 from Martin Sebor <msebor at gcc dot gnu.org> ---
> Apparently the problem comes from the fact that len(yerrmsg) is not known at
> compile time, but I don't understand why the warning use nonsensical numbers.

The numbers that are printed are the values or their ranges that GCC computes
for the arguments and what GCC uses as the maximum: 9223372036854775807 (or
PTRDIFF_MAX) in LP64.  Memset takes a size_t argument so negative values passed
to it are printed as very large positive numbers.  In both instances of the
warning for the Fortran test case, 4294967291 (in ILP32) and
18446744073709551611 (LP64) is the same as -5.

On x86_64 where the warning triggers with -O2, the excessive memset is
introduced during constant propagation (-fdump-tree-ccp1=/dev/stdout).  The
.ccp1 dump shows this:

  _32 = _yerrmsg_19(D) + 5;
  ...
  _10 = (unsigned long) _32;
  _11 = (unsigned long) _yerrmsg_19(D);
  if (_10 < _11)                   <<<  can never be true
    goto <bb 7>; [0.00%]
  else
    goto <bb 8>; [0.00%]

  <bb 7> [0.00%]:
  _12 = (unsigned long) _yerrmsg_19(D);
  _13 = (unsigned long) _32;
  _15 = (sizetype) _32;
  _16 = yerrmsg_25(D) + _15;
  __builtin_memset (_16, 32, 18446744073709551611);

The result of yerrmsg + 5 (_10) can never be less than the yerrmsg pointer
itself (_11) so the test (_10  < _11) above can never succeed.  The test shows
up in the first dump so, as Jeff already noted in comment #2,  it's introduced
by the Fortran front end.  I don't enough about Fortran to guess why the test
is introduced but it should be clear that the problem is not that the warning
is behaving incorrectly or printing nonsensical numbers but rather either that
a test that cannot be true is inserted to begin with, or that it's not
eliminated.

That said, it's possible that the warning could be made clearer if it used some
other notation instead of printing very large positive decimal numbers.  I'm
not sure that printing hex numbers instead is the right solution though.  The
following doesn't seem much clearer to me:

Warning: ‘__builtin_memset’: specified size 0xfffffffffffffffb exceeds maximum
object size 7fffffffffffffff [-Wstringop-overflow=]

In any event, the particular notation used by the warning is orthogonal to this
problem.

Reply via email to