https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86400
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- The set constructs a std::string element from *root i.e. "/" with this constructor: 514 basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) 515 : _M_dataplus(_M_local_data(), __a) 516 { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); } Which then calls _M_construct with the same pointer for __beg and __end: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*> (__end=0x6020a0 <foo2()::root> "/", __beg=0x6020a0 <foo2()::root> "/", this=0x7fffffffd320) at /home/jwakely/gcc/9/include/c++/9.0.0/bits/basic_string.h:516 This constructs an empty string object, and so of course the d.find("/") call returns the end iterator. The problem is that traits_type::length(__s) returns 0, which is consistent with my earlier observation that -foptimize-strlen is required to reproduce the failure.