diff options
Diffstat (limited to 'libcxx/test/std')
8 files changed, 410 insertions, 28 deletions
diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp index 246eb935c99..520c9730bdf 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: libcpp-has-no-threads + // <mutex> // template <class Mutex> class lock_guard; @@ -14,35 +16,9 @@ // explicit lock_guard(mutex_type& m); #include <mutex> -#include <thread> -#include <cstdlib> -#include <cassert> - -std::mutex m; - -typedef std::chrono::system_clock Clock; -typedef Clock::time_point time_point; -typedef Clock::duration duration; -typedef std::chrono::milliseconds ms; -typedef std::chrono::nanoseconds ns; - -void f() -{ - time_point t0 = Clock::now(); - time_point t1; - { - std::lock_guard<std::mutex> lg = m; - t1 = Clock::now(); - } - ns d = t1 - t0 - ms(250); - assert(d < ns(2500000)); // within 2.5ms -} int main() { - m.lock(); - std::thread t(f); - std::this_thread::sleep_for(ms(250)); - m.unlock(); - t.join(); + std::mutex m; + std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}} } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp new file mode 100644 index 00000000000..0de002a2a42 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard(Mutex&..., adopt_lock_t); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <cassert> + +struct TestMutex { + bool locked = false; + TestMutex() = default; + + void lock() { assert(!locked); locked = true; } + bool try_lock() { if (locked) return false; return locked = true; } + void unlock() { assert(locked); locked = false; } + + TestMutex(TestMutex const&) = delete; + TestMutex& operator=(TestMutex const&) = delete; +}; + +int main() +{ + { + using LG = std::lock_guard<>; + LG lg(std::adopt_lock); + } + { + TestMutex m1, m2; + using LG = std::lock_guard<TestMutex, TestMutex>; + m1.lock(); m2.lock(); + { + LG lg(m1, m2, std::adopt_lock); + assert(m1.locked && m2.locked); + } + assert(!m1.locked && !m2.locked); + } + { + TestMutex m1, m2, m3; + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>; + m1.lock(); m2.lock(); m3.lock(); + { + LG lg(m1, m2, m3, std::adopt_lock); + assert(m1.locked && m2.locked && m3.locked); + } + assert(!m1.locked && !m2.locked && !m3.locked); + } + +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp new file mode 100644 index 00000000000..18193e000ed --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard& operator=(lock_guard const&) = delete; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + M om0, om1, om2; + { + using LG = std::lock_guard<>; + LG lg1, lg2; + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } + { + using LG = std::lock_guard<M, M>; + LG lg1(m0, m1); + LG lg2(om0, om1); + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } + { + using LG = std::lock_guard<M, M, M>; + LG lg1(m0, m1, m2); + LG lg2(om0, om1, om2); + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp new file mode 100644 index 00000000000..6dc37e970fb --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// lock_guard(lock_guard const&) = delete; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + { + using LG = std::lock_guard<>; + const LG Orig; + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } + { + using LG = std::lock_guard<M, M>; + const LG Orig(m0, m1); + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } + { + using LG = std::lock_guard<M, M, M>; + const LG Orig(m0, m1, m2); + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp new file mode 100644 index 00000000000..866538a2834 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// explicit lock_guard(Mutex&...); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> + +template <class LG> +void test_conversion(LG) {} + +int main() +{ + using M = std::mutex; + M m0, m1, m2; + M n0, n1, n2; + { + using LG = std::lock_guard<>; + LG lg = {}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({}); // expected-error{{no matching function for call}} + ((void)lg); + } + { + using LG = std::lock_guard<M, M>; + LG lg = {m0, m1}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({n0, n1}); // expected-error{{no matching function for call}} + ((void)lg); + } + { + using LG = std::lock_guard<M, M, M>; + LG lg = {m0, m1, m2}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion<LG>({n0, n1, n2}); // expected-error{{no matching function for call}} + } +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp new file mode 100644 index 00000000000..d63dc12909d --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// explicit lock_guard(mutex_type& m); + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <cassert> + +struct TestMutex { + bool locked = false; + TestMutex() = default; + ~TestMutex() { assert(!locked); } + + void lock() { assert(!locked); locked = true; } + bool try_lock() { if (locked) return false; return locked = true; } + void unlock() { assert(locked); locked = false; } + + TestMutex(TestMutex const&) = delete; + TestMutex& operator=(TestMutex const&) = delete; +}; + +#if !defined(TEST_HAS_NO_EXCEPTIONS) +struct TestMutexThrows { + bool locked = false; + bool throws_on_lock = false; + + TestMutexThrows() = default; + ~TestMutexThrows() { assert(!locked); } + + void lock() { + assert(!locked); + if (throws_on_lock) { + throw 42; + } + locked = true; + } + + bool try_lock() { + if (locked) return false; + lock(); + return true; + } + + void unlock() { assert(locked); locked = false; } + + TestMutexThrows(TestMutexThrows const&) = delete; + TestMutexThrows& operator=(TestMutexThrows const&) = delete; +}; +#endif // !defined(TEST_HAS_NO_EXCEPTIONS) + +int main() +{ + { + using LG = std::lock_guard<>; + LG lg; + } + { + using LG = std::lock_guard<TestMutex, TestMutex>; + TestMutex m1, m2; + { + LG lg(m1, m2); + assert(m1.locked && m2.locked); + } + assert(!m1.locked && !m2.locked); + } + { + using LG = std::lock_guard<TestMutex, TestMutex, TestMutex>; + TestMutex m1, m2, m3; + { + LG lg(m1, m2, m3); + assert(m1.locked && m2.locked && m3.locked); + } + assert(!m1.locked && !m2.locked && !m3.locked); + } +#if !defined(TEST_HAS_NO_EXCEPTIONS) + { + using MT = TestMutexThrows; + using LG = std::lock_guard<MT, MT>; + MT m1, m2; + m1.throws_on_lock = true; + try { + LG lg(m1, m2); + assert(false); + } catch (int) {} + assert(!m1.locked && !m2.locked); + } + { + using MT = TestMutexThrows; + using LG = std::lock_guard<MT, MT, MT>; + MT m1, m2, m3; + m2.throws_on_lock = true; + try { + LG lg(m1, m2, m3); + assert(false); + } catch (int) {} + assert(!m1.locked && !m2.locked && !m3.locked); + } +#endif +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp new file mode 100644 index 00000000000..3c134e0b886 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <mutex> + +// template <class ...Mutex> class lock_guard; + +// Test that the variadic lock guard implementation compiles in all standard +// dialects, including C++03, even though it is forward declared using +// variadic templates. + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include "mutex.pass.cpp" // Use the existing non-variadic test diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp new file mode 100644 index 00000000000..2b06742a673 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <mutex> + +// template <class Mutex> +// class lock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include <mutex> +#include <type_traits> + +struct NAT {}; + +template <class LG> +auto test_typedef(int) -> typename LG::mutex_type; + +template <class LG> +auto test_typedef(...) -> NAT; + +template <class LG> +constexpr bool has_mutex_type() { + return !std::is_same<decltype(test_typedef<LG>(0)), NAT>::value; +} + +int main() +{ + { + using T = std::lock_guard<>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using T = std::lock_guard<M1>; + static_assert(std::is_same<T::mutex_type, M1>::value, ""); + } + { + using M1 = std::recursive_mutex; + using T = std::lock_guard<M1>; + static_assert(std::is_same<T::mutex_type, M1>::value, ""); + } + { + using M1 = std::mutex; + using M2 = std::recursive_mutex; + using T = std::lock_guard<M1, M2>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using M2 = std::recursive_mutex; + using T = std::lock_guard<M1, M1, M2>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::mutex; + using T = std::lock_guard<M1, M1>; + static_assert(!has_mutex_type<T>(), ""); + } + { + using M1 = std::recursive_mutex; + using T = std::lock_guard<M1, M1, M1>; + static_assert(!has_mutex_type<T>(), ""); + } +} |