1*bcaeed49SFangrui Song // This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't).
2*bcaeed49SFangrui Song 
3*bcaeed49SFangrui Song // RUN: %clangxx_tsan %s -o %t_no_tsan -fno-sanitize=thread
4*bcaeed49SFangrui Song // RUN: %clangxx_tsan %s -o %t_with_tsan
5*bcaeed49SFangrui Song 
6*bcaeed49SFangrui Song // RUN: %run %t_no_tsan   2>&1 | FileCheck %s
7*bcaeed49SFangrui Song // RUN: %run %t_with_tsan 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
8*bcaeed49SFangrui Song 
9*bcaeed49SFangrui Song #include <dispatch/dispatch.h>
10*bcaeed49SFangrui Song 
11*bcaeed49SFangrui Song #include <stdio.h>
12*bcaeed49SFangrui Song 
13*bcaeed49SFangrui Song struct MyClass {
14*bcaeed49SFangrui Song   static int copyCount;
printCopyCountMyClass15*bcaeed49SFangrui Song   static void printCopyCount() {
16*bcaeed49SFangrui Song     fprintf(stderr, "copyCount = %d\n", copyCount);
17*bcaeed49SFangrui Song   }
MyClassMyClass18*bcaeed49SFangrui Song   MyClass(){};
MyClassMyClass19*bcaeed49SFangrui Song   MyClass(const MyClass &obj) { copyCount++; };
fooMyClass20*bcaeed49SFangrui Song   void foo() const {
21*bcaeed49SFangrui Song     fprintf(stderr, "MyClass::foo\n");
22*bcaeed49SFangrui Song   }
23*bcaeed49SFangrui Song };
24*bcaeed49SFangrui Song int MyClass::copyCount = 0;
25*bcaeed49SFangrui Song 
main(int argc,const char * argv[])26*bcaeed49SFangrui Song int main(int argc, const char* argv[]) {
27*bcaeed49SFangrui Song   dispatch_queue_t q = dispatch_queue_create("my.queue", NULL);
28*bcaeed49SFangrui Song   MyClass obj;
29*bcaeed49SFangrui Song   MyClass::printCopyCount();
30*bcaeed49SFangrui Song   void (^block)(void) = ^{
31*bcaeed49SFangrui Song     obj.foo();
32*bcaeed49SFangrui Song   };
33*bcaeed49SFangrui Song   MyClass::printCopyCount();
34*bcaeed49SFangrui Song   dispatch_sync(q, block);
35*bcaeed49SFangrui Song   MyClass::printCopyCount();
36*bcaeed49SFangrui Song 
37*bcaeed49SFangrui Song   fprintf(stderr, "Done.\n");
38*bcaeed49SFangrui Song   return 0;
39*bcaeed49SFangrui Song }
40*bcaeed49SFangrui Song 
41*bcaeed49SFangrui Song // CHECK: copyCount = 0
42*bcaeed49SFangrui Song // CHECK: copyCount = 1
43*bcaeed49SFangrui Song // CHECK: MyClass::foo
44*bcaeed49SFangrui Song // CHECK: copyCount = 1
45*bcaeed49SFangrui Song // CHECK: Done.
46