https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99805
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- Wow, this is tricksy. The bug happens when parsing the string into a path. The path is split into components and the offset of each component from the beginning of the string is stored, so that parent_path() can efficiently erase the part of the native() string that refers to the last component. The offset is calculated like this: for (auto& c : buf) { auto pos = c.str.data() - _M_pathname.data(); ::new(output++) _Cmpt(c.str, c.type, pos); ++_M_cmpts._M_impl->_M_size; } The bug is that for the COW std::string _M_pathname.data() causes the string to be reallocated, and so changes the address at which the string is stored. So the string_view c.str no longer refers to the same data as _M_pathname. We get a bogus offset for the components, and when we try to remove the last component to get the parent_path(), we don't remove anything from the string.