]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/thread-local-atexit-macOS.dtest/main.cpp
dyld-750.5.tar.gz
[apple/dyld.git] / testing / test-cases / thread-local-atexit-macOS.dtest / main.cpp
1 // BUILD_ONLY: MacOSX
2
3 // BUILD: $CXX main.cpp -std=c++11 -o $BUILD_DIR/thread-local-atexit-macOS.exe
4
5 // RUN: ./thread-local-atexit-macOS.exe
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <pthread.h>
10
11 #include "test_support.h"
12
13 // We create an A and a B.
14 // While destroying B we create a C
15 // Given that tlv_finalize has "destroy in reverse order of construction", we
16 // must then immediately destroy C before we destroy A to maintain that invariant
17
18 enum State {
19 None,
20 ConstructedA,
21 ConstructedB,
22 ConstructedC,
23 DestroyingB,
24 DestroyedA,
25 DestroyedB,
26 DestroyedC,
27 };
28
29 struct A {
30 A();
31 ~A();
32 };
33
34 struct B {
35 B();
36 ~B();
37 };
38
39 struct C {
40 C();
41 ~C();
42 };
43
44 State state;
45
46 A::A() {
47 if ( state != None ) {
48 FAIL("should be in the 'None' state");
49 }
50 state = ConstructedA;
51 }
52
53 B::B() {
54 if ( state != ConstructedA ) {
55 FAIL("should be in the 'ConstructedA' state");
56 }
57 state = ConstructedB;
58 }
59
60 C::C() {
61 // We construct C during B's destructor
62 if ( state != DestroyingB ) {
63 FAIL("should be in the 'DestroyingB' state");
64 }
65 state = ConstructedC;
66 }
67
68 // We destroy B first
69 B::~B() {
70 if ( state != ConstructedB ) {
71 FAIL("should be in the 'ConstructedB' state");
72 }
73 state = DestroyingB;
74 static thread_local C c;
75 if ( state != ConstructedC ) {
76 FAIL("should be in the 'ConstructedC' state");
77 }
78 state = DestroyedB;
79 }
80
81 // Then we destroy C
82 C::~C() {
83 if ( state != DestroyedB ) {
84 FAIL("should be in the 'DestroyedB' state");
85 }
86 state = DestroyedC;
87 }
88
89 // And finally destroy A
90 A::~A() {
91 if ( state != DestroyedC ) {
92 FAIL("should be in the 'DestroyedC' state");
93 }
94 state = DestroyedA;
95 PASS("[Success");
96 }
97
98 static void work()
99 {
100 thread_local A a = {};
101 thread_local B b = {};
102 }
103
104 int main(int argc, const char* argv[], const char* envp[], const char* apple[]) {
105 work();
106 return 0;
107 }
108