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.