[TSan][libdispatch] Port gcd-sync-block-copy.mm to C++
Summary:
Apparently, it makes a difference on where a block lives depending on if
it's passed "inline" versus assigned and then passed via a variable.
Both tests in this commit now give a signal, if `Block_copy` is used in
`dispatch_sync`.
Since these tests use different mechanisms (Objective-C retain versus
C++ copy constructor) as proxies to observe if the block was copied, we
should keep both of them.
Commit, that first avoided the unnecessary copy:
faef7d034a
Subscribers: kubamracek, #sanitizers, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D60639
llvm-svn: 358469
This commit is contained in:
parent
3ad162bbeb
commit
2632643454
|
@ -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 <Foundation/Foundation.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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 <dispatch/dispatch.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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.
|
Loading…
Reference in New Issue