From 0b54e792b7b31e44a58b53938bc73b87bbcd897f Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 14 Mar 2016 23:07:32 +0000 Subject: [PATCH] Implement LWG2577: {shared,unique}_lock should use std::addressof llvm-svn: 263506 --- libcxx/include/__mutex_base | 12 ++++----- libcxx/include/shared_mutex | 12 ++++----- .../move_assign.pass.cpp | 26 ++++++++++++++---- .../move_ctor.pass.cpp | 22 ++++++++++++--- .../mutex_adopt_lock.pass.cpp | 20 +++++++++++--- .../mutex_defer_lock.pass.cpp | 17 +++++++++--- .../copy_assign.fail.cpp | 12 +++++---- .../copy_ctor.fail.cpp | 10 ++++--- .../move_assign.pass.cpp | 27 ++++++++++++++----- .../move_ctor.pass.cpp | 23 ++++++++++++---- .../mutex_adopt_lock.pass.cpp | 18 ++++++++++--- .../mutex_defer_lock.pass.cpp | 17 +++++++++--- libcxx/www/cxx1z_status.html | 2 +- 13 files changed, 163 insertions(+), 55 deletions(-) diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index b019b4760d18..6165023d2963 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -109,24 +109,24 @@ public: unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY explicit unique_lock(mutex_type& __m) - : __m_(&__m), __owns_(true) {__m_->lock();} + : __m_(addressof(__m)), __owns_(true) {__m_->lock();} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), __owns_(false) {} + : __m_(addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), __owns_(__m.try_lock()) {} + : __m_(addressof(__m)), __owns_(__m.try_lock()) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), __owns_(true) {} + : __m_(addressof(__m)), __owns_(true) {} template _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) - : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} + : __m_(addressof(__m)), __owns_(__m.try_lock_until(__t)) {} template _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) - : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} + : __m_(addressof(__m)), __owns_(__m.try_lock_for(__d)) {} _LIBCPP_INLINE_VISIBILITY ~unique_lock() { diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex index dcb93949e30d..45e7fd0677af 100644 --- a/libcxx/include/shared_mutex +++ b/libcxx/include/shared_mutex @@ -319,25 +319,25 @@ public: _LIBCPP_INLINE_VISIBILITY explicit shared_lock(mutex_type& __m) - : __m_(&__m), + : __m_(addressof(__m)), __owns_(true) {__m_->lock_shared();} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), + : __m_(addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), + : __m_(addressof(__m)), __owns_(__m.try_lock_shared()) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), + : __m_(addressof(__m)), __owns_(true) {} @@ -345,7 +345,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) - : __m_(&__m), + : __m_(addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {} @@ -353,7 +353,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) - : __m_(&__m), + : __m_(addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {} 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 15c193c60b5d..bd707bb90ce1 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 @@ -18,17 +18,33 @@ #include #include +#include "nasty_containers.hpp" -std::shared_timed_mutex m0; -std::shared_timed_mutex m1; int main() { - std::shared_lock lk0(m0); - std::shared_lock lk1(m1); + { + typedef std::shared_timed_mutex M; + M m0; + M m1; + std::shared_lock lk0(m0); + std::shared_lock lk1(m1); lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0)); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m0; + M m1; + std::shared_lock lk0(m0); + std::shared_lock lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp index 4f4f6a5e9fbd..c29a3fb04d0f 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp @@ -18,14 +18,28 @@ #include #include +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock lk0(m); - std::shared_lock lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::shared_lock lk0(m); + std::shared_lock lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::shared_lock lk0(m); + std::shared_lock lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp index 995210221065..341f0ce7efd2 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp @@ -18,12 +18,24 @@ #include #include +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - m.lock_shared(); - std::shared_lock lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + m.lock(); + std::unique_lock lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp index d81796b95bf3..5fbb7244ef8e 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp @@ -18,11 +18,22 @@ #include #include +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::unique_lock lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp index 4f477449d6a2..8d864ea8e7da 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp @@ -16,16 +16,18 @@ #include #include -std::mutex m0; -std::mutex m1; - int main() { - std::unique_lock lk0(m0); - std::unique_lock lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock lk0(m0); + std::unique_lock lk1(m1); lk1 = lk0; assert(lk1.mutex() == &m0); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp index 4888fe90d92c..067302127cad 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp @@ -16,14 +16,16 @@ #include #include -std::mutex m; - int main() { - std::unique_lock lk0(m); - std::unique_lock lk = lk0; + { + typedef std::mutex M; + M m; + std::unique_lock lk0(m); + std::unique_lock lk = lk0; assert(lk.mutex() == &m); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } } 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 4dff853088ac..e5db685e46e7 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 @@ -17,19 +17,34 @@ #include #include - -std::mutex m0; -std::mutex m1; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock lk0(m0); - std::unique_lock lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock lk0(m0); + std::unique_lock lk1(m1); lk1 = std::move(lk0); - assert(lk1.mutex() == &m0); + assert(lk1.mutex() == std::addressof(m0)); assert(lk1.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m0; + M m1; + std::unique_lock lk0(m0); + std::unique_lock lk1(m1); + lk1 = std::move(lk0); + assert(lk1.mutex() == std::addressof(m0)); + assert(lk1.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp index aa640ee6d746..427deabc5a59 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp @@ -17,17 +17,30 @@ #include #include - -std::mutex m; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock lk0(m); - std::unique_lock lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock lk0(m); + std::unique_lock lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock lk0(m); + std::unique_lock lk = std::move(lk0); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + assert(lk0.mutex() == nullptr); + assert(lk0.owns_lock() == false); + } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp index 9c3a7b6505a4..20f7d249b6f4 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp @@ -17,12 +17,24 @@ #include #include +#include "nasty_containers.hpp" int main() { - std::mutex m; + { + typedef std::mutex M; + M m; m.lock(); - std::unique_lock lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + std::unique_lock lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == true); + } + { + typedef nasty_mutex M; + M m; + m.lock(); + std::unique_lock lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp index bf622311f013..242dacb1eb92 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp @@ -17,11 +17,22 @@ #include #include +#include "nasty_containers.hpp" int main() { - std::mutex m; - std::unique_lock lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); assert(lk.owns_lock() == false); + } + { + typedef nasty_mutex M; + M m; + std::unique_lock lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } diff --git a/libcxx/www/cxx1z_status.html b/libcxx/www/cxx1z_status.html index 0445145d86f0..0b9023b7e29f 100644 --- a/libcxx/www/cxx1z_status.html +++ b/libcxx/www/cxx1z_status.html @@ -223,7 +223,7 @@ 2574[fund.ts.v2] std::experimental::function::operator=(F&&) should be constrainedJacksonville 2575[fund.ts.v2] experimental::function::assign should be removedJacksonville 2576istream_iterator and ostream_iterator should use std::addressofJacksonville - 2577{shared,unique}_lock should use std::addressofJacksonville + 2577{shared,unique}_lock should use std::addressofJacksonvilleComplete 2579Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assignJacksonvilleComplete 2581Specialization of <type_traits> variable templates should be prohibitedJacksonvilleComplete 2582§[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traitsJacksonville