1 | // RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc |
2 | // RUN: %run %t 6 2>&1 | FileCheck %s --check-prefix=SIX |
3 | // RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=SEVEN |
4 | |
5 | #import <Foundation/Foundation.h> |
6 | |
7 | static bool isTaggedPtr(id obj) { |
8 | uintptr_t ptr = (uintptr_t) obj; |
9 | return (ptr & 0x8000000000000001ull) != 0; |
10 | } |
11 | |
12 | int main(int argc, char* argv[]) { |
13 | assert(argc == 2); |
14 | int arg = atoi(argv[1]); |
15 | |
16 | @autoreleasepool { |
17 | NSObject* obj = [NSObject new]; |
18 | NSObject* num1 = [NSNumber numberWithInt:7]; |
19 | NSObject* num2 = [NSNumber numberWithInt:arg]; |
20 | |
21 | assert(!isTaggedPtr(obj)); |
22 | assert(isTaggedPtr(num1) && isTaggedPtr(num2)); |
23 | |
24 | // obj -> num1 (includes num2) |
25 | @synchronized(obj) { |
26 | @synchronized(num1) { |
27 | } |
28 | } |
29 | |
30 | // num2 -> obj1 |
31 | @synchronized(num2) { |
32 | @synchronized(obj) { |
33 | // SEVEN: ThreadSanitizer: lock-order-inversion (potential deadlock) |
34 | } |
35 | } |
36 | } |
37 | |
38 | NSLog(@"PASS" ); |
39 | // SIX-NOT: ThreadSanitizer |
40 | // SIX: PASS |
41 | return 0; |
42 | } |
43 | |