Author: ericwf Date: Wed Jun 1 23:57:00 2016 New Revision: 271487 URL: http://llvm.org/viewvc/llvm-project?rev=271487&view=rev Log: Fix leak in __enable_weak_this(). Thanks to Arthur O'Dwyer for finding it.
Modified: libcxx/trunk/include/memory libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=271487&r1=271486&r2=271487&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Wed Jun 1 23:57:00 2016 @@ -4122,9 +4122,11 @@ private: { if (__e && __e->__weak_this_.expired()) { - __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e)); - __e->__weak_this_.__cntrl_ = __cntrl_; + weak_ptr<_Yp> __tmp; + __tmp.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e)); + __tmp.__cntrl_ = __cntrl_; __cntrl_->__add_weak(); + __e->__weak_this_.swap(__tmp); } } Modified: libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp?rev=271487&r1=271486&r2=271487&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp Wed Jun 1 23:57:00 2016 @@ -26,6 +26,7 @@ #include <cassert> #include "test_macros.h" +#include "count_new.hpp" struct T : public std::enable_shared_from_this<T> @@ -62,7 +63,7 @@ int main() // * Using 'weak_from_this().expired()' in C++17. // * Using 'shared_from_this()' in all dialects. { - + assert(globalMemCounter.checkOutstandingNewEq(0)); T* ptr = new T; std::shared_ptr<T> s(ptr); { @@ -87,6 +88,37 @@ int main() } } #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 #if TEST_STD_VER > 14 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits