https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81437
            Bug ID: 81437
           Summary: missing -Wstringop-overflow reading past the end of a
                    string
           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: ---

GCC 8 diagnoses some non-trivial instances of reading past the end of an array
but misses some of the most basic ones.  For example, while it diagnoses past
the end reads in memcpy when the size is a variable in a range whose lower
bound  causes the invalid access it fails to issue the same diagnostic when the
variable is has a known value with the same effect.  Similarly, no warning is
issued for calls to strcpy whose where the source argument points past the
terminating NUL of a string.

$ cat a.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout a.c
void f (char *d, unsigned n)
{
  const char a[] = "123";
  if (n < 1) n = 1;
  __builtin_memcpy (d, a + 4, n);   // warning (ok)
}

void g (char *d, unsigned n)
{
  const char a[] = "123";
  n = 1;
  __builtin_memcpy (d, a + 4, n);   // missing warning
}

void h (char *d)
{
  const char a[] = "123";
  __builtin_strcpy (d, a + 4);   // missing warning
}

;; Function f (f, funcdef_no=0, decl_uid=1816, cgraph_uid=0, symbol_order=0)

Removing basic block 3
f (char * d, unsigned int n)
{
  const char a[4];
  unsigned int _2;
  long unsigned int prephitmp_9;

  <bb 2> [100.00%] [count: INV]:
  if (n_4(D) == 0)
    goto <bb 3>; [50.00%] [count: INV]
  else
    goto <bb 4>; [50.00%] [count: INV]

  <bb 3> [50.00%] [count: INV]:

  <bb 4> [100.00%] [count: INV]:
  # _2 = PHI <n_4(D)(2), 1(3)>
  prephitmp_9 = (long unsigned int) _2;
  __builtin_memcpy (d_5(D), &MEM[(void *)&a + 4B], prephitmp_9); [tail call]
  a ={v} {CLOBBER};
  return;

}


a.c: In function ‘f’:
a.c:5:3: warning: ‘__builtin_memcpy’ reading between 1 and 4294967295 bytes
from a region of size 0 [-Wstringop-overflow=]
   __builtin_memcpy (d, a + 4, n);   // warning (ok)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;; Function g (g, funcdef_no=1, decl_uid=1821, cgraph_uid=1, symbol_order=1)

g (char * d, unsigned int n)
{
  const char a[4];
  unsigned char _5;

  <bb 2> [100.00%] [count: INV]:
  _5 = MEM[(char * {ref-all})&a + 4B];
  MEM[(char * {ref-all})d_2(D)] = _5;
  a ={v} {CLOBBER};
  return;

}



;; Function h (h, funcdef_no=2, decl_uid=1825, cgraph_uid=2, symbol_order=2)

h (char * d)
{
  const char a[4];

  <bb 2> [100.00%] [count: INV]:
  __builtin_strcpy (d_2(D), &MEM[(void *)&a + 4B]); [tail call]
  a ={v} {CLOBBER};
  return;

}

Reply via email to