1 //===-------------- thread_local_destruction_order.pass.cpp ---------------===//
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 // UNSUPPORTED: c++98, c++03
11 // UNSUPPORTED: libcxxabi-no-threads
12 
13 #include <cassert>
14 #include <thread>
15 
16 int seq = 0;
17 
18 class OrderChecker {
19 public:
20   explicit OrderChecker(int n) : n_{n} { }
21 
22   ~OrderChecker() {
23     assert(seq++ == n_);
24   }
25 
26 private:
27   int n_;
28 };
29 
30 template <int ID>
31 class CreatesThreadLocalInDestructor {
32 public:
33   ~CreatesThreadLocalInDestructor() {
34     thread_local OrderChecker checker{ID};
35   }
36 };
37 
38 OrderChecker global{7};
39 
40 void thread_fn() {
41   static OrderChecker fn_static{5};
42   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
43   thread_local OrderChecker fn_thread_local{1};
44   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
45 }
46 
47 int main() {
48   static OrderChecker fn_static{6};
49 
50   std::thread{thread_fn}.join();
51   assert(seq == 3);
52 
53   thread_local OrderChecker fn_thread_local{4};
54   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
55 
56   return 0;
57 }
58