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 = @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