1 | // This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't). |
2 | |
3 | // RUN: %clang_tsan %s -o %t_no_tsan -framework Foundation -fno-sanitize=thread |
4 | // RUN: %clang_tsan %s -o %t_with_tsan -framework Foundation |
5 | |
6 | // RUN: %run %t_no_tsan 2>&1 | FileCheck %s |
7 | // RUN: %run %t_with_tsan 2>&1 | FileCheck %s |
8 | |
9 | #import <Foundation/Foundation.h> |
10 | |
11 | @interface MyClass : NSObject |
12 | @end |
13 | |
14 | @implementation MyClass |
15 | - (instancetype)retain { |
16 | // Copying the dispatch_sync'd block below will increment the retain count of |
17 | // this object. Abort if that happens. |
18 | abort(); |
19 | } |
20 | @end |
21 | |
22 | int main(int argc, const char* argv[]) { |
23 | dispatch_queue_t q = dispatch_queue_create("my.queue" , NULL); |
24 | id object = [[MyClass alloc] init]; |
25 | void (^block)(void) = ^ { |
26 | NSLog(@"%@" , object); |
27 | }; |
28 | dispatch_sync(q, ^{ |
29 | NSLog(@"%@" , object); |
30 | }); |
31 | dispatch_sync(q, block); |
32 | [object release]; |
33 | NSLog(@"Done." ); |
34 | return 0; |
35 | } |
36 | |
37 | // CHECK: Done. |
38 | // CHECK-NOT: WARNING: ThreadSanitizer |
39 | |