From a69dac7f16f98029694a96aa6a0aad85af7f342c Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 22 Jun 2026 18:40:25 +0000 Subject: [PATCH] Merge pull request 'Fix move-assignment leak and self-assignment in ConflictSet' (#55) from weaselbot/conflict-set:weaselbot/issue-54 into main Reviewed-on: https://git.weaselab.dev/weaselab/conflict-set/pulls/55 --- ConflictSet.cpp | 7 ++++++- HashTable.cpp | 8 +++++++- SkipList.cpp | 7 ++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index d9d4408..4ded851 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -3648,7 +3648,12 @@ ConflictSet::ConflictSet(ConflictSet &&other) noexcept : impl(std::exchange(other.impl, nullptr)) {} ConflictSet &ConflictSet::operator=(ConflictSet &&other) noexcept { - impl = std::exchange(other.impl, nullptr); + if (this != &other) { + if (impl) { + internal_destroy(impl); + } + impl = std::exchange(other.impl, nullptr); + } return *this; } diff --git a/HashTable.cpp b/HashTable.cpp index e3fa477..f76e8c2 100644 --- a/HashTable.cpp +++ b/HashTable.cpp @@ -119,7 +119,13 @@ ConflictSet::ConflictSet(ConflictSet &&other) noexcept : impl(std::exchange(other.impl, nullptr)) {} ConflictSet &ConflictSet::operator=(ConflictSet &&other) noexcept { - impl = std::exchange(other.impl, nullptr); + if (this != &other) { + if (impl) { + impl->~Impl(); + safe_free(impl, sizeof(Impl)); + } + impl = std::exchange(other.impl, nullptr); + } return *this; } diff --git a/SkipList.cpp b/SkipList.cpp index e0bf4e1..98d8a9b 100644 --- a/SkipList.cpp +++ b/SkipList.cpp @@ -903,7 +903,12 @@ ConflictSet::ConflictSet(ConflictSet &&other) noexcept : impl(std::exchange(other.impl, nullptr)) {} ConflictSet &ConflictSet::operator=(ConflictSet &&other) noexcept { - impl = std::exchange(other.impl, nullptr); + if (this != &other) { + if (impl) { + internal_destroy(impl); + } + impl = std::exchange(other.impl, nullptr); + } return *this; }