[libcxx] LWG4172 fix self-move-assignment in {unique|shared}_lock (#129542)
Fixes: https://github.com/llvm/llvm-project/issues/127861 --------- Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This commit is contained in:
parent
d5326411fe
commit
2c98c6ee0e
@ -113,7 +113,7 @@
|
||||
"","","","","","",""
|
||||
"`LWG3578 <https://wg21.link/LWG3578>`__","Iterator SCARYness in the context of associative container merging","2025-02 (Hagenberg)","","","`#127859 <https://github.com/llvm/llvm-project/issues/127859>`__",""
|
||||
"`LWG3956 <https://wg21.link/LWG3956>`__","``chrono::parse`` uses ``from_stream`` as a customization point","2025-02 (Hagenberg)","","","`#127860 <https://github.com/llvm/llvm-project/issues/127860>`__",""
|
||||
"`LWG4172 <https://wg21.link/LWG4172>`__","``unique_lock`` self-move-assignment is broken","2025-02 (Hagenberg)","","","`#127861 <https://github.com/llvm/llvm-project/issues/127861>`__",""
|
||||
"`LWG4172 <https://wg21.link/LWG4172>`__","``unique_lock`` self-move-assignment is broken","2025-02 (Hagenberg)","|Complete|","22","`#127861 <https://github.com/llvm/llvm-project/issues/127861>`__",""
|
||||
"`LWG4175 <https://wg21.link/LWG4175>`__","``get_env()`` specified in terms of ``as_const()`` but this doesn't work with rvalue senders","2025-02 (Hagenberg)","","","`#127862 <https://github.com/llvm/llvm-project/issues/127862>`__",""
|
||||
"`LWG4179 <https://wg21.link/LWG4179>`__","Wrong range in ``[alg.search]``","2025-02 (Hagenberg)","","","`#127863 <https://github.com/llvm/llvm-project/issues/127863>`__",""
|
||||
"`LWG4186 <https://wg21.link/LWG4186>`__","``regex_traits::transform_primary`` mistakenly detects ``typeid`` of a function","2025-02 (Hagenberg)","","","`#127864 <https://github.com/llvm/llvm-project/issues/127864>`__",""
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <__memory/addressof.h>
|
||||
#include <__mutex/tag_types.h>
|
||||
#include <__system_error/throw_system_error.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/swap.h>
|
||||
#include <cerrno>
|
||||
|
||||
@ -22,6 +23,9 @@
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Mutex>
|
||||
@ -74,13 +78,8 @@ public:
|
||||
}
|
||||
|
||||
_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;
|
||||
if (this != std::addressof(__u))
|
||||
unique_lock(std::move(__u)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -170,4 +169,6 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mu
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H
|
||||
|
||||
@ -138,6 +138,7 @@ template <class Mutex>
|
||||
# include <__mutex/tag_types.h>
|
||||
# include <__mutex/unique_lock.h>
|
||||
# include <__system_error/throw_system_error.h>
|
||||
# include <__utility/move.h>
|
||||
# include <__utility/swap.h>
|
||||
# include <cerrno>
|
||||
# include <version>
|
||||
@ -340,14 +341,8 @@ 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;
|
||||
if (this != std::addressof(__u))
|
||||
shared_lock(std::move(__u)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
||||
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
|
||||
|
||||
// UNSUPPORTED: no-threads
|
||||
// UNSUPPORTED: c++03, c++11
|
||||
|
||||
@ -13,18 +15,17 @@
|
||||
|
||||
// template <class Mutex> class shared_lock;
|
||||
|
||||
// shared_lock& operator=(shared_lock&& u);
|
||||
// shared_lock& operator=(shared_lock&& u) noexcept;
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <cassert>
|
||||
#include "nasty_containers.h"
|
||||
#include <shared_mutex>
|
||||
#include <type_traits>
|
||||
|
||||
#include "nasty_containers.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
int main(int, char**) {
|
||||
{
|
||||
typedef std::shared_timed_mutex M;
|
||||
M m0;
|
||||
M m1;
|
||||
@ -35,8 +36,10 @@ int main(int, char**)
|
||||
assert(lk1.owns_lock() == true);
|
||||
assert(lk0.mutex() == nullptr);
|
||||
assert(lk0.owns_lock() == false);
|
||||
}
|
||||
{
|
||||
|
||||
static_assert(std::is_nothrow_move_assignable<std::shared_lock<M> >::value, "");
|
||||
}
|
||||
{
|
||||
typedef nasty_mutex M;
|
||||
M m0;
|
||||
M m1;
|
||||
@ -47,7 +50,18 @@ int main(int, char**)
|
||||
assert(lk1.owns_lock() == true);
|
||||
assert(lk0.mutex() == nullptr);
|
||||
assert(lk0.owns_lock() == false);
|
||||
}
|
||||
|
||||
static_assert(std::is_nothrow_move_assignable<std::shared_lock<M> >::value, "");
|
||||
}
|
||||
{
|
||||
// Test self move-assignment (LWG4172)
|
||||
typedef std::shared_timed_mutex M;
|
||||
M m0;
|
||||
std::shared_lock<M> lk0(m0);
|
||||
lk0 = std::move(lk0);
|
||||
assert(lk0.mutex() == std::addressof(m0));
|
||||
assert(lk0.owns_lock() == true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6,31 +6,52 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
|
||||
|
||||
// <mutex>
|
||||
|
||||
// template <class Mutex> class unique_lock;
|
||||
|
||||
// unique_lock& operator=(unique_lock&& u);
|
||||
// unique_lock& operator=(unique_lock&& u) noexcept;
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
|
||||
#include "checking_mutex.h"
|
||||
|
||||
int main(int, char**) {
|
||||
checking_mutex m0;
|
||||
checking_mutex m1;
|
||||
std::unique_lock<checking_mutex> lk0(m0);
|
||||
std::unique_lock<checking_mutex> lk1(m1);
|
||||
{
|
||||
checking_mutex m0;
|
||||
checking_mutex m1;
|
||||
std::unique_lock<checking_mutex> lk0(m0);
|
||||
std::unique_lock<checking_mutex> lk1(m1);
|
||||
|
||||
auto& result = (lk1 = std::move(lk0));
|
||||
// Test self move assignment for lk0.
|
||||
lk0 = std::move(lk0);
|
||||
assert(lk0.mutex() == std::addressof(m0));
|
||||
assert(lk0.owns_lock() == true);
|
||||
|
||||
assert(&result == &lk1);
|
||||
assert(lk1.mutex() == std::addressof(m0));
|
||||
assert(lk1.owns_lock());
|
||||
assert(lk0.mutex() == nullptr);
|
||||
assert(!lk0.owns_lock());
|
||||
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() == false);
|
||||
|
||||
static_assert(std::is_nothrow_move_assignable<std::unique_lock<checking_mutex> >::value, "");
|
||||
}
|
||||
|
||||
{
|
||||
// Test self move-assignment (LWG4172)
|
||||
checking_mutex m0;
|
||||
std::unique_lock<checking_mutex> lk0(m0);
|
||||
lk0 = std::move(lk0);
|
||||
assert(lk0.mutex() == std::addressof(m0));
|
||||
assert(lk0.owns_lock() == true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user