Fix leak in __enable_weak_this(). Thanks to Arthur O'Dwyer for finding it.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@271487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -4122,9 +4122,11 @@ private:
|
|||||||
{
|
{
|
||||||
if (__e && __e->__weak_this_.expired())
|
if (__e && __e->__weak_this_.expired())
|
||||||
{
|
{
|
||||||
__e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));
|
weak_ptr<_Yp> __tmp;
|
||||||
__e->__weak_this_.__cntrl_ = __cntrl_;
|
__tmp.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));
|
||||||
|
__tmp.__cntrl_ = __cntrl_;
|
||||||
__cntrl_->__add_weak();
|
__cntrl_->__add_weak();
|
||||||
|
__e->__weak_this_.swap(__tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
#include "count_new.hpp"
|
||||||
|
|
||||||
struct T
|
struct T
|
||||||
: public std::enable_shared_from_this<T>
|
: public std::enable_shared_from_this<T>
|
||||||
@@ -62,7 +63,7 @@ int main()
|
|||||||
// * Using 'weak_from_this().expired()' in C++17.
|
// * Using 'weak_from_this().expired()' in C++17.
|
||||||
// * Using 'shared_from_this()' in all dialects.
|
// * Using 'shared_from_this()' in all dialects.
|
||||||
{
|
{
|
||||||
|
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||||
T* ptr = new T;
|
T* ptr = new T;
|
||||||
std::shared_ptr<T> s(ptr);
|
std::shared_ptr<T> s(ptr);
|
||||||
{
|
{
|
||||||
@@ -87,6 +88,37 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
s.reset();
|
||||||
|
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||||
|
}
|
||||||
|
// Test LWG issue 2529 again. This time check that an expired pointer
|
||||||
|
// is replaced.
|
||||||
|
{
|
||||||
|
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||||
|
T* ptr = new T;
|
||||||
|
std::weak_ptr<T> weak;
|
||||||
|
{
|
||||||
|
std::shared_ptr<T> s(ptr, &nullDeleter);
|
||||||
|
assert(ptr->shared_from_this() == s);
|
||||||
|
weak = s;
|
||||||
|
assert(!weak.expired());
|
||||||
|
}
|
||||||
|
assert(weak.expired());
|
||||||
|
weak.reset();
|
||||||
|
|
||||||
|
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
ptr->shared_from_this();
|
||||||
|
assert(false);
|
||||||
|
} catch (std::bad_weak_ptr const&) {
|
||||||
|
} catch (...) { assert(false); }
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
std::shared_ptr<T> s2(ptr, &nullDeleter);
|
||||||
|
assert(ptr->shared_from_this() == s2);
|
||||||
|
}
|
||||||
|
delete ptr;
|
||||||
|
assert(globalMemCounter.checkOutstandingNewEq(0));
|
||||||
}
|
}
|
||||||
// Test weak_from_this_methods
|
// Test weak_from_this_methods
|
||||||
#if TEST_STD_VER > 14
|
#if TEST_STD_VER > 14
|
||||||
|
|||||||
Reference in New Issue
Block a user