From dafae50ce26b89ffbdd6a154a273d17e5ebbbfeb Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 17 Jul 2015 15:55:24 +0200 Subject: [PATCH] Protect against self-move-assignment to fix stable_sort in MSVC --- panda/src/express/pointerToBase.I | 15 +++++++++------ panda/src/putil/copyOnWritePointer.I | 13 ++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index 783d59353e..ce319a5f50 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -71,14 +71,17 @@ PointerToBase(PointerToBase &&from) NOEXCEPT { template INLINE void PointerToBase:: reassign(PointerToBase &&from) NOEXCEPT { - To *old_ptr = (To *)this->_void_ptr; + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + To *old_ptr = (To *)this->_void_ptr; - this->_void_ptr = from._void_ptr; - from._void_ptr = NULL; + this->_void_ptr = from._void_ptr; + from._void_ptr = NULL; - // Now delete the old pointer. - if (old_ptr != (To *)NULL) { - unref_delete(old_ptr); + // Now delete the old pointer. + if (old_ptr != (To *)NULL) { + unref_delete(old_ptr); + } } } #endif // USE_MOVE_SEMANTICS diff --git a/panda/src/putil/copyOnWritePointer.I b/panda/src/putil/copyOnWritePointer.I index d9c81d9de5..47e51fab15 100644 --- a/panda/src/putil/copyOnWritePointer.I +++ b/panda/src/putil/copyOnWritePointer.I @@ -102,12 +102,15 @@ CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT : //////////////////////////////////////////////////////////////////// INLINE void CopyOnWritePointer:: operator = (CopyOnWritePointer &&move) NOEXCEPT { - CopyOnWriteObject *old_object = _cow_object; - _cow_object = move._cow_object; - move._cow_object = NULL; + // Protect against self-move-assignment. + if (move._cow_object != _cow_object) { + CopyOnWriteObject *old_object = _cow_object; + _cow_object = move._cow_object; + move._cow_object = NULL; - if (old_object != (CopyOnWriteObject *)NULL) { - cache_unref_delete(old_object); + if (old_object != (CopyOnWriteObject *)NULL) { + cache_unref_delete(old_object); + } } } #endif // USE_MOVE_SEMANTICS