Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 6d290f5

Browse files
committed
[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: faef7d034a9ec6cb757137adce8e8670ec6c2d7b Subscribers: kubamracek, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D60639 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@358469 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit d33c5cf)
1 parent 8ea0e7c commit 6d290f5

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

test/tsan/Darwin/gcd-sync-block-copy.mm

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't).
22

3-
// RUN: %clang_tsan -fno-sanitize=thread %s -o %t_no_tsan -framework Foundation
4-
// RUN: %run %t_no_tsan 2>&1 | FileCheck %s
5-
3+
// RUN: %clang_tsan %s -o %t_no_tsan -framework Foundation -fno-sanitize=thread
64
// RUN: %clang_tsan %s -o %t_with_tsan -framework Foundation
5+
6+
// RUN: %run %t_no_tsan 2>&1 | FileCheck %s
77
// RUN: %run %t_with_tsan 2>&1 | FileCheck %s
88

99
#import <Foundation/Foundation.h>
@@ -22,9 +22,13 @@ - (instancetype)retain {
2222
int main(int argc, const char* argv[]) {
2323
dispatch_queue_t q = dispatch_queue_create("my.queue", NULL);
2424
id object = [[MyClass alloc] init];
25+
void (^block)(void) = ^ {
26+
NSLog(@"%@", object);
27+
};
2528
dispatch_sync(q, ^{
2629
NSLog(@"%@", object);
2730
});
31+
dispatch_sync(q, block);
2832
[object release];
2933
NSLog(@"Done.");
3034
return 0;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't).
2+
3+
// RUN: %clangxx_tsan %s -o %t_no_tsan -fno-sanitize=thread
4+
// RUN: %clangxx_tsan %s -o %t_with_tsan
5+
6+
// RUN: %run %t_no_tsan 2>&1 | FileCheck %s
7+
// RUN: %run %t_with_tsan 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
8+
9+
#include <dispatch/dispatch.h>
10+
11+
#include <stdio.h>
12+
13+
struct MyClass {
14+
static int copyCount;
15+
static void printCopyCount() {
16+
fprintf(stderr, "copyCount = %d\n", copyCount);
17+
}
18+
MyClass(){};
19+
MyClass(const MyClass &obj) { copyCount++; };
20+
void foo() const {
21+
fprintf(stderr, "MyClass::foo\n");
22+
}
23+
};
24+
int MyClass::copyCount = 0;
25+
26+
int main(int argc, const char* argv[]) {
27+
dispatch_queue_t q = dispatch_queue_create("my.queue", NULL);
28+
MyClass obj;
29+
MyClass::printCopyCount();
30+
void (^block)(void) = ^{
31+
obj.foo();
32+
};
33+
MyClass::printCopyCount();
34+
dispatch_sync(q, block);
35+
MyClass::printCopyCount();
36+
37+
fprintf(stderr, "Done.\n");
38+
return 0;
39+
}
40+
41+
// CHECK: copyCount = 0
42+
// CHECK: copyCount = 1
43+
// CHECK: MyClass::foo
44+
// CHECK: copyCount = 1
45+
// CHECK: Done.

0 commit comments

Comments
 (0)