https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109706
Bug ID: 109706 Summary: basic_string runs into __builtin_unreachable() when constructing from istringstream Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tchaikov at gmail dot com Target Milestone: --- We copy from source range to the local buffer, and then reallocate to larger one if necessary, when disposing the old buffer. And the old buffer could be provisioned by the local buffer or an allocated buffer. _M_is_local() is used to tell if the buffer is the local one or not. In addition to comparing the buffer address with the local buffer, this function also performs the sanity check if _M_string_length is greater than _S_local_capacity, if the check fails __builtin_unreachable() is called. But we failed to set _M_string_length in this constructor is specialized for std::input_iterator. So, if UBSan is enabled when compiling the source, there are chances that the uninitialized data in _M_string_length is greater than _S_local_capacity, and the application aborts a runtime error or exception emitted by the UBSan. a minimal reproducer is like: #include <cstring> #include <string> #include <sstream> int main() { unsigned char buf[sizeof(std::string)] ; std::memset(buf, 0xff, sizeof(buf)); const char s[] = "1234567890abcdefg"; std::istringstream in{s}; std::istreambuf_iterator<char> it{in}, end; auto* p = new (buf) std::string(it, end); return 0; } see https://godbolt.org/z/7q4nG68xn a patch has been posted to the related mailing list. see https://gcc.gnu.org/pipermail/libstdc++/2023-May/055895.html