1 | // RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc |
2 | // RUN: %run %t 2>&1 | FileCheck %s |
3 | |
4 | #import <Foundation/Foundation.h> |
5 | |
6 | NSString *tagged_string = nil; |
7 | |
8 | @interface MyClass : NSObject { |
9 | long field; |
10 | } |
11 | @property(nonatomic, readonly) long value; |
12 | @end |
13 | |
14 | dispatch_group_t group; |
15 | |
16 | @implementation MyClass |
17 | |
18 | - (void)start { |
19 | dispatch_queue_t q = dispatch_queue_create(NULL, NULL); |
20 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
21 | for (int i = 0; i < 10; i++) { |
22 | dispatch_async(q, ^{ |
23 | @synchronized(tagged_string) { |
24 | self->field = i; |
25 | } |
26 | }); |
27 | } |
28 | }); |
29 | } |
30 | |
31 | - (long)value { |
32 | @synchronized(tagged_string) { |
33 | return self->field; |
34 | } |
35 | } |
36 | |
37 | - (void)dealloc { |
38 | dispatch_group_leave(group); |
39 | } |
40 | |
41 | @end |
42 | |
43 | int main() { |
44 | tagged_string = [NSString stringWithFormat:@"%s" , "abc" ]; |
45 | uintptr_t tagged_string_bits = (uintptr_t)tagged_string; |
46 | assert((tagged_string_bits & 0x8000000000000001ull) != 0); |
47 | group = dispatch_group_create(); |
48 | @autoreleasepool { |
49 | for (int j = 0; j < 100; ++j) { |
50 | dispatch_group_enter(group); |
51 | MyClass *obj = [[MyClass alloc] init]; |
52 | [obj start]; |
53 | long x = obj.value; |
54 | (void)x; |
55 | } |
56 | } |
57 | dispatch_group_wait(group, DISPATCH_TIME_FOREVER); |
58 | NSLog(@"Hello world" ); |
59 | } |
60 | |
61 | // CHECK: Hello world |
62 | // CHECK-NOT: WARNING: ThreadSanitizer |
63 | |