150
|
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
|
173
|
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
|
150
|
22 // UNSUPPORTED: c++98, c++03
|
|
23 // UNSUPPORTED: libcxxabi-no-threads
|
|
24
|
|
25 #include <cassert>
|
|
26 #include <thread>
|
|
27
|
|
28 int seq = 0;
|
|
29
|
|
30 class OrderChecker {
|
|
31 public:
|
|
32 explicit OrderChecker(int n) : n_{n} { }
|
|
33
|
|
34 ~OrderChecker() {
|
|
35 assert(seq++ == n_);
|
|
36 }
|
|
37
|
|
38 private:
|
|
39 int n_;
|
|
40 };
|
|
41
|
|
42 template <int ID>
|
|
43 class CreatesThreadLocalInDestructor {
|
|
44 public:
|
|
45 ~CreatesThreadLocalInDestructor() {
|
|
46 thread_local OrderChecker checker{ID};
|
|
47 }
|
|
48 };
|
|
49
|
|
50 OrderChecker global{7};
|
|
51
|
|
52 void thread_fn() {
|
|
53 static OrderChecker fn_static{5};
|
|
54 thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
|
|
55 thread_local OrderChecker fn_thread_local{1};
|
|
56 thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
|
|
57 }
|
|
58
|
|
59 int main() {
|
|
60 static OrderChecker fn_static{6};
|
|
61
|
|
62 std::thread{thread_fn}.join();
|
|
63 assert(seq == 3);
|
|
64
|
|
65 thread_local OrderChecker fn_thread_local{4};
|
|
66 thread_local CreatesThreadLocalInDestructor<3> creates_tl;
|
|
67
|
|
68 return 0;
|
|
69 }
|