• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Darwin TLV finalization routines fail when creating a thread-local variable
11 // in the destructor for another thread-local variable:
12 // http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html
13 // XFAIL: darwin
14 // UNSUPPORTED: c++98, c++03
15 // UNSUPPORTED: libcxxabi-no-threads
16 
17 #include <cassert>
18 #include <thread>
19 
20 int seq = 0;
21 
22 class OrderChecker {
23 public:
OrderChecker(int n)24   explicit OrderChecker(int n) : n_{n} { }
25 
~OrderChecker()26   ~OrderChecker() {
27     assert(seq++ == n_);
28   }
29 
30 private:
31   int n_;
32 };
33 
34 template <int ID>
35 class CreatesThreadLocalInDestructor {
36 public:
~CreatesThreadLocalInDestructor()37   ~CreatesThreadLocalInDestructor() {
38     thread_local OrderChecker checker{ID};
39   }
40 };
41 
42 OrderChecker global{7};
43 
thread_fn()44 void thread_fn() {
45   static OrderChecker fn_static{5};
46   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
47   thread_local OrderChecker fn_thread_local{1};
48   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
49 }
50 
main()51 int main() {
52   static OrderChecker fn_static{6};
53 
54   std::thread{thread_fn}.join();
55   assert(seq == 3);
56 
57   thread_local OrderChecker fn_thread_local{4};
58   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
59 
60   return 0;
61 }
62