From 6bbb6097b7150dcace3e2fd69caff8b73d59647a Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Thu, 23 Mar 2017 14:54:59 -0700 Subject: Fix CFX_RetainPtr move-assign semantics. Ensure moved value becomes a nullptr after the move. Update comment while we're at it. Change-Id: I7a2999d5f5c5142cc7826cd7880b1e2317b5445f Reviewed-on: https://pdfium-review.googlesource.com/3163 Commit-Queue: Tom Sepez Reviewed-by: Lei Zhang --- core/fxcrt/cfx_retain_ptr.h | 7 ++++++- core/fxcrt/cfx_retain_ptr_unittest.cpp | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/core/fxcrt/cfx_retain_ptr.h b/core/fxcrt/cfx_retain_ptr.h index 0267ae04cd..5db384f334 100644 --- a/core/fxcrt/cfx_retain_ptr.h +++ b/core/fxcrt/cfx_retain_ptr.h @@ -44,7 +44,7 @@ class CFX_RetainPtr { T* Get() const { return m_pObj.get(); } void Swap(CFX_RetainPtr& that) { m_pObj.swap(that.m_pObj); } - // TODO(tsepez): temporary scaffolding, to be removed. + // Useful for passing notion of object ownership across a C API. T* Leak() { return m_pObj.release(); } void Unleak(T* ptr) { m_pObj.reset(ptr); } @@ -54,6 +54,11 @@ class CFX_RetainPtr { return *this; } + CFX_RetainPtr& operator=(CFX_RetainPtr&& that) { + m_pObj.reset(that.Leak()); + return *this; + } + bool operator==(const CFX_RetainPtr& that) const { return Get() == that.Get(); } diff --git a/core/fxcrt/cfx_retain_ptr_unittest.cpp b/core/fxcrt/cfx_retain_ptr_unittest.cpp index 3168b5a4c7..f097b4b28c 100644 --- a/core/fxcrt/cfx_retain_ptr_unittest.cpp +++ b/core/fxcrt/cfx_retain_ptr_unittest.cpp @@ -65,6 +65,8 @@ TEST(fxcrt, RetainPtrMoveCtor) { CFX_RetainPtr ptr1(&obj); { CFX_RetainPtr ptr2(std::move(ptr1)); + EXPECT_EQ(nullptr, ptr1.Get()); + EXPECT_EQ(&obj, ptr2.Get()); EXPECT_EQ(1, obj.retain_count()); EXPECT_EQ(0, obj.release_count()); } @@ -185,6 +187,27 @@ TEST(fxcrt, RetainPtrAssign) { EXPECT_EQ(2, obj.release_count()); } +TEST(fxcrt, RetainPtrMoveAssign) { + PseudoRetainable obj; + { + CFX_RetainPtr ptr1(&obj); + { + CFX_RetainPtr ptr2; + EXPECT_EQ(&obj, ptr1.Get()); + EXPECT_EQ(nullptr, ptr2.Get()); + ptr2 = std::move(ptr1); + EXPECT_EQ(nullptr, ptr1.Get()); + EXPECT_EQ(&obj, ptr2.Get()); + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(0, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); + } + EXPECT_EQ(1, obj.retain_count()); + EXPECT_EQ(1, obj.release_count()); +} + TEST(fxcrt, RetainPtrEquals) { PseudoRetainable obj1; PseudoRetainable obj2; -- cgit v1.2.3