mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-15 15:03:40 +08:00
re PR libstdc++/40518 (data races when calling std::string::erase() on empty string)
2009-06-23 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/40518 * include/bits/basic_string.h (basic_string<>::_Rep:: _M_set_length_and_sharable): Do not write the empty rep. (basic_string<>::erase(iterator, iterator)): Likewise, move out of line... * include/bits/basic_string.tcc: ... here. From-SVN: r148850
This commit is contained in:
parent
2724e58f96
commit
7309083f99
@ -1,3 +1,12 @@
|
||||
2009-06-23 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/40518
|
||||
* include/bits/basic_string.h (basic_string<>::_Rep::
|
||||
_M_set_length_and_sharable): Do not write the empty rep.
|
||||
(basic_string<>::erase(iterator, iterator)): Likewise,
|
||||
move out of line...
|
||||
* include/bits/basic_string.tcc: ... here.
|
||||
|
||||
2009-06-22 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* testsuite/util/testsuite_common_types.h (bitwise_operators,
|
||||
|
@ -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.
|
||||
|
@ -385,6 +385,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc>
|
||||
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<typename _CharT, typename _Traits, typename _Alloc>
|
||||
basic_string<_CharT, _Traits, _Alloc>&
|
||||
basic_string<_CharT, _Traits, _Alloc>::
|
||||
|
Loading…
Reference in New Issue
Block a user