[libcxx] r213269 - Fix bug #20335 - memory leak when move-constructing a string with unequal allocator. Thanks to Thomas Koeppe for the report

Marshall Clow mclow.lists at gmail.com
Thu Jul 17 08:32:21 PDT 2014


Author: marshall
Date: Thu Jul 17 10:32:20 2014
New Revision: 213269

URL: http://llvm.org/viewvc/llvm-project?rev=213269&view=rev
Log:
Fix bug #20335 - memory leak when move-constructing a string with unequal allocator. Thanks to Thomas Koeppe for the report

Modified:
    libcxx/trunk/include/string
    libcxx/trunk/test/strings/basic.string/string.cons/move_alloc.pass.cpp

Modified: libcxx/trunk/include/string
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=213269&r1=213268&r2=213269&view=diff
==============================================================================
--- libcxx/trunk/include/string (original)
+++ libcxx/trunk/include/string Thu Jul 17 10:32:20 2014
@@ -1031,16 +1031,16 @@ __str_rfind(const _CharT *__p, _SizeT __
               _CharT __c, _SizeT __pos) _NOEXCEPT
 {
     if (__sz < 1)
-    	return __npos;
-	if (__pos < __sz)
-		++__pos;
-	else
-		__pos = __sz;
-	for (const _CharT* __ps = __p + __pos; __ps != __p;)
-	{
-		if (_Traits::eq(*--__ps, __c))
-			return static_cast<_SizeT>(__ps - __p);
-	}
+        return __npos;
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+    {
+        if (_Traits::eq(*--__ps, __c))
+            return static_cast<_SizeT>(__ps - __p);
+    }
     return __npos;
 }
 
@@ -2136,11 +2136,13 @@ inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
     : __r_(__a)
 {
-    if (__a == __str.__alloc() || !__str.__is_long())
-        __r_.first().__r = __str.__r_.first().__r;
-    else
+    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
         __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
     __get_db()->__insert_c(this);
     if (__is_long())

Modified: libcxx/trunk/test/strings/basic.string/string.cons/move_alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.cons/move_alloc.pass.cpp?rev=213269&r1=213268&r2=213269&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.cons/move_alloc.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.cons/move_alloc.pass.cpp Thu Jul 17 10:32:20 2014
@@ -45,6 +45,16 @@ int main()
     test(S("1"), A(5));
     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
     {
     typedef min_allocator<char> A;





More information about the cfe-commits mailing list