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

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
I can confirm the warning with the (possibly overly) reduced test case below
but not really that it's a bug in the warning code.  In the reduced test case,
memset() is called with a size that's either zero or in excess of PTRDIFF_MAX. 
The call is diagnosed by design because the zero size is unlikely.

In the bigger test case, GCC (I think the jump threading pass) introduces a
couple of earlier calls to memset that VRP substitutes constant arguments into
and leaves the last call with the non-constant argument in the same ~[1,
PTRDIFF_MAX] anti-range.  One solution would be to improve GCC to eliminate the
last memcpy() call because it's either dead (zero size) or invalid.

In the meantime, changing the type of the argument to func2() to unsigned
avoids the warning.  It's better to use unsigned variables to represent
quantities that cannot be negative; that way the whole issue or excessively
large results as a result of sign extension becomes moot.

$ cat c.c && gcc -O2 -S -Wall -fdump-tree-vrp=/dev/stdout c.c
void g (int *a, int n)
{
  if (n == 2)
    *a = 0;
  else if (n > 0)
    return;

  char b[8];
  __builtin_memset (b, 0, n);

  if (n == 2)
    return;

  __builtin_puts (b);
}

...
Value ranges after VRP:

...
_20: ~[1, 18446744071562067967]


g (int * a, int n)
{
  char b[8];
  long unsigned int _20;

  <bb 2> [local count: 1073741825]:
  if (n_5(D) == 2)
    goto <bb 3>; [34.00%]
  else
    goto <bb 4>; [66.00%]

  <bb 3> [local count: 365072220]:
  *a_7(D) = 0;
  goto <bb 5>; [100.00%]

  <bb 4> [local count: 708669604]:
  if (n_5(D) > 0)
    goto <bb 5>; [42.57%]
  else
    goto <bb 7>; [57.43%]

  <bb 5> [local count: 571979267]:
  b ={v} {CLOBBER};

  <bb 6> [local count: 1073741825]:
  return;

  <bb 7> [local count: 501762557]:
  _20 = (long unsigned int) n_5(D);
  __builtin_memset (&b, 0, _20);
  __builtin_puts (&b);
  b ={v} {CLOBBER};
  goto <bb 6>; [100.00%]

}


c.c: In function ‘g’:
c.c:9:3: warning: ‘__builtin_memset’ specified size between
18446744071562067968 and 18446744073709551615 exceeds maximum object size
9223372036854775807 [-Wstringop-overflow=]
   __builtin_memset (b, 0, n);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to