Index: compiler-rt/trunk/test/tsan/Darwin/gcd-sync-block-copy.mm =================================================================== --- compiler-rt/trunk/test/tsan/Darwin/gcd-sync-block-copy.mm +++ compiler-rt/trunk/test/tsan/Darwin/gcd-sync-block-copy.mm @@ -1,9 +1,9 @@ // This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't). -// RUN: %clang_tsan -fno-sanitize=thread %s -o %t_no_tsan -framework Foundation -// RUN: %run %t_no_tsan 2>&1 | FileCheck %s - +// RUN: %clang_tsan %s -o %t_no_tsan -framework Foundation -fno-sanitize=thread // RUN: %clang_tsan %s -o %t_with_tsan -framework Foundation + +// RUN: %run %t_no_tsan 2>&1 | FileCheck %s // RUN: %run %t_with_tsan 2>&1 | FileCheck %s #import @@ -22,9 +22,13 @@ int main(int argc, const char* argv[]) { dispatch_queue_t q = dispatch_queue_create("my.queue", NULL); id object = [[MyClass alloc] init]; + void (^block)(void) = ^ { + NSLog(@"%@", object); + }; dispatch_sync(q, ^{ NSLog(@"%@", object); }); + dispatch_sync(q, block); [object release]; NSLog(@"Done."); return 0; Index: compiler-rt/trunk/test/tsan/libdispatch/sync-block-copy.cc =================================================================== --- compiler-rt/trunk/test/tsan/libdispatch/sync-block-copy.cc +++ compiler-rt/trunk/test/tsan/libdispatch/sync-block-copy.cc @@ -0,0 +1,45 @@ +// This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't). + +// RUN: %clangxx_tsan %s -o %t_no_tsan -fno-sanitize=thread +// RUN: %clangxx_tsan %s -o %t_with_tsan + +// RUN: %run %t_no_tsan 2>&1 | FileCheck %s +// RUN: %run %t_with_tsan 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer' + +#include + +#include + +struct MyClass { + static int copyCount; + static void printCopyCount() { + fprintf(stderr, "copyCount = %d\n", copyCount); + } + MyClass(){}; + MyClass(const MyClass &obj) { copyCount++; }; + void foo() const { + fprintf(stderr, "MyClass::foo\n"); + } +}; +int MyClass::copyCount = 0; + +int main(int argc, const char* argv[]) { + dispatch_queue_t q = dispatch_queue_create("my.queue", NULL); + MyClass obj; + MyClass::printCopyCount(); + void (^block)(void) = ^{ + obj.foo(); + }; + MyClass::printCopyCount(); + dispatch_sync(q, block); + MyClass::printCopyCount(); + + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK: copyCount = 0 +// CHECK: copyCount = 1 +// CHECK: MyClass::foo +// CHECK: copyCount = 1 +// CHECK: Done.