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

--- Comment #12 from Siddhesh Poyarekar <siddhesh at gcc dot gnu.org> ---
This is interesting here's the IR dump right after objsz:

struct magic_map * apprentice_load ()
{
  unsigned int i;
  char b[1024];
  struct magic_ * ptr;
  struct magic_map * map2;
  char buf[128];
  struct magic_ * * _1;
  void * _9;
  long unsigned int _11;

  <bb 2> [local count: 1073741824]:
  map2_4 = __builtin_malloc (8);
  pin_pointer (&buf);
  _1 = &map2_4->magic;
  _9 = __builtin_malloc (9);
  *_1 = _9;
  goto <bb 4>; [100.00%]

  <bb 3> [local count: 1073741824]:
  b = "";
  ptr_10 = *_1;
  _11 = 8;
  __builtin___memcpy_chk (ptr_10, &b, 9, _11);
  b ={v} {CLOBBER(eos)};
  i_13 = i_12 + 1;

  <bb 4> [local count: 2147483648]:
  # i_12 = PHI <0(2), i_13(3)>
  if (i_12 == 0)
    goto <bb 3>; [50.00%]
  else
    goto <bb 5>; [50.00%]

  <bb 5> [local count: 1073741824]:
  pin_pointer (map2_4);
  buf ={v} {CLOBBER(eos)};
  return;

}

The key bit is:

  map2_4 = __builtin_malloc (8);
  pin_pointer (&buf);
  _1 = &map2_4->magic;
  _9 = __builtin_malloc (9);
  *_1 = _9;
  goto <bb 4>; [100.00%]

  <bb 3> [local count: 1073741824]:
  b = "";
  ptr_10 = *_1;
  _11 = 8;
  __builtin___memcpy_chk (ptr_10, &b, 9, _11);

where *_1 gets updated to _9, but when one follows the *_1 through ptr_10, it
doesn't end up with _9, the def statement is:

  _1 = &map2_4->magic;

which leads to the incorrect value for the object size.  This is because the
pass doesn't know that a MEM_REF could be the LHS (for the zero byte offset
case like it is here) for an assignment, i.e. this:

  *_1 = _9;

Reply via email to