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 <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/cfx_retain_ptr.h b/core/fxcrt/cfx_retain_ptr.h
index 0267ae0..5db384f 100644
--- a/core/fxcrt/cfx_retain_ptr.h
+++ b/core/fxcrt/cfx_retain_ptr.h
@@ -44,7 +44,7 @@
   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 @@
     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 3168b5a..f097b4b 100644
--- a/core/fxcrt/cfx_retain_ptr_unittest.cpp
+++ b/core/fxcrt/cfx_retain_ptr_unittest.cpp
@@ -65,6 +65,8 @@
     CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
     {
       CFX_RetainPtr<PseudoRetainable> 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 @@
   EXPECT_EQ(2, obj.release_count());
 }
 
+TEST(fxcrt, RetainPtrMoveAssign) {
+  PseudoRetainable obj;
+  {
+    CFX_RetainPtr<PseudoRetainable> ptr1(&obj);
+    {
+      CFX_RetainPtr<PseudoRetainable> 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;