1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // XFAIL: libcpp-no-exceptions 11 // UNSUPPORTED: libcpp-has-no-threads 12 13 // <thread> 14 15 // class thread 16 17 // template <class F, class ...Args> thread(F&& f, Args&&... args); 18 19 // UNSUPPORTED: sanitizer-new-delete 20 21 #include <thread> 22 #include <new> 23 #include <cstdlib> 24 #include <cassert> 25 26 #include "test_macros.h" 27 28 unsigned throw_one = 0xFFFF; 29 30 void* operator new(std::size_t s) throw(std::bad_alloc) 31 { 32 if (throw_one == 0) 33 throw std::bad_alloc(); 34 --throw_one; 35 return std::malloc(s); 36 } 37 38 void operator delete(void* p) throw() 39 { 40 std::free(p); 41 } 42 43 bool f_run = false; 44 45 void f() 46 { 47 f_run = true; 48 } 49 50 class G 51 { 52 int alive_; 53 public: 54 static int n_alive; 55 static bool op_run; 56 57 G() : alive_(1) {++n_alive;} 58 G(const G& g) : alive_(g.alive_) {++n_alive;} 59 ~G() {alive_ = 0; --n_alive;} 60 61 void operator()() 62 { 63 assert(alive_ == 1); 64 assert(n_alive >= 1); 65 op_run = true; 66 } 67 68 void operator()(int i, double j) 69 { 70 assert(alive_ == 1); 71 assert(n_alive >= 1); 72 assert(i == 5); 73 assert(j == 5.5); 74 op_run = true; 75 } 76 }; 77 78 int G::n_alive = 0; 79 bool G::op_run = false; 80 81 #if TEST_STD_VER >= 11 82 83 class MoveOnly 84 { 85 MoveOnly(const MoveOnly&); 86 public: 87 MoveOnly() {} 88 MoveOnly(MoveOnly&&) {} 89 90 void operator()(MoveOnly&&) 91 { 92 } 93 }; 94 95 #endif 96 97 int main() 98 { 99 { 100 std::thread t(f); 101 t.join(); 102 assert(f_run == true); 103 } 104 f_run = false; 105 { 106 try 107 { 108 throw_one = 0; 109 std::thread t(f); 110 assert(false); 111 } 112 catch (...) 113 { 114 throw_one = 0xFFFF; 115 assert(!f_run); 116 } 117 } 118 { 119 assert(G::n_alive == 0); 120 assert(!G::op_run); 121 std::thread t((G())); 122 t.join(); 123 assert(G::n_alive == 0); 124 assert(G::op_run); 125 } 126 G::op_run = false; 127 { 128 try 129 { 130 throw_one = 0; 131 assert(G::n_alive == 0); 132 assert(!G::op_run); 133 std::thread t((G())); 134 assert(false); 135 } 136 catch (...) 137 { 138 throw_one = 0xFFFF; 139 assert(G::n_alive == 0); 140 assert(!G::op_run); 141 } 142 } 143 #if TEST_STD_VER >= 11 144 { 145 assert(G::n_alive == 0); 146 assert(!G::op_run); 147 std::thread t(G(), 5, 5.5); 148 t.join(); 149 assert(G::n_alive == 0); 150 assert(G::op_run); 151 } 152 { 153 std::thread t = std::thread(MoveOnly(), MoveOnly()); 154 t.join(); 155 } 156 #endif 157 } 158