Index: include/bits/basic_string.h =================================================================== --- include/bits/basic_string.h (revision 158139) +++ include/bits/basic_string.h (working copy) @@ -197,12 +197,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void _M_set_length_and_sharable(size_type __n) - { - this->_M_set_sharable(); // One reference. - this->_M_length = __n; - traits_type::assign(this->_M_refdata()[__n], _S_terminal); - // grrr. (per 21.3.4) - // You cannot leave those LWG people alone for a second. + { +#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__builtin_expect(this != &_S_empty_rep(), false)) +#endif + { + this->_M_set_sharable(); // One reference. + this->_M_length = __n; + traits_type::assign(this->_M_refdata()[__n], _S_terminal); + // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + } } _CharT* @@ -1226,16 +1231,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * The value of the string doesn't change if an error is thrown. */ iterator - erase(iterator __first, iterator __last) - { - _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last - && __last <= _M_iend()); - const size_type __pos = __first - _M_ibegin(); - _M_mutate(__pos, __last - __first, size_type(0)); - _M_rep()->_M_set_leaked(); - return iterator(_M_data() + __pos); - } - + erase(iterator __first, iterator __last); + /** * @brief Replace characters with value from another string. * @param pos Index of first character to replace. Index: include/bits/basic_string.tcc =================================================================== --- include/bits/basic_string.tcc (revision 158139) +++ include/bits/basic_string.tcc (working copy) @@ -387,6 +387,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } template + typename basic_string<_CharT, _Traits, _Alloc>::iterator + basic_string<_CharT, _Traits, _Alloc>:: + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + + // NB: This isn't just an optimization (bail out early when + // there is nothing to do, really), it's also a correctness + // issue vs MT, see libstdc++/40518. + const size_type __size = __last - __first; + if (__size) + { + const size_type __pos = __first - _M_ibegin(); + _M_mutate(__pos, __size, size_type(0)); + _M_rep()->_M_set_leaked(); + return iterator(_M_data() + __pos); + } + else + return __first; + } + + template basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: replace(size_type __pos, size_type __n1, const _CharT* __s,