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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot 
gnu.org

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC 10.0 diagnoses all but one instance of the buffer overflow, namely the one
in arr_var.  (It issues duplicate warnings which might be something to look
into.)

$ gcc -O2 -S -Wall pr91848.c
pr91848.c: In function ‘arr_cst’:
pr91848.c:12:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3
[-Wstringop-overflow=]
   12 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here
    3 | struct A { char a[3]; int i; };
      |                 ^
pr91848.c:12:3: warning: ‘strcpy’ offset [91, 92] from the object at ‘b’ is out
of the bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 88
[-Warray-bounds]
   12 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr91848.c:3:17: note: subobject ‘a’ declared here
    3 | struct A { char a[3]; int i; };
      |                 ^
pr91848.c: In function ‘ptr_cst’:
pr91848.c:19:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3
[-Wstringop-overflow=]
   19 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here
    3 | struct A { char a[3]; int i; };
      |                 ^
pr91848.c:19:3: warning: ‘strcpy’ offset [91, 92] from the object at ‘p’ is out
of the bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 88
[-Warray-bounds]
   19 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr91848.c:3:17: note: subobject ‘a’ declared here
    3 | struct A { char a[3]; int i; };
      |                 ^
pr91848.c: In function ‘ptr_var’:
pr91848.c:33:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3
[-Wstringop-overflow=]
   33 |   strcpy (q->a, a + sizeof a - 4 - 1);   // missing warning
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here
    3 | struct A { char a[3]; int i; };
      |                 ^

The IL for arr_var where the overflow is not diagnosed looks like so:

arr_var (int i)
{
  const char a[11];
  char[3] * _1;
  sizetype _7;
  sizetype _8;
  sizetype _9;

  <bb 2> [local count: 1073741824]:
  a = "0123456789";
  _7 = (sizetype) i_2(D);
  _8 = _7 * 12;
  _9 = _8 + 4;
  _1 = &b + _9;
  strcpy (_1, &MEM <const char[11]> [(void *)&a + 6B]);
  a ={v} {CLOBBER};
  return;

}

so the detail that the store is to the member of the array b rather than to b
itself is lost.  This appears to be caused by the laddress pass.  Until then
the IL still shows:

  <bb 2> [local count: 1073741824]:
  a = "0123456789";
  _1 = &MEM <struct B[<unknown>]> [(struct A *)&b][i_2(D)].a.a;
  strcpy (_1, &MEM <const char[11]> [(void *)&a + 6B]);

Reply via email to