• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-------------- thread_local_destruction_order.pass.cpp ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // Darwin TLV finalization routines used to fail when creating a thread-local
10 // variable in the destructor for another thread-local variable:
11 //  - http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html
12 //  - rdar://29523281
13 // This was fixed in dyld in macos 10.15.
14 //
15 // XFAIL: macosx10.14
16 // XFAIL: macosx10.13
17 // XFAIL: macosx10.12
18 // XFAIL: macosx10.11
19 // XFAIL: macosx10.10
20 // XFAIL: macosx10.9
21 
22 // UNSUPPORTED: c++03
23 // UNSUPPORTED: libcxxabi-no-threads
24 
25 #include <cassert>
26 #include <thread>
27 
28 #include "make_test_thread.h"
29 
30 int seq = 0;
31 
32 class OrderChecker {
33 public:
OrderChecker(int n)34   explicit OrderChecker(int n) : n_{n} { }
35 
~OrderChecker()36   ~OrderChecker() {
37     assert(seq++ == n_);
38   }
39 
40 private:
41   int n_;
42 };
43 
44 template <int ID>
45 class CreatesThreadLocalInDestructor {
46 public:
~CreatesThreadLocalInDestructor()47   ~CreatesThreadLocalInDestructor() {
48     thread_local OrderChecker checker{ID};
49   }
50 };
51 
52 OrderChecker global{7};
53 
thread_fn()54 void thread_fn() {
55   static OrderChecker fn_static{5};
56   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
57   thread_local OrderChecker fn_thread_local{1};
58   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
59 }
60 
main(int,char **)61 int main(int, char**) {
62   static OrderChecker fn_static{6};
63 
64   support::make_test_thread(thread_fn).join();
65   assert(seq == 3);
66 
67   thread_local OrderChecker fn_thread_local{4};
68   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
69 
70   return 0;
71 }
72