]> git.proxmox.com Git - rustc.git/blob - src/compiler-rt/test/tsan/Darwin/norace-objcxx-run-time.mm
New upstream version 1.19.0+dfsg3
[rustc.git] / src / compiler-rt / test / tsan / Darwin / norace-objcxx-run-time.mm
1 // RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation
2 // RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
3
4 // Check that we do not report races between:
5 // - Object retain and initialize
6 // - Object release and dealloc
7 // - Object release and .cxx_destruct
8
9 #import <Foundation/Foundation.h>
10 #include "../test.h"
11 invisible_barrier_t barrier2;
12
13 class NeedCleanup {
14 public:
15 int x;
16 NeedCleanup() {
17 x = 1;
18 }
19 ~NeedCleanup() {
20 x = 0;
21 }
22 };
23
24 @interface TestDeallocObject : NSObject {
25 @public
26 int v;
27 }
28 - (id)init;
29 - (void)accessMember;
30 - (void)dealloc;
31 @end
32
33 @implementation TestDeallocObject
34 - (id)init {
35 if ([super self]) {
36 v = 1;
37 return self;
38 }
39 return nil;
40 }
41 - (void)accessMember {
42 int local = v;
43 local++;
44 }
45 - (void)dealloc {
46 v = 0;
47 }
48 @end
49
50 @interface TestCXXDestructObject : NSObject {
51 @public
52 NeedCleanup cxxMemberWithCleanup;
53 }
54 - (void)accessMember;
55 @end
56
57 @implementation TestCXXDestructObject
58 - (void)accessMember {
59 int local = cxxMemberWithCleanup.x;
60 local++;
61 }
62 @end
63
64 @interface TestInitializeObject : NSObject
65 @end
66
67 @implementation TestInitializeObject
68 static long InitializerAccessedGlobal = 0;
69 + (void)initialize {
70 InitializerAccessedGlobal = 42;
71 }
72 @end
73
74 int main(int argc, const char *argv[]) {
75 // Ensure that there is no race when calling initialize on TestInitializeObject;
76 // otherwise, the locking from ObjC runtime becomes observable. Also ensures that
77 // blocks are dispatched to 2 different threads.
78 barrier_init(&barrier, 2);
79 // Ensure that objects are destructed during block object release.
80 barrier_init(&barrier2, 3);
81
82 TestDeallocObject *tdo = [[TestDeallocObject alloc] init];
83 TestCXXDestructObject *tcxxdo = [[TestCXXDestructObject alloc] init];
84 [tdo accessMember];
85 [tcxxdo accessMember];
86 {
87 dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
88 dispatch_async(q, ^{
89 [TestInitializeObject new];
90 barrier_wait(&barrier);
91 long local = InitializerAccessedGlobal;
92 local++;
93 [tdo accessMember];
94 [tcxxdo accessMember];
95 barrier_wait(&barrier2);
96 });
97 dispatch_async(q, ^{
98 barrier_wait(&barrier);
99 [TestInitializeObject new];
100 long local = InitializerAccessedGlobal;
101 local++;
102 [tdo accessMember];
103 [tcxxdo accessMember];
104 barrier_wait(&barrier2);
105 });
106 }
107 barrier_wait(&barrier2);
108 NSLog(@"Done.");
109 return 0;
110 }
111
112 // CHECK: Done.
113 // CHECK-NOT: ThreadSanitizer: data race