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 22int 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