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

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu.org

--- Comment #6 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
renaming main to main2 and compiling with -O2 -fno-exceptions makes the string
go away now.  With exceptions we get:

int main2 ()
{
  void * D.39961;
  struct string s;
  char * _24;
  long unsigned int _26;
  long unsigned int _27;
  void * _28;

  <bb 2> [local count: 1073741824]:
  MEM[(struct basic_string *)&s] ={v} {CLOBBER(bob)};
  MEM[(struct _Alloc_hider *)&s] ={v} {CLOBBER(bob)};
  MEM[(struct _Alloc_hider *)&s]._M_p = &s.D.25525._M_local_buf;
  __builtin_memcpy (&s.D.25525._M_local_buf, "abc", 3);
  s._M_string_length = 3;
  MEM[(char_type &)&s + 19] = 0;
  foo ();

  <bb 3> [local count: 1073741824]:
  _24 = s._M_dataplus._M_p;
  if (&s.D.25525._M_local_buf == _24)
    goto <bb 5>; [18.09%]
  else
    goto <bb 4>; [81.91%]

  <bb 4> [local count: 879501928]:
  _26 = s.D.25525._M_allocated_capacity;
  _27 = _26 + 1;
  operator delete (_24, _27);

  <bb 5> [local count: 1073741824]:
  s ={v} {CLOBBER(eob)};
  s ={v} {CLOBBER(eos)};
  return 0;

  <bb 6> [count: 0]:
<L5>:
  std::__cxx11::basic_string<char>::_M_dispose (&s);
  s ={v} {CLOBBER(eob)};
  _28 = __builtin_eh_pointer (6);
  __builtin_unwind_resume (_28);

}

the problem here is call to _M_dispose which prevents removal of new/delete
pair.

_M_dispose looks as follows:
void std::__cxx11::basic_string<char>::_M_dispose (struct basic_string * const
this)
{
  long unsigned int _1;
  char * _5;
  const char[16] * _6;
  long unsigned int _7;
  long unsigned int _8;

  <bb 2> [local count: 1073741824]:
  _5 = MEM[(const struct basic_string *)this_4(D)]._M_dataplus._M_p;
  _6 = &MEM[(const struct basic_string *)this_4(D)].D.25525._M_local_buf;
  if (_5 == _6)
    goto <bb 3>; [18.09%]
  else
    goto <bb 5>; [81.91%]

  <bb 3> [local count: 194239896]:
  _7 = MEM[(const struct basic_string *)this_4(D)]._M_string_length;
  if (_7 > 15)
    goto <bb 4>; [0.00%]
  else
    goto <bb 6>; [100.00%]

  <bb 4> [count: 0]:
  __builtin_unreachable ();

  <bb 5> [local count: 879501928]:
  _1 = this_4(D)->D.25525._M_allocated_capacity;
  _8 = _1 + 1;
  operator delete (_5, _8);

  <bb 6> [local count: 1073741824]:
  return;

}

We do fnsplit to optimize away the builtin_unreachable check which is silly.
Will fix that. However without getting it inline we currently can't math the
new/delete pair.

Reply via email to