From 1cf6182218bec79ece0b91e762f507e8c027807c Mon Sep 17 00:00:00 2001 From: Wawha Date: Wed, 10 Jun 2020 21:47:55 +0200 Subject: [PATCH] fixed unique_ptr<[]>::reset() instructions order. Internal pointer must be updated before deleting object (#375) --- include/EASTL/unique_ptr.h | 6 +++--- test/source/TestSmartPtr.cpp | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/include/EASTL/unique_ptr.h b/include/EASTL/unique_ptr.h index 27f477ed..cce8ebde 100644 --- a/include/EASTL/unique_ptr.h +++ b/include/EASTL/unique_ptr.h @@ -210,7 +210,7 @@ namespace eastl { if (pValue != mPair.first()) { - if (auto first = exchange(mPair.first(), pValue)) + if (auto first = eastl::exchange(mPair.first(), pValue)) get_deleter()(first); } } @@ -431,8 +431,8 @@ namespace eastl { if(pArray != mPair.first()) { - get_deleter()(mPair.first()); - mPair.first() = pArray; + if (auto first = eastl::exchange(mPair.first(), pArray)) + get_deleter()(first); } } diff --git a/test/source/TestSmartPtr.cpp b/test/source/TestSmartPtr.cpp index 594d569d..dc94b960 100644 --- a/test/source/TestSmartPtr.cpp +++ b/test/source/TestSmartPtr.cpp @@ -406,6 +406,19 @@ namespace SmartPtrTest bool CheckUPtrEmptyInDestructor::mCheckUPtrEmpty = false; + struct CheckUPtrArrayEmptyInDestructor + { + ~CheckUPtrArrayEmptyInDestructor() + { + if(mpUPtr) + mCheckUPtrEmpty = (*mpUPtr == nullptr); + } + + eastl::unique_ptr* mpUPtr{}; + static bool mCheckUPtrEmpty; + }; + + bool CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty = false; } // namespace SmartPtrTest @@ -566,6 +579,16 @@ static int Test_unique_ptr() EATEST_VERIFY(CheckUPtrEmptyInDestructor::mCheckUPtrEmpty); } + { + // Test that unique_ptr<[]> internal pointer is reset before calling the destructor + CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty = false; + + unique_ptr uptr(new CheckUPtrArrayEmptyInDestructor[1]); + uptr[0].mpUPtr = &uptr; + uptr.reset(); + EATEST_VERIFY(CheckUPtrArrayEmptyInDestructor::mCheckUPtrEmpty); + } + { #if EASTL_CORE_ALLOCATOR_ENABLED // Test EA::Allocator::EASTLICoreDeleter usage within eastl::shared_ptr.