commit 8b173f993683acdb5ca8048a0a229660c18f45ab Author: Kefu Chai Date: Mon May 1 21:24:26 2023 libstdc++: Set _M_string_length before calling _M_dispose() This always sets _M_string_length in the constructor specialized for range of input_iterator, for the cases like istringstream. 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. In this change, to avoid the false alarm, _M_string_length is initialized to zero before doing anything else, so that _M_is_local() doesn't see an uninitialized value. This issue only surfaces when constructing a string with a range of input_iterator, and the uninitialized _M_string_length is greater than _S_local_capacity, i.e., 15. libstdc++-v3/ChangeLog: * include/bits/basic_string.h (basic_string(Iter, Iter, Alloc)): Initialize _M_string_length. Signed-off-by: Kefu Chai Co-authored-by: Jonathan Wakely diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 8247ee6bdc6..b16b2898b62 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -760,7 +760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _GLIBCXX20_CONSTEXPR basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()) - : _M_dataplus(_M_local_data(), __a) + : _M_dataplus(_M_local_data(), __a), _M_string_length(0) { #if __cplusplus >= 201103L _M_construct(__beg, __end, std::__iterator_category(__beg));