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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
The memmove call in the IL the warning is issued for writes past the end of the
allocated block.  My guess is that the call to operator new prevents it from
figuring out that the _M_finish initially zeroed out by the vectorized store to
vectp.132_96 is still clear in bb 5.  This can be confirmed by replacing the
call to operator new with one to __builtin_malloc() which both eliminates the
warning and also results in much more efficient code(*).  There are duplicates
of this problem in Bugzilla.  The root cause is probably the fix for pr101480.

  <bb 2> [local count: 1073741824]:
  vectp.132_96 = &MEM[(struct _Vector_impl_data *)v_2(D)]._M_start;
  MEM <vector(2) long unsigned int> [(union U * *)vectp.132_96] = { 0, 0 };  
<<< zero out _M_finish (and _M_start)
  MEM[(struct _Vector_impl_data *)v_2(D)]._M_end_of_storage = 0B;
  _70 = operator new (100);

  <bb 3> [local count: 1073741824]:
  __builtin_memset (_70, 255, 100);
  _78 = v_2(D)->D.25350._M_impl.D.24657._M_start;    <<< zero
  if (_78 != 0B)
    goto <bb 4>; [89.00%]
  else
    goto <bb 5>; [11.00%]

  <bb 4> [local count: 439275554]:                   <<< unreachable 
  # __cur_127 = PHI <__cur_83(4), _70(3)>
  # __first_120 = PHI <__first_82(4), _78(3)>
  *__cur_127 ={v} {CLOBBER};
  _81 = MEM[(const union U &)__first_120];
  MEM[(union U *)__cur_127] = _81;
  __first_82 = __first_120 + 1;
  __cur_83 = __cur_127 + 1;
  goto <bb 4>; [100.00%]

  <bb 5> [local count: 54292484]:
  __new_finish_85 = _70 + 100;
  _86 = v_2(D)->D.25350._M_impl.D.24657._M_finish;   <<< zero
  if (_86 != 0B)
    goto <bb 6>; [89.00%]
  else
    goto <bb 7>; [11.00%]

  <bb 6> [local count: 48320311]:                    <<< unreachable
  _93 = (sizetype) _86;                              <<< zero
  __builtin_memmove (__new_finish_85, 0B, _93);      <<< warning
  ...


The IL for the function when operator new is replaced with __builtin_malloc:

struct vector bug ()
{
  union U * __new_finish;
  union U * __cur;
  long unsigned int __n;
  union U * _70;

  <bb 2> [local count: 1073741824]:
  _70 = __builtin_malloc (100);
  __builtin_memset (_70, 255, 100);
  __new_finish_84 = _70 + 100;
  v_2(D)->D.25350._M_impl.D.24657._M_start = _70;
  v_2(D)->D.25350._M_impl.D.24657._M_finish = __new_finish_84;
  v_2(D)->D.25350._M_impl.D.24657._M_end_of_storage = __new_finish_84;
  return v_2(D);

}

Reply via email to