Lift self-copy protection up to the header file and add self-move
authorChandler Carruth <chandlerc@gmail.com>
Tue, 26 Nov 2013 00:54:44 +0000 (00:54 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 26 Nov 2013 00:54:44 +0000 (00:54 +0000)
protection to the same layer.

This is in line with Howard's advice on how best to handle self-move
assignment as he explained on SO[1]. It also ensures that implementing
swap with move assignment continues to work in the case of self-swap.

[1]: http://stackoverflow.com/questions/9322174/move-assignment-operator-and-if-this-rhs

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195705 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/SmallPtrSet.h
lib/Support/SmallPtrSet.cpp

index c7f5e5bfc0f5bedcc6b2618e0932bebce907706c..b52aebf7d55148c2fef048262000b82dfa509b1f 100644 (file)
@@ -293,14 +293,16 @@ public:
 
   SmallPtrSet<PtrType, SmallSize> &
   operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
 
   SmallPtrSet<PtrType, SmallSize> &
   operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
-    CopyFrom(RHS);
+    if (&RHS != this)
+      CopyFrom(RHS);
     return *this;
   }
 
 #if LLVM_HAS_RVALUE_REFERENCES
   SmallPtrSet<PtrType, SmallSize>&
   operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
     return *this;
   }
 
 #if LLVM_HAS_RVALUE_REFERENCES
   SmallPtrSet<PtrType, SmallSize>&
   operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
-    MoveFrom(SmallSizePowTwo, std::move(RHS));
+    if (&RHS != this)
+      MoveFrom(SmallSizePowTwo, std::move(RHS));
     return *this;
   }
 #endif
     return *this;
   }
 #endif
index fa8d91545e71064bde1cf0b7b7d22f27182d2b39..f873d91d6e0ce9342a4a5478853f7484c95c8c23 100644 (file)
@@ -218,8 +218,7 @@ SmallPtrSetImpl::SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
 /// CopyFrom - implement operator= from a smallptrset that has the same pointer
 /// type, but may have a different small size.
 void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
 /// CopyFrom - implement operator= from a smallptrset that has the same pointer
 /// type, but may have a different small size.
 void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
-  if (&RHS == this)
-    return;
+  assert(&RHS != this && "Self-copy should be handled by the caller.");
 
   if (isSmall() && RHS.isSmall())
     assert(CurArraySize == RHS.CurArraySize &&
 
   if (isSmall() && RHS.isSmall())
     assert(CurArraySize == RHS.CurArraySize &&
@@ -256,6 +255,8 @@ void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
 
 #if LLVM_HAS_RVALUE_REFERENCES
 void SmallPtrSetImpl::MoveFrom(unsigned SmallSize, SmallPtrSetImpl &&RHS) {
 
 #if LLVM_HAS_RVALUE_REFERENCES
 void SmallPtrSetImpl::MoveFrom(unsigned SmallSize, SmallPtrSetImpl &&RHS) {
+  assert(&RHS != this && "Self-move should be handled by the caller.");
+
   if (!isSmall())
     free(CurArray);
 
   if (!isSmall())
     free(CurArray);