From d84b9c6337bab41ce0cd78969fccc8bc6c086ea0 Mon Sep 17 00:00:00 2001 From: Wawha Date: Tue, 9 Jun 2020 18:21:31 +0200 Subject: [PATCH] fixed unique_ptr::reset() instructions order. Internal pointer must be updated before deleting object (#373) --- include/EASTL/unique_ptr.h | 6 ++---- test/source/TestSmartPtr.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/EASTL/unique_ptr.h b/include/EASTL/unique_ptr.h index b39dd698..27f477ed 100644 --- a/include/EASTL/unique_ptr.h +++ b/include/EASTL/unique_ptr.h @@ -210,10 +210,8 @@ namespace eastl { if (pValue != mPair.first()) { - if (mPair.first()) - get_deleter()(mPair.first()); - - mPair.first() = pValue; + if (auto first = exchange(mPair.first(), pValue)) + get_deleter()(first); } } diff --git a/test/source/TestSmartPtr.cpp b/test/source/TestSmartPtr.cpp index 907c5b1e..031ea8c4 100644 --- a/test/source/TestSmartPtr.cpp +++ b/test/source/TestSmartPtr.cpp @@ -392,6 +392,20 @@ namespace SmartPtrTest int mX; }; + struct CheckUPtrEmptyInDestructor + { + ~CheckUPtrEmptyInDestructor() + { + if(mpUPtr) + mCheckUPtrEmpty = (*mpUPtr == nullptr); + } + + eastl::unique_ptr* mpUPtr{}; + static bool mCheckUPtrEmpty; + }; + + bool CheckUPtrEmptyInDestructor::mCheckUPtrEmpty = false; + } // namespace SmartPtrTest @@ -542,6 +556,16 @@ static int Test_unique_ptr() } } + { + // Test that unique_ptr internal pointer is reset before calling the destructor + CheckUPtrEmptyInDestructor::mCheckUPtrEmpty = false; + + unique_ptr uptr(new CheckUPtrEmptyInDestructor); + uptr->mpUPtr = &uptr; + uptr.reset(); + EATEST_VERIFY(CheckUPtrEmptyInDestructor::mCheckUPtrEmpty); + } + { #if EASTL_CORE_ALLOCATOR_ENABLED // Test EA::Allocator::EASTLICoreDeleter usage within eastl::shared_ptr.