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

            Bug ID: 91219
           Summary: missing warning on a past-the-end power of access by
                    memcpy
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The past-the-end access in f0 and g0 are diagnosed as expected (the specific
warning could be debated) but the equivalent invalid accesses in f1 and g1 are
not.  The problem is due to the difference between memcpy and MEM_REF.


$ cat a.c && gcc -O2 -S -Wall -fdump-tree-lower=/dev/stdout a.c
char a[4], b[4];

void f0 (void)
{
  __builtin_memcpy (a, b + 1, 4);   // warning (good)
}

void g0 (void)
{
  __builtin_memcpy (a + 1, b, 4);   // warning (good)
}

void f1 (void)
{
  char *p = a, *q = b + 1;
  __builtin_memcpy (p, q, 4);   // missing warning
}

void g1 (void)
{
  char *p = a + 1, *q = b;
  __builtin_memcpy (p, q, 4);   // missing warning
}


;; Function f0 (f0, funcdef_no=0, decl_uid=1910, cgraph_uid=1, symbol_order=2)

f0 ()
{
  _1 = &b + 1;
  __builtin_memcpy (&a, _1, 4);
  return;
}



;; Function g0 (g0, funcdef_no=1, decl_uid=1913, cgraph_uid=2, symbol_order=3)

g0 ()
{
  _1 = &a + 1;
  __builtin_memcpy (_1, &b, 4);
  return;
}



;; Function f1 (f1, funcdef_no=2, decl_uid=1916, cgraph_uid=3, symbol_order=4)

f1 ()
{
  unsigned int D.1926;
  char * q;
  char * p;

  p = &a;
  q = &b + 1;
  D.1926 = MEM <unsigned int> [(char * {ref-all})q];
  MEM <unsigned int> [(char * {ref-all})p] = D.1926;
  return;
}



;; Function g1 (g1, funcdef_no=3, decl_uid=1921, cgraph_uid=4, symbol_order=5)

g1 ()
{
  unsigned int D.1927;
  char * q;
  char * p;

  p = &a + 1;
  q = &b;
  D.1927 = MEM <unsigned int> [(char * {ref-all})q];
  MEM <unsigned int> [(char * {ref-all})p] = D.1927;
  return;
}


a.c: In function ‘f0’:
a.c:5:3: warning: ‘__builtin_memcpy’ forming offset 5 is out of the bounds [0,
4] of object ‘b’ with type ‘char[4]’ [-Warray-bounds]
    5 |   __builtin_memcpy (a, b + 1, 4);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.c:1:12: note: ‘b’ declared here
    1 | char a[4], b[4];
      |            ^
a.c: In function ‘g0’:
a.c:10:3: warning: ‘__builtin_memcpy’ forming offset 5 is out of the bounds [0,
4] of object ‘a’ with type ‘char[4]’ [-Warray-bounds]
   10 |   __builtin_memcpy (a + 1, b, 4);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.c:1:6: note: ‘a’ declared here
    1 | char a[4], b[4];
      |      ^

Reply via email to