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

            Bug ID: 84859
           Summary: bogus -Warray-bounds on a memcpy in a loop
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The following test case was reduced from the report at
https://lkml.org/lkml/2018/3/13/383.

In g() GCC correctly figures out the memcpy call is safe.  In h(), though, it
thinks it overflows.

$ cat x.c && gcc -S -O2 -Wall x.c
void f (void*);

void __attribute__ ((noinline, noclone))
g (const void *p, unsigned n)
{
  unsigned char a[8];
  if (n > sizeof a)
    return;

  for (; n > 0; n -= *a)
  {
     *a = n > 255 ? 255 : n;

    __builtin_memcpy (a, p, *a);   // no warning (good)
  }
}

void __attribute__ ((noinline, noclone))
h (const void *p, unsigned n)
{
  unsigned char a[8];
  if (n > sizeof a)
    return;

  for (; n > 0; n -= *a)
  {
    if (n > 255)
      *a = 255;
    else
      *a = n;

    __builtin_memcpy (a, p, *a);   // bogus -Warray-bounds
  }
}
x.c: In function ‘h’:
x.c:32:5: warning: ‘__builtin_memcpy’ forming offset [9, 255] is out of the
bounds [0, 8] of object ‘a’ with type ‘unsigned char[8]’ [-Warray-bounds]
     __builtin_memcpy (a, p, *a);   // bogus -Warray-bounds
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:21:17: note: ‘a’ declared here
   unsigned char a[8];
                 ^

Reply via email to