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

--- Comment #5 from Marc Glisse <glisse at gcc dot gnu.org> ---
struct A { char*p; char c[13]; };
void f(A&a,bool b){
  a.p=b?a.c:(char*)__builtin_malloc(13);
  __builtin_memcpy(a.p, "hello world!", 12);
  a.p[12]=0;
}

gives

  if (b_4(D) != 0)
    goto <bb 3>; [67.00%]
  else
    goto <bb 4>; [33.00%]

  <bb 3> [local count: 719407023]:
  iftmp.0_9 = &a_8(D)->c;
  goto <bb 5>; [100.00%]

  <bb 4> [local count: 354334802]:
  iftmp.0_7 = __builtin_malloc (13);

  <bb 5> [local count: 1073741824]:
  # iftmp.0_2 = PHI <iftmp.0_9(3), iftmp.0_7(4)>
  a_8(D)->p = iftmp.0_2;
  __builtin_memcpy (iftmp.0_2, "hello world!", 12);
  _1 = a_8(D)->p;
  MEM[(char *)_1 + 12B] = 0;

Note in particular that the compiler fails to notice that memcpy cannot clobber
the first field of p.

If I tweak the libstdc++ implementation to let it know that copying and writing
the final 0 do not clobber the pointer, I can get

  # _47 = PHI <_59(9), &str.D.28972._M_local_buf(12), _59(8)>
  str ={v} {CLOBBER};
  return _47;

but that doesn't warn, although you just said that it warns for "maybe"s?

Reply via email to