[libcxx-commits] [libcxx] [libcxx] LWG4172 fix self-move-assignment in {unique|shared}_lock (PR #129542)
Mohamed Atef via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Nov 8 04:16:31 PST 2025
https://github.com/elhewaty updated https://github.com/llvm/llvm-project/pull/129542
>From 7b8417e47f602a3bc40287a5f31e8f2f5430f02b Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Tue, 14 Oct 2025 11:13:58 +0300
Subject: [PATCH 1/2] [libcxx] LWG4172 fix self-move-assignment in
{unique|shared}_lock
---
libcxx/include/__mutex/unique_lock.h | 8 +------
libcxx/include/shared_mutex | 9 +-------
.../move_assign.pass.cpp | 23 +++++++++++++------
.../move_assign.pass.cpp | 11 ++++++++-
4 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/libcxx/include/__mutex/unique_lock.h b/libcxx/include/__mutex/unique_lock.h
index aea93eb9b8c9b..5fd50282a3f2a 100644
--- a/libcxx/include/__mutex/unique_lock.h
+++ b/libcxx/include/__mutex/unique_lock.h
@@ -74,13 +74,7 @@ class unique_lock {
}
_LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT {
- if (__owns_)
- __m_->unlock();
-
- __m_ = __u.__m_;
- __owns_ = __u.__owns_;
- __u.__m_ = nullptr;
- __u.__owns_ = false;
+ unique_lock{std::move(__u)}.swap(*this);
return *this;
}
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 8c02e348e4de7..bbcdc6cf554f3 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -340,14 +340,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT {
- if (__owns_)
- __m_->unlock_shared();
- __m_ = nullptr;
- __owns_ = false;
- __m_ = __u.__m_;
- __owns_ = __u.__owns_;
- __u.__m_ = nullptr;
- __u.__owns_ = false;
+ shared_lock{std::move(__u)}.swap(*this);
return *this;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
index 6d7838e8c6c95..b0647f06e4c43 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
@@ -21,22 +21,31 @@
#include "test_macros.h"
-
-int main(int, char**)
-{
- {
+int main(int, char**) {
+ {
typedef std::shared_timed_mutex M;
M m0;
M m1;
std::shared_lock<M> lk0(m0);
std::shared_lock<M> lk1(m1);
+
+ // Test self move assignment for lk0.
+ lk0 = std::move(lk0);
+ assert(lk0.mutex() == std::addressof(m0));
+ assert(lk0.owns_lock() == true);
+
lk1 = std::move(lk0);
assert(lk1.mutex() == std::addressof(m0));
assert(lk1.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
- }
- {
+
+ // Test self move assignment for lk1.
+ lk1 = std::move(lk1);
+ assert(lk1.mutex() == std::addressof(m0));
+ assert(lk1.owns_lock() == true);
+ }
+ {
typedef nasty_mutex M;
M m0;
M m1;
@@ -47,7 +56,7 @@ int main(int, char**)
assert(lk1.owns_lock() == true);
assert(lk0.mutex() == nullptr);
assert(lk0.owns_lock() == false);
- }
+ }
return 0;
}
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
index 588d8332c4164..5b25cb6d5940d 100644
--- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
@@ -24,13 +24,22 @@ int main(int, char**) {
std::unique_lock<checking_mutex> lk0(m0);
std::unique_lock<checking_mutex> lk1(m1);
+ // Test self move assignment for lk0.
+ lk0 = std::move(lk0);
+ assert(lk0.mutex() == std::addressof(m0));
+ assert(lk0.owns_lock() == true);
+
auto& result = (lk1 = std::move(lk0));
assert(&result == &lk1);
assert(lk1.mutex() == std::addressof(m0));
assert(lk1.owns_lock());
assert(lk0.mutex() == nullptr);
- assert(!lk0.owns_lock());
+ assert(lk0.owns_lock() == false);
+ // Test self move assignment for lk1
+ lk1 = std::move(lk1);
+ assert(lk1.mutex() == std::addressof(m0));
+ assert(lk1.owns_lock() == true);
return 0;
}
>From b42e8d70a07ce7dd008abbd5b399df04aafd119f Mon Sep 17 00:00:00 2001
From: Mohamed Atef <mohamedatef1698 at gmail.com>
Date: Sat, 8 Nov 2025 14:15:55 +0200
Subject: [PATCH 2/2] [libcxx] Address comments to fix build failures
---
libcxx/include/__mutex/unique_lock.h | 1 +
libcxx/include/shared_mutex | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/libcxx/include/__mutex/unique_lock.h b/libcxx/include/__mutex/unique_lock.h
index 5fd50282a3f2a..8f023228e9465 100644
--- a/libcxx/include/__mutex/unique_lock.h
+++ b/libcxx/include/__mutex/unique_lock.h
@@ -16,6 +16,7 @@
#include <__mutex/tag_types.h>
#include <__system_error/throw_system_error.h>
#include <__utility/swap.h>
+#include <__utility/move.h>
#include <cerrno>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index bbcdc6cf554f3..f6d3ac0bc981e 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -139,6 +139,7 @@ template <class Mutex>
# include <__mutex/unique_lock.h>
# include <__system_error/throw_system_error.h>
# include <__utility/swap.h>
+# include <__utility/move.h>
# include <cerrno>
# include <version>
@@ -151,6 +152,8 @@ _LIBCPP_PUSH_MACROS
# pragma GCC system_header
# endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_EXPORTED_FROM_ABI __shared_mutex_base {
@@ -430,6 +433,7 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(shared_lock<_Mutex>& __x, shared_lock<_Mu
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
# endif // _LIBCPP_STD_VER >= 14
More information about the libcxx-commits
mailing list