Skip to content

Commit 673a83a

Browse files
committed
[libcxx] LWG4172 fix self-move-assignment in {unique|shared}_lock
1 parent 4a8dd49 commit 673a83a

File tree

4 files changed

+28
-23
lines changed

4 files changed

+28
-23
lines changed

libcxx/include/__mutex/unique_lock.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,7 @@ class unique_lock {
7474
}
7575

7676
_LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT {
77-
if (__owns_)
78-
__m_->unlock();
79-
80-
__m_ = __u.__m_;
81-
__owns_ = __u.__owns_;
82-
__u.__m_ = nullptr;
83-
__u.__owns_ = false;
77+
unique_lock{std::move(__u)}.swap(*this);
8478
return *this;
8579
}
8680

libcxx/include/shared_mutex

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,7 @@ public:
340340
}
341341

342342
_LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT {
343-
if (__owns_)
344-
__m_->unlock_shared();
345-
__m_ = nullptr;
346-
__owns_ = false;
347-
__m_ = __u.__m_;
348-
__owns_ = __u.__owns_;
349-
__u.__m_ = nullptr;
350-
__u.__owns_ = false;
343+
shared_lock{std::move(__u)}.swap(*this);
351344
return *this;
352345
}
353346

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,31 @@
2121

2222
#include "test_macros.h"
2323

24-
25-
int main(int, char**)
26-
{
27-
{
24+
int main(int, char**) {
25+
{
2826
typedef std::shared_timed_mutex M;
2927
M m0;
3028
M m1;
3129
std::shared_lock<M> lk0(m0);
3230
std::shared_lock<M> lk1(m1);
31+
32+
// Test self move assignment for lk0.
33+
lk0 = std::move(lk0);
34+
assert(lk0.mutex() == std::addressof(m0));
35+
assert(lk0.owns_lock() == true);
36+
3337
lk1 = std::move(lk0);
3438
assert(lk1.mutex() == std::addressof(m0));
3539
assert(lk1.owns_lock() == true);
3640
assert(lk0.mutex() == nullptr);
3741
assert(lk0.owns_lock() == false);
38-
}
39-
{
42+
43+
// Test self move assignment for lk1.
44+
lk1 = std::move(lk1);
45+
assert(lk1.mutex() == std::addressof(m0));
46+
assert(lk1.owns_lock() == true);
47+
}
48+
{
4049
typedef nasty_mutex M;
4150
M m0;
4251
M m1;
@@ -47,7 +56,7 @@ int main(int, char**)
4756
assert(lk1.owns_lock() == true);
4857
assert(lk0.mutex() == nullptr);
4958
assert(lk0.owns_lock() == false);
50-
}
59+
}
5160

5261
return 0;
5362
}

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,22 @@ int main(int, char**) {
2424
std::unique_lock<checking_mutex> lk0(m0);
2525
std::unique_lock<checking_mutex> lk1(m1);
2626

27+
// Test self move assignment for lk0.
28+
lk0 = std::move(lk0);
29+
assert(lk0.mutex() == std::addressof(m0));
30+
assert(lk0.owns_lock() == true);
31+
2732
auto& result = (lk1 = std::move(lk0));
2833

2934
assert(&result == &lk1);
3035
assert(lk1.mutex() == std::addressof(m0));
3136
assert(lk1.owns_lock());
3237
assert(lk0.mutex() == nullptr);
33-
assert(!lk0.owns_lock());
38+
assert(lk0.owns_lock() == false);
3439

40+
// Test self move assignment for lk1
41+
lk1 = std::move(lk1);
42+
assert(lk1.mutex() == std::addressof(m0));
43+
assert(lk1.owns_lock() == true);
3544
return 0;
3645
}

0 commit comments

Comments
 (0)