diff options
Diffstat (limited to 'test/std/thread')
62 files changed, 766 insertions, 491 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp index 2c1313b7a2f0f..5cb824d482240 100644 --- a/test/std/thread/futures/futures.async/async.pass.cpp +++ b/test/std/thread/futures/futures.async/async.pass.cpp @@ -21,15 +21,22 @@ // future<typename result_of<F(Args...)>::type> // async(launch policy, F&& f, Args&&... args); + #include <future> +#include <atomic> #include <memory> #include <cassert> +#include "test_macros.h" + typedef std::chrono::high_resolution_clock Clock; typedef std::chrono::milliseconds ms; +std::atomic_bool invoked = ATOMIC_VAR_INIT(false); + int f0() { + invoked = true; std::this_thread::sleep_for(ms(200)); return 3; } @@ -38,163 +45,109 @@ int i = 0; int& f1() { + invoked = true; std::this_thread::sleep_for(ms(200)); return i; } void f2() { + invoked = true; std::this_thread::sleep_for(ms(200)); } -std::unique_ptr<int> f3(int i) +std::unique_ptr<int> f3(int j) { + invoked = true; std::this_thread::sleep_for(ms(200)); - return std::unique_ptr<int>(new int(i)); + return std::unique_ptr<int>(new int(j)); } std::unique_ptr<int> f4(std::unique_ptr<int>&& p) { + invoked = true; std::this_thread::sleep_for(ms(200)); return std::move(p); } -void f5(int i) +void f5(int j) { std::this_thread::sleep_for(ms(200)); - throw i; + throw j; } -int main() -{ - { - std::future<int> f = std::async(f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::async, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::any, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int> f = std::async(std::launch::deferred, f0); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } +template <class Ret, class CheckLamdba, class ...Args> +void test(CheckLamdba&& getAndCheckFn, bool IsDeferred, Args&&... args) { + // Reset global state. + invoked = false; - { - std::future<int&> f = std::async(f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::async, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::any, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<int&> f = std::async(std::launch::deferred, f1); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(&f.get() == &i); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); - } + // Create the future and wait + std::future<Ret> f = std::async(std::forward<Args>(args)...); + std::this_thread::sleep_for(ms(300)); - { - std::future<void> f = std::async(f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); - } - { - std::future<void> f = std::async(std::launch::async, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); + // Check that deferred async's have not invoked the function. + assert(invoked == !IsDeferred); + + // Time the call to f.get() and check that the returned value matches + // what is expected. + Clock::time_point t0 = Clock::now(); + assert(getAndCheckFn(f)); + Clock::time_point t1 = Clock::now(); + + // If the async is deferred it should take more than 100ms, otherwise + // it should take less than 100ms. + if (IsDeferred) { + assert(t1-t0 > ms(100)); + } else { assert(t1-t0 < ms(100)); } +} + +int main() +{ + // The default launch policy is implementation defined. libc++ defines + // it to be std::launch::async. + bool DefaultPolicyIsDeferred = false; + bool DPID = DefaultPolicyIsDeferred; + + std::launch AnyPolicy = std::launch::async | std::launch::deferred; + LIBCPP_ASSERT(AnyPolicy == std::launch::any); + { - std::future<void> f = std::async(std::launch::any, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; + test<int>(checkInt, DPID, f0); + test<int>(checkInt, false, std::launch::async, f0); + test<int>(checkInt, true, std::launch::deferred, f0); + test<int>(checkInt, DPID, AnyPolicy, f0); } { - std::future<void> f = std::async(std::launch::deferred, f2); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - f.get(); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 > ms(100)); + auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; + test<int&>(checkIntRef, DPID, f1); + test<int&>(checkIntRef, false, std::launch::async, f1); + test<int&>(checkIntRef, true, std::launch::deferred, f1); + test<int&>(checkIntRef, DPID, AnyPolicy, f1); } - { - std::future<std::unique_ptr<int>> f = std::async(f3, 3); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; + test<void>(checkVoid, DPID, f2); + test<void>(checkVoid, false, std::launch::async, f2); + test<void>(checkVoid, true, std::launch::deferred, f2); + test<void>(checkVoid, DPID, AnyPolicy, f2); } - { - std::future<std::unique_ptr<int>> f = - std::async(f4, std::unique_ptr<int>(new int(3))); - std::this_thread::sleep_for(ms(300)); - Clock::time_point t0 = Clock::now(); - assert(*f.get() == 3); - Clock::time_point t1 = Clock::now(); - assert(t1-t0 < ms(100)); + using Ret = std::unique_ptr<int>; + auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; + test<Ret>(checkUPtr, DPID, f3, 3); + test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); } - { std::future<void> f = std::async(f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - { std::future<void> f = std::async(std::launch::deferred, f5, 3); std::this_thread::sleep_for(ms(300)); - try { f.get(); assert (false); } catch ( int ex ) {} + try { f.get(); assert (false); } catch ( int ) {} } - } diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp index 1e6fcb76a0e73..06397487a7344 100644 --- a/test/std/thread/futures/futures.overview/future_errc.pass.cpp +++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp @@ -9,22 +9,32 @@ // // UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 +// Libc++'s enum class emulation does not allow static_cast<Enum>(0) to work. + // <future> // enum class future_errc // { -// future_already_retrieved = 1, -// promise_already_satisfied, -// no_state -// broken_promise, +// broken_promise = implementation-defined, +// future_already_retrieved = implementation-defined, +// promise_already_satisfied = implementation-defined, +// no_state = implementation-defined // }; #include <future> int main() { - static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, ""); - static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, ""); - static_assert(static_cast<int>(std::future_errc::no_state) == 3, ""); - static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::future_already_retrieved, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::promise_already_satisfied, ""); + static_assert(std::future_errc::broken_promise != std::future_errc::no_state, ""); + static_assert(std::future_errc::future_already_retrieved != std::future_errc::promise_already_satisfied, ""); + static_assert(std::future_errc::future_already_retrieved != std::future_errc::no_state, ""); + static_assert(std::future_errc::promise_already_satisfied != std::future_errc::no_state, ""); + + static_assert(std::future_errc::broken_promise != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::future_already_retrieved != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::promise_already_satisfied != static_cast<std::future_errc>(0), ""); + static_assert(std::future_errc::no_state != static_cast<std::future_errc>(0), ""); } diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp index da54f7ee67329..a26b01f67b3e7 100644 --- a/test/std/thread/futures/futures.overview/launch.pass.cpp +++ b/test/std/thread/futures/futures.overview/launch.pass.cpp @@ -15,28 +15,30 @@ // { // async = 1, // deferred = 2, -// any = async | deferred +// any = async | deferred /* EXTENSION */ // }; #include <future> #include <cassert> +#include "test_macros.h" + int main() { #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS - static_assert(static_cast<int>(std::launch::any) == + LIBCPP_STATIC_ASSERT(static_cast<int>(std::launch::any) == (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), ""); #else - static_assert(std::launch::any == (std::launch::async | std::launch::deferred), ""); + LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async | std::launch::deferred), ""); static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), ""); - static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); - static_assert(std::launch::deferred == ~std::launch::async, ""); + LIBCPP_STATIC_ASSERT(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); + LIBCPP_STATIC_ASSERT(std::launch::deferred == ~std::launch::async, ""); std::launch x = std::launch::async; x &= std::launch::deferred; assert(x == std::launch(0)); x = std::launch::async; x |= std::launch::deferred; - assert(x == std::launch::any); + LIBCPP_ASSERT(x == std::launch::any); x ^= std::launch::deferred; assert(x == std::launch::async); #endif diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp index e150ba0df65a1..0311cf9b6b00f 100644 --- a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp +++ b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp index 34becbc1259b3..779fc5bfc7c44 100644 --- a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp +++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp index 9cce3f59550a2..e0c6e15d98d5e 100644 --- a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp +++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp @@ -7,8 +7,7 @@ // //===----------------------------------------------------------------------===// // -// XFAIL: libcpp-no-exceptions -// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: libcpp-has-no-threads, libcpp-no-exceptions // <future> diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp deleted file mode 100644 index f7c9b223add1f..0000000000000 --- a/test/std/thread/futures/futures.tas/types.pass.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <future> - -// template<class R, class... ArgTypes> -// class packaged_task<R(ArgTypes...)> -// { -// public: -// typedef R result_type; - -#include <future> -#include <type_traits> - -struct A {}; - -int main() -{ - static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), ""); -} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/assign_copy.fail.cpp index 6c6418594d007..9449e1490270d 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/assign_copy.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/assign_move.pass.cpp index 3f11d670bede3..3f11d670bede3 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/assign_move.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor1.fail.cpp index 7097d428962af..6d7d734bd5e7e 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor1.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> @@ -14,7 +15,7 @@ // class packaged_task<R(ArgTypes...)> // template <class F> // packaged_task(F&& f); -// These constructors shall not participate in overload resolution if +// These constructors shall not participate in overload resolution if // decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. #include <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor2.fail.cpp index feb7657bed37e..984dcdc80b32e 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor2.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> @@ -14,7 +15,7 @@ // class packaged_task<R(ArgTypes...)> // template <class F, class Allocator> // packaged_task(allocator_arg_t, const Allocator& a, F&& f); -// These constructors shall not participate in overload resolution if +// These constructors shall not participate in overload resolution if // decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. #include <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_copy.fail.cpp index 97624f90f3dfe..ff07db9a2e6f1 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_copy.fail.cpp @@ -6,7 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - +// +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03 // <future> diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_default.pass.cpp index ed147d74895b1..ed147d74895b1 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_default.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_func.pass.cpp index 14ac7614bb8e5..14ac7614bb8e5 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_func.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp index 39784876b8c31..39784876b8c31 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/ctor_move.pass.cpp index d9951dca585ab..d9951dca585ab 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/ctor_move.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/dtor.pass.cpp index 7fafd10056490..7fafd10056490 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/dtor.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/get_future.pass.cpp index c8e5d6efd6b42..c8e5d6efd6b42 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/get_future.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/make_ready_at_thread_exit.pass.cpp index 54ac644582486..54ac644582486 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/make_ready_at_thread_exit.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/operator.pass.cpp index 9ad1509517f64..9ad1509517f64 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/operator.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/reset.pass.cpp index 02a567500ee2d..02a567500ee2d 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/reset.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.task/futures.task.members/swap.pass.cpp index eb0091c8e8171..eb0091c8e8171 100644 --- a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.members/swap.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.task/futures.task.nonmembers/swap.pass.cpp index d90d593a75bdf..d90d593a75bdf 100644 --- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.nonmembers/swap.pass.cpp diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.pass.cpp index bbe75de7f8a9c..bbe75de7f8a9c 100644 --- a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp +++ b/test/std/thread/futures/futures.task/futures.task.nonmembers/uses_allocator.pass.cpp diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp index 781c9c9d61991..d20f0c38071f4 100644 --- a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp +++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp index 0d7b5f5074d39..e1d85ac2cfdde 100644 --- a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp +++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp @@ -6,6 +6,8 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads // <future> diff --git a/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp deleted file mode 100644 index bf28e01a0e861..0000000000000 --- a/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <condition_variable> - -// class condition_variable; - -// typedef pthread_cond_t* native_handle_type; -// native_handle_type native_handle(); - -#include <condition_variable> -#include <cassert> - -int main() -{ - static_assert((std::is_same<std::condition_variable::native_handle_type, - pthread_cond_t*>::value), ""); - std::condition_variable cv; - std::condition_variable::native_handle_type h = cv.native_handle(); - assert(h != nullptr); -} diff --git a/test/std/thread/thread.condition/version.pass.cpp b/test/std/thread/thread.condition/version.pass.cpp deleted file mode 100644 index 12a775e833982..0000000000000 --- a/test/std/thread/thread.condition/version.pass.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <condition_variable> - -#include <condition_variable> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp index 246eb935c995d..520c9730bdf7a 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp +++ b/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/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp new file mode 100644 index 0000000000000..840af6788d04f --- /dev/null +++ b/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; locked = true; return 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/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp new file mode 100644 index 0000000000000..18193e000edc7 --- /dev/null +++ b/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/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp new file mode 100644 index 0000000000000..6dc37e970fb60 --- /dev/null +++ b/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/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp new file mode 100644 index 0000000000000..866538a2834f5 --- /dev/null +++ b/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/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp new file mode 100644 index 0000000000000..4910d837cae32 --- /dev/null +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +#include "test_macros.h" + +struct TestMutex { + bool locked = false; + TestMutex() = default; + ~TestMutex() { assert(!locked); } + + void lock() { assert(!locked); locked = true; } + bool try_lock() { if (locked) return false; locked = true; return 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/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp index 10626bc4072e0..3c134e0b88615 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp @@ -11,17 +11,11 @@ // <mutex> -// class recursive_mutex; +// template <class ...Mutex> class lock_guard; -// typedef pthread_mutex_t* native_handle_type; -// native_handle_type native_handle(); +// Test that the variadic lock guard implementation compiles in all standard +// dialects, including C++03, even though it is forward declared using +// variadic templates. -#include <mutex> -#include <cassert> - -int main() -{ - std::recursive_mutex m; - pthread_mutex_t* h = m.native_handle(); - assert(h); -} +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#include "mutex.pass.cpp" // Use the existing non-variadic test diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp new file mode 100644 index 0000000000000..2b06742a673e6 --- /dev/null +++ b/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>(), ""); + } +} diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp index 446807f3f3335..79f43e860ca2f 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // template <class Mutex> class shared_lock; @@ -15,20 +16,12 @@ #include <shared_mutex> -#if _LIBCPP_STD_VER > 11 - std::shared_timed_mutex m0; std::shared_timed_mutex m1; -#endif // _LIBCPP_STD_VER > 11 - int main() { -#if _LIBCPP_STD_VER > 11 std::shared_lock<std::shared_timed_mutex> lk0(m0); std::shared_lock<std::shared_timed_mutex> lk1(m1); lk1 = lk0; -#else -# error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp index 370c1fa4e3361..d6bf57947afe0 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // template <class Mutex> class shared_lock; @@ -15,16 +16,10 @@ #include <shared_mutex> -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m; -#endif // _LIBCPP_STD_VER > 11 int main() { -#if _LIBCPP_STD_VER > 11 std::shared_lock<std::shared_timed_mutex> lk0(m); std::shared_lock<std::shared_timed_mutex> lk = lk0; -#else -# error -#endif // _LIBCPP_STD_VER > 11 } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp index 15c193c60b5d3..bd707bb90ce10 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp @@ -18,17 +18,33 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" -std::shared_timed_mutex m0; -std::shared_timed_mutex m1; int main() { - std::shared_lock<std::shared_timed_mutex> lk0(m0); - std::shared_lock<std::shared_timed_mutex> lk1(m1); + { + typedef std::shared_timed_mutex M; + M m0; + M m1; + std::shared_lock<M> lk0(m0); + std::shared_lock<M> 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<M> lk0(m0); + std::shared_lock<M> 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/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp index 4f4f6a5e9fbdb..c29a3fb04d0ff 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp @@ -18,14 +18,28 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk0(m); - std::shared_lock<std::shared_timed_mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::shared_lock<M> lk0(m); + std::shared_lock<M> 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<M> lk0(m); + std::shared_lock<M> 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/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp index 995210221065e..341f0ce7efd2c 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp @@ -18,12 +18,24 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - m.lock_shared(); - std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + m.lock(); + std::unique_lock<M> 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<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp index d81796b95bf3c..5fbb7244ef8ef 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp @@ -18,11 +18,22 @@ #include <shared_mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::shared_timed_mutex m; - std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::shared_timed_mutex M; + M m; + std::unique_lock<M> 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<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp index 4f477449d6a28..8d864ea8e7da6 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp @@ -16,16 +16,18 @@ #include <mutex> #include <cassert> -std::mutex m0; -std::mutex m1; - int main() { - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> 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/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp index 4888fe90d92c6..067302127cadf 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp @@ -16,14 +16,16 @@ #include <mutex> #include <cassert> -std::mutex m; - int main() { - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = lk0; + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> lk = lk0; assert(lk.mutex() == &m); assert(lk.owns_lock() == true); assert(lk0.mutex() == nullptr); assert(lk0.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp index 4dff853088ac7..e5db685e46e75 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp @@ -17,19 +17,34 @@ #include <mutex> #include <cassert> - -std::mutex m0; -std::mutex m1; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m0); - std::unique_lock<std::mutex> lk1(m1); + { + typedef std::mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> 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); + } + { + typedef nasty_mutex M; + M m0; + M m1; + std::unique_lock<M> lk0(m0); + std::unique_lock<M> 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); + } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp index aa640ee6d746f..427deabc5a59d 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp @@ -17,17 +17,30 @@ #include <mutex> #include <cassert> - -std::mutex m; +#include "nasty_containers.hpp" int main() { #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - std::unique_lock<std::mutex> lk0(m); - std::unique_lock<std::mutex> lk = std::move(lk0); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> lk0(m); + std::unique_lock<M> 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<M> lk0(m); + std::unique_lock<M> 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/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp index 9c3a7b6505a46..20f7d249b6f49 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp @@ -17,12 +17,24 @@ #include <mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::mutex m; + { + typedef std::mutex M; + M m; m.lock(); - std::unique_lock<std::mutex> lk(m, std::adopt_lock); - assert(lk.mutex() == &m); + std::unique_lock<M> 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<M> lk(m, std::adopt_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == true); + } } diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp index bf622311f0132..242dacb1eb922 100644 --- a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp +++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp @@ -17,11 +17,22 @@ #include <mutex> #include <cassert> +#include "nasty_containers.hpp" int main() { - std::mutex m; - std::unique_lock<std::mutex> lk(m, std::defer_lock); - assert(lk.mutex() == &m); + { + typedef std::mutex M; + M m; + std::unique_lock<M> 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<M> lk(m, std::defer_lock); + assert(lk.mutex() == std::addressof(m)); + assert(lk.owns_lock() == false); + } } diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp deleted file mode 100644 index 12c80f02c340d..0000000000000 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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> - -// class mutex; - -// typedef pthread_mutex_t* native_handle_type; -// native_handle_type native_handle(); - -#include <mutex> -#include <cassert> - -int main() -{ - std::mutex m; - pthread_mutex_t* h = m.native_handle(); - assert(h); -} diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp index 5c67a34ab52bb..81995f6c88883 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03, c++11, c++14 // <shared_mutex> diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp index c7cac6041c824..e4bee4bb7ad13 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: c++98, c++03, c++11, c++14 // <shared_mutex> diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp index 528aaca6d9e14..0c5bfa804bea2 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // class shared_timed_mutex; @@ -17,11 +18,7 @@ int main() { -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m0; std::shared_timed_mutex m1; m1 = m0; -#else -# error -#endif } diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp index dbf01002e6912..3656ec62ec17a 100644 --- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp +++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11 // <shared_mutex> // class shared_timed_mutex; @@ -17,10 +18,6 @@ int main() { -#if _LIBCPP_STD_VER > 11 std::shared_timed_mutex m0; std::shared_timed_mutex m1(m0); -#else -# error -#endif } diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp index afc318cc3d7a5..71b054fced886 100644 --- a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp +++ b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp @@ -21,6 +21,8 @@ #include <thread> #include <cassert> +#include "test_macros.h" + typedef std::chrono::milliseconds ms; std::once_flag flg0; @@ -171,7 +173,7 @@ public: void operator()(int&) {} }; -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // reference qualifiers on functions are a C++11 extension struct RefQual { @@ -240,7 +242,7 @@ int main() int i = 0; std::call_once(f, NonCopyable(), i); } -#if __cplusplus >= 201103L +#if TEST_STD_VER >= 11 // reference qualifiers on functions are a C++11 extension { std::once_flag f1, f2; diff --git a/test/std/thread/thread.mutex/version.pass.cpp b/test/std/thread/thread.mutex/version.pass.cpp deleted file mode 100644 index 81b52c79204b8..0000000000000 --- a/test/std/thread/thread.mutex/version.pass.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// <mutex> - -#include <mutex> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp index 3de15af8929bf..5dd6a40a0eb7a 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp @@ -20,23 +20,30 @@ #include <thread> #include <new> +#include <atomic> #include <cstdlib> #include <cassert> #include "test_macros.h" -unsigned throw_one = 0xFFFF; +std::atomic<unsigned> throw_one(0xFFFF); +std::atomic<unsigned> outstanding_new(0); + void* operator new(std::size_t s) throw(std::bad_alloc) { if (throw_one == 0) throw std::bad_alloc(); --throw_one; - return std::malloc(s); + ++outstanding_new; + void* ret = std::malloc(s); + if (!ret) std::abort(); // placate MSVC's unchecked malloc warning + return ret; } void operator delete(void* p) throw() { + --outstanding_new; std::free(p); } @@ -94,27 +101,58 @@ public: #endif -int main() -{ +// Test throwing std::bad_alloc +//----------------------------- +// Concerns: +// A Each allocation performed during thread construction should be performed +// in the parent thread so that std::terminate is not called if +// std::bad_alloc is thrown by new. +// B std::threads constructor should properly handle exceptions and not leak +// memory. +// Plan: +// 1 Create a thread and count the number of allocations, 'N', it performs. +// 2 For each allocation performed run a test where that allocation throws. +// 2.1 check that the exception can be caught in the parent thread. +// 2.2 Check that the functor has not been called. +// 2.3 Check that no memory allocated by the creation of the thread is leaked. +// 3 Finally check that a thread runs successfully if we throw after 'N+1' +// allocations. +void test_throwing_new_during_thread_creation() { + throw_one = 0xFFF; { std::thread t(f); t.join(); - assert(f_run == true); } - f_run = false; - { - try - { - throw_one = 0; + const int numAllocs = 0xFFF - throw_one; + // i <= numAllocs means the last iteration is expected not to throw. + for (int i=0; i <= numAllocs; ++i) { + throw_one = i; + f_run = false; + unsigned old_outstanding = outstanding_new; + try { std::thread t(f); - assert(false); - } - catch (...) - { - throw_one = 0xFFFF; - assert(!f_run); + assert(i == numAllocs); // Only final iteration will not throw. + t.join(); + assert(f_run); + } catch (std::bad_alloc const&) { + assert(i < numAllocs); + assert(!f_run); // (2.2) } + assert(old_outstanding == outstanding_new); // (2.3) + } + f_run = false; + throw_one = 0xFFF; +} + +int main() +{ + test_throwing_new_during_thread_creation(); + { + std::thread t(f); + t.join(); + assert(f_run == true); } + { assert(G::n_alive == 0); assert(!G::op_run); diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp index a331add962635..54fc0b80280c8 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp @@ -12,7 +12,7 @@ // class thread // template <class _Fp, class ..._Args, // explicit thread(_Fp&& __f, _Args&&... __args); -// This constructor shall not participate in overload resolution +// This constructor shall not participate in overload resolution // if decay<F>::type is the same type as std::thread. diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp index 726395d990440..3dd7c6a6014c6 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp @@ -17,8 +17,11 @@ #include <thread> #include <atomic> +#include <system_error> #include <cassert> +#include "test_macros.h" + std::atomic_bool done(false); class G @@ -57,6 +60,8 @@ public: int G::n_alive = 0; bool G::op_run = false; +void foo() {} + int main() { { @@ -70,4 +75,16 @@ int main() assert(G::n_alive == 1); } assert(G::n_alive == 0); +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::thread t0(foo); + assert(t0.joinable()); + t0.detach(); + assert(!t0.joinable()); + try { + t0.detach(); + } catch (std::system_error const&) { + } + } +#endif } diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp index 0512e49dcb336..f0c3ef74c9abb 100644 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp +++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp @@ -19,6 +19,9 @@ #include <new> #include <cstdlib> #include <cassert> +#include <system_error> + +#include "test_macros.h" class G { @@ -42,6 +45,8 @@ public: int G::n_alive = 0; bool G::op_run = false; +void foo() {} + int main() { { @@ -50,5 +55,23 @@ int main() assert(t0.joinable()); t0.join(); assert(!t0.joinable()); +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + t0.join(); + assert(false); + } catch (std::system_error const&) { + } +#endif + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::thread t0(foo); + t0.detach(); + try { + t0.join(); + assert(false); + } catch (std::system_error const&) { + } } +#endif } diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp deleted file mode 100644 index c8807a965c44b..0000000000000 --- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <thread> - -// class thread - -// native_handle_type native_handle(); - -#include <thread> -#include <new> -#include <cstdlib> -#include <cassert> - -class G -{ - int alive_; -public: - static int n_alive; - static bool op_run; - - G() : alive_(1) {++n_alive;} - G(const G& g) : alive_(g.alive_) {++n_alive;} - ~G() {alive_ = 0; --n_alive;} - - void operator()() - { - assert(alive_ == 1); - assert(n_alive >= 1); - op_run = true; - } -}; - -int G::n_alive = 0; -bool G::op_run = false; - -int main() -{ - { - G g; - std::thread t0(g); - pthread_t pid = t0.native_handle(); - assert(pid != 0); - t0.join(); - } -} diff --git a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp deleted file mode 100644 index a5bf77031ccaf..0000000000000 --- a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <thread> - -// class thread -// { -// public: -// typedef pthread_t native_handle_type; -// ... -// }; - -#include <thread> -#include <type_traits> - -int main() -{ - static_assert((std::is_same<std::thread::native_handle_type, pthread_t>::value), ""); -} diff --git a/test/std/thread/thread.threads/version.pass.cpp b/test/std/thread/thread.threads/version.pass.cpp deleted file mode 100644 index d16b0eb068428..0000000000000 --- a/test/std/thread/thread.threads/version.pass.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// <thread> - -#include <thread> - -#ifndef _LIBCPP_VERSION -#error _LIBCPP_VERSION not defined -#endif - -int main() -{ -} |