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
7static bool isTaggedPtr(id obj) {
8 uintptr_t ptr = (uintptr_t) obj;
9 return (ptr & 0x8000000000000001ull) != 0;
10}
11
12int 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

source code of compiler-rt/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm