Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions stl/inc/mutex
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,8 @@ public:
_Other._Owns = false;
}

unique_lock& operator=(unique_lock&& _Other) noexcept /* strengthened */ {
if (this != _STD addressof(_Other)) {
if (_Owns) {
_Pmtx->unlock();
}

_Pmtx = _Other._Pmtx;
_Owns = _Other._Owns;
_Other._Pmtx = nullptr;
_Other._Owns = false;
}
unique_lock& operator=(unique_lock&& _Other) noexcept {
unique_lock{_STD move(_Other)}.swap(*this);
return *this;
}

Expand Down
9 changes: 1 addition & 8 deletions stl/inc/shared_mutex
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,7 @@ public:
}

shared_lock& operator=(shared_lock&& _Right) noexcept {
if (_Owns) {
_Pmtx->unlock_shared();
}

_Pmtx = _Right._Pmtx;
_Owns = _Right._Owns;
_Right._Pmtx = nullptr;
_Right._Owns = false;
shared_lock{_STD move(_Right)}.swap(*this);
return *this;
}

Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ tests\LWG3561_discard_block_engine_counter
tests\LWG3610_iota_view_size_and_integer_class
tests\LWG4084_iostream_uppercase_inf_nan
tests\LWG4105_ranges_ends_with_and_integer_class
tests\LWG4172_unique_lock_self_move_assignment
tests\P0009R18_mdspan_default_accessor
tests\P0009R18_mdspan_extents
tests\P0009R18_mdspan_extents_death
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\impure_matrix.lst
111 changes: 111 additions & 0 deletions tests/std/tests/LWG4172_unique_lock_self_move_assignment/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <mutex>
#include <shared_mutex>
#include <utility>

using namespace std;

struct lockable_with_counters {
void lock() {
++lock_count;
}

void unlock() {
++unlock_count;
}

void lock_shared() {
++shared_lock_count;
}

void unlock_shared() {
++shared_unlock_count;
}

int lock_count = 0;
int unlock_count = 0;
int shared_lock_count = 0;
int shared_unlock_count = 0;
};

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-move"
#endif // __clang__
#pragma warning(push)
#pragma warning(disable : 26800) // use a moved-from object
int main() {
lockable_with_counters lockable1;
lockable_with_counters lockable2;

{
unique_lock<lockable_with_counters> lock_a(lockable1);
assert(lockable1.lock_count == 1);
assert(lockable1.unlock_count == 0);

lock_a = move(lock_a);
assert(lockable1.lock_count == 1);
assert(lockable1.unlock_count == 0);
{
unique_lock<lockable_with_counters> lock_b(lockable2);
assert(lockable2.lock_count == 1);
assert(lockable2.unlock_count == 0);

lock_a = move(lock_b);

assert(lockable1.lock_count == 1);
assert(lockable1.unlock_count == 1);
assert(lockable2.lock_count == 1);
assert(lockable2.unlock_count == 0);
}

assert(lockable1.lock_count == 1);
assert(lockable1.unlock_count == 1);
assert(lockable2.lock_count == 1);
assert(lockable2.unlock_count == 0);
}

assert(lockable1.lock_count == 1);
assert(lockable1.unlock_count == 1);
assert(lockable2.lock_count == 1);
assert(lockable2.unlock_count == 1);

{
shared_lock<lockable_with_counters> lock_a(lockable1);
assert(lockable1.shared_lock_count == 1);
assert(lockable1.shared_unlock_count == 0);

lock_a = move(lock_a);
assert(lockable1.shared_lock_count == 1);
assert(lockable1.shared_unlock_count == 0);
{
shared_lock<lockable_with_counters> lock_b(lockable2);
assert(lockable2.shared_lock_count == 1);
assert(lockable2.shared_unlock_count == 0);

lock_a = move(lock_b);

assert(lockable1.shared_lock_count == 1);
assert(lockable1.shared_unlock_count == 1);
assert(lockable2.shared_lock_count == 1);
assert(lockable2.shared_unlock_count == 0);
}

assert(lockable1.shared_lock_count == 1);
assert(lockable1.shared_unlock_count == 1);
assert(lockable2.shared_lock_count == 1);
assert(lockable2.shared_unlock_count == 0);
}

assert(lockable1.shared_lock_count == 1);
assert(lockable1.shared_unlock_count == 1);
assert(lockable2.shared_lock_count == 1);
assert(lockable2.shared_unlock_count == 1);
}
#pragma warning(pop)
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__