forked from OSchip/llvm-project
Fix bug #20335 - memory leak when move-constructing a string with unequal allocator. Thanks to Thomas Koeppe for the report
llvm-svn: 213269
This commit is contained in:
parent
18cfe7d634
commit
3dd8846840
libcxx
|
@ -1031,16 +1031,16 @@ __str_rfind(const _CharT *__p, _SizeT __sz,
|
||||||
_CharT __c, _SizeT __pos) _NOEXCEPT
|
_CharT __c, _SizeT __pos) _NOEXCEPT
|
||||||
{
|
{
|
||||||
if (__sz < 1)
|
if (__sz < 1)
|
||||||
return __npos;
|
return __npos;
|
||||||
if (__pos < __sz)
|
if (__pos < __sz)
|
||||||
++__pos;
|
++__pos;
|
||||||
else
|
else
|
||||||
__pos = __sz;
|
__pos = __sz;
|
||||||
for (const _CharT* __ps = __p + __pos; __ps != __p;)
|
for (const _CharT* __ps = __p + __pos; __ps != __p;)
|
||||||
{
|
{
|
||||||
if (_Traits::eq(*--__ps, __c))
|
if (_Traits::eq(*--__ps, __c))
|
||||||
return static_cast<_SizeT>(__ps - __p);
|
return static_cast<_SizeT>(__ps - __p);
|
||||||
}
|
}
|
||||||
return __npos;
|
return __npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2136,11 +2136,13 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||||
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
|
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
|
||||||
: __r_(__a)
|
: __r_(__a)
|
||||||
{
|
{
|
||||||
if (__a == __str.__alloc() || !__str.__is_long())
|
if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
|
||||||
__r_.first().__r = __str.__r_.first().__r;
|
|
||||||
else
|
|
||||||
__init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
|
__init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
|
||||||
__str.__zero();
|
else
|
||||||
|
{
|
||||||
|
__r_.first().__r = __str.__r_.first().__r;
|
||||||
|
__str.__zero();
|
||||||
|
}
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
__get_db()->__insert_c(this);
|
__get_db()->__insert_c(this);
|
||||||
if (__is_long())
|
if (__is_long())
|
||||||
|
|
|
@ -45,6 +45,16 @@ int main()
|
||||||
test(S("1"), A(5));
|
test(S("1"), A(5));
|
||||||
test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
|
test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int alloc_count = test_alloc_base::alloc_count;
|
||||||
|
{
|
||||||
|
typedef test_allocator<char> A;
|
||||||
|
typedef std::basic_string<char, std::char_traits<char>, A> S;
|
||||||
|
S s1 ( "Twas brillig, and the slivy toves did gyre and gymbal in the wabe" );
|
||||||
|
S s2 (std::move(s1), A(1));
|
||||||
|
}
|
||||||
|
assert ( test_alloc_base::alloc_count == alloc_count );
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
{
|
{
|
||||||
typedef min_allocator<char> A;
|
typedef min_allocator<char> A;
|
||||||
|
|
Loading…
Reference in New Issue