Check for self-assignment in move assignment
authorZejun Wu <watashi@fb.com>
Thu, 17 Jul 2014 16:49:39 +0000 (09:49 -0700)
committerTudor Bosman <tudorb@fb.com>
Mon, 21 Jul 2014 19:22:03 +0000 (12:22 -0700)
Summary:
Check for self-assignment in move assignment. Otherwise
Optional<Neko> cat = whatever;
cat = std::move(cat);
cat.hasValue(); // always returns false

Test Plan: fbmake runtests

Reviewed By: tjackson@fb.com

FB internal diff: D1440633

folly/Optional.h
folly/test/OptionalTest.cpp

index 701d744e9ad4ff16928afc2aea6c8962e71ef60d..eb8de160c8903d47bda5757c4e28b783bd402ae1 100644 (file)
@@ -136,11 +136,13 @@ class Optional {
   }
 
   void assign(Optional&& src) {
-    if (src.hasValue()) {
-      assign(std::move(src.value()));
-      src.clear();
-    } else {
-      clear();
+    if (this != &src) {
+      if (src.hasValue()) {
+        assign(std::move(src.value()));
+        src.clear();
+      } else {
+        clear();
+      }
     }
   }
 
index ff82abdcdc4e677870fe70f6cff596c6a8204b5e..79968d013f3b439b8607105414c9486b5497187b 100644 (file)
@@ -379,6 +379,16 @@ TEST(Optional, MakeOptional) {
   EXPECT_EQ(**optIntPtr, 3);
 }
 
+TEST(Optional, SelfAssignment) {
+  Optional<int> a = 42;
+  a = a;
+  ASSERT_TRUE(a.hasValue() && a.value() == 42);
+
+  Optional<int> b = 23333333;
+  b = std::move(b);
+  ASSERT_TRUE(b.hasValue() && b.value() == 23333333);
+}
+
 class ContainsOptional {
  public:
   ContainsOptional() { }