aboutsummaryrefslogtreecommitdiff
path: root/test/tsan/Darwin
diff options
context:
space:
mode:
Diffstat (limited to 'test/tsan/Darwin')
-rw-r--r--test/tsan/Darwin/debug_external.cc66
-rw-r--r--test/tsan/Darwin/dispatch_main.mm2
-rw-r--r--test/tsan/Darwin/dispatch_once_deadlock.mm2
-rw-r--r--test/tsan/Darwin/external.cc163
-rw-r--r--test/tsan/Darwin/gcd-after-null.mm23
-rw-r--r--test/tsan/Darwin/gcd-after.mm2
-rw-r--r--test/tsan/Darwin/gcd-apply-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-apply.mm2
-rw-r--r--test/tsan/Darwin/gcd-async-norace.mm2
-rw-r--r--test/tsan/Darwin/gcd-async-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-barrier-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-barrier.mm2
-rw-r--r--test/tsan/Darwin/gcd-blocks.mm2
-rw-r--r--test/tsan/Darwin/gcd-data.mm2
-rw-r--r--test/tsan/Darwin/gcd-fd.mm2
-rw-r--r--test/tsan/Darwin/gcd-groups-destructor.mm2
-rw-r--r--test/tsan/Darwin/gcd-groups-leave.mm2
-rw-r--r--test/tsan/Darwin/gcd-groups-norace.mm2
-rw-r--r--test/tsan/Darwin/gcd-groups-stress.mm2
-rw-r--r--test/tsan/Darwin/gcd-io-barrier-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-io-barrier.mm2
-rw-r--r--test/tsan/Darwin/gcd-io-cleanup.mm2
-rw-r--r--test/tsan/Darwin/gcd-io-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-io.mm2
-rw-r--r--test/tsan/Darwin/gcd-once.mm2
-rw-r--r--test/tsan/Darwin/gcd-semaphore-norace.mm2
-rw-r--r--test/tsan/Darwin/gcd-serial-queue-norace.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-cancel.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-cancel2.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-event.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-event2.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-registration.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-registration2.mm2
-rw-r--r--test/tsan/Darwin/gcd-source-serial.mm2
-rw-r--r--test/tsan/Darwin/gcd-suspend.mm2
-rw-r--r--test/tsan/Darwin/gcd-sync-norace.mm2
-rw-r--r--test/tsan/Darwin/gcd-sync-race.mm2
-rw-r--r--test/tsan/Darwin/gcd-target-queue-norace.mm2
-rw-r--r--test/tsan/Darwin/ignore-noninstrumented.mm2
-rw-r--r--test/tsan/Darwin/ignored-interceptors.mm6
-rw-r--r--test/tsan/Darwin/libcxx-call-once.mm2
-rw-r--r--test/tsan/Darwin/libcxx-future.mm2
-rw-r--r--test/tsan/Darwin/libcxx-shared-ptr-recursive.mm2
-rw-r--r--test/tsan/Darwin/libcxx-shared-ptr-stress.mm2
-rw-r--r--test/tsan/Darwin/libcxx-shared-ptr.mm2
-rw-r--r--test/tsan/Darwin/lit.local.cfg2
-rw-r--r--test/tsan/Darwin/main_tid.mm46
-rw-r--r--test/tsan/Darwin/norace-objcxx-run-time.mm2
-rw-r--r--test/tsan/Darwin/objc-double-property.mm8
-rw-r--r--test/tsan/Darwin/objc-simple.mm2
-rw-r--r--test/tsan/Darwin/workerthreads.mm43
-rw-r--r--test/tsan/Darwin/xpc-cancel.mm37
-rw-r--r--test/tsan/Darwin/xpc-race.mm2
-rw-r--r--test/tsan/Darwin/xpc.mm2
54 files changed, 432 insertions, 52 deletions
diff --git a/test/tsan/Darwin/debug_external.cc b/test/tsan/Darwin/debug_external.cc
new file mode 100644
index 000000000000..217690fc5dd0
--- /dev/null
+++ b/test/tsan/Darwin/debug_external.cc
@@ -0,0 +1,66 @@
+// RUN: %clangxx_tsan -O1 %s -o %t
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test.h"
+
+extern "C" {
+void __tsan_on_report(void *report);
+int __tsan_get_report_loc(void *report, unsigned long idx, const char **type,
+ void **addr, void **start,
+ unsigned long *size, int *tid, int *fd,
+ int *suppressable, void **trace,
+ unsigned long trace_size);
+int __tsan_get_report_loc_object_type(void *report, unsigned long idx,
+ const char **object_type);
+void *__tsan_external_register_tag(const char *object_type);
+void __tsan_external_assign_tag(void *addr, void *tag);
+}
+
+void *Thread(void *arg) {
+ barrier_wait(&barrier);
+ *((long *)arg) = 42;
+ return NULL;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ void *tag = __tsan_external_register_tag("MyObject");
+ long *obj = (long *)malloc(sizeof(long));
+ fprintf(stderr, "obj = %p\n", obj);
+ // CHECK: obj = [[ADDR:0x[0-9a-f]+]]
+ __tsan_external_assign_tag(obj, tag);
+
+ pthread_t t;
+ pthread_create(&t, 0, Thread, obj);
+ *obj = 41;
+ barrier_wait(&barrier);
+ pthread_join(t, 0);
+ fprintf(stderr, "Done.\n");
+ return 0;
+}
+
+void __tsan_on_report(void *report) {
+ const char *type;
+ void *addr;
+ void *start;
+ unsigned long size;
+ int tid, fd, suppressable;
+ void *trace[16] = {0};
+ __tsan_get_report_loc(report, 0, &type, &addr, &start, &size, &tid, &fd,
+ &suppressable, trace, 16);
+ fprintf(stderr, "type = %s, start = %p, size = %ld\n", type, start, size);
+ // CHECK: type = heap, start = [[ADDR]], size = 8
+
+ const char *object_type;
+ __tsan_get_report_loc_object_type(report, 0, &object_type);
+ fprintf(stderr, "object_type = %s\n", object_type);
+ // CHECK: object_type = MyObject
+}
+
+// CHECK: Done.
+// CHECK: ThreadSanitizer: reported 1 warnings
diff --git a/test/tsan/Darwin/dispatch_main.mm b/test/tsan/Darwin/dispatch_main.mm
index 75887547c606..f4c1e44bc6b1 100644
--- a/test/tsan/Darwin/dispatch_main.mm
+++ b/test/tsan/Darwin/dispatch_main.mm
@@ -2,7 +2,7 @@
// quits the main thread.
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/dispatch_once_deadlock.mm b/test/tsan/Darwin/dispatch_once_deadlock.mm
index e88cdc0d0da5..e109f64a8dcb 100644
--- a/test/tsan/Darwin/dispatch_once_deadlock.mm
+++ b/test/tsan/Darwin/dispatch_once_deadlock.mm
@@ -1,7 +1,7 @@
// Check that calling dispatch_once from a report callback works.
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <pthread.h>
diff --git a/test/tsan/Darwin/external.cc b/test/tsan/Darwin/external.cc
new file mode 100644
index 000000000000..2605480d7b82
--- /dev/null
+++ b/test/tsan/Darwin/external.cc
@@ -0,0 +1,163 @@
+// RUN: %clangxx_tsan %s -shared -DSHARED_LIB \
+// RUN: -o %t-lib-instrumented.dylib \
+// RUN: -install_name @rpath/`basename %t-lib-instrumented.dylib`
+
+// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread \
+// RUN: -o %t-lib-noninstrumented.dylib \
+// RUN: -install_name @rpath/`basename %t-lib-noninstrumented.dylib`
+
+// RUN: %clangxx_tsan %s -shared -DSHARED_LIB -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \
+// RUN: -o %t-lib-noninstrumented-callbacks.dylib \
+// RUN: -install_name @rpath/`basename %t-lib-noninstrumented-callbacks.dylib`
+
+// RUN: %clangxx_tsan %s %t-lib-instrumented.dylib -o %t-lib-instrumented
+// RUN: %clangxx_tsan %s %t-lib-noninstrumented.dylib -o %t-lib-noninstrumented
+// RUN: %clangxx_tsan %s %t-lib-noninstrumented-callbacks.dylib -o %t-lib-noninstrumented-callbacks
+
+// RUN: %deflake %run %t-lib-instrumented 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST1
+// RUN: %run %t-lib-noninstrumented 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST2
+// RUN: %deflake %run %t-lib-noninstrumented-callbacks 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST3
+
+#include <thread>
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct MyObject;
+typedef MyObject *MyObjectRef;
+extern "C" {
+ void InitializeLibrary();
+ MyObject *ObjectCreate();
+ long ObjectRead(MyObject *);
+ void ObjectWrite(MyObject *, long);
+ void ObjectWriteAnother(MyObject *, long);
+}
+
+#if defined(SHARED_LIB)
+
+struct MyObject {
+ long _val;
+ long _another;
+};
+
+#if defined(USE_TSAN_CALLBACKS)
+static void *tag;
+void *(*callback_register_tag)(const char *object_type);
+void *(*callback_assign_tag)(void *addr, void *tag);
+void (*callback_read)(void *addr, void *caller_pc, void *tag);
+void (*callback_write)(void *addr, void *caller_pc, void *tag);
+#endif
+
+void InitializeLibrary() {
+#if defined(USE_TSAN_CALLBACKS)
+ callback_register_tag = (decltype(callback_register_tag))dlsym(RTLD_DEFAULT, "__tsan_external_register_tag");
+ callback_assign_tag = (decltype(callback_assign_tag))dlsym(RTLD_DEFAULT, "__tsan_external_assign_tag");
+ callback_read = (decltype(callback_read))dlsym(RTLD_DEFAULT, "__tsan_external_read");
+ callback_write = (decltype(callback_write))dlsym(RTLD_DEFAULT, "__tsan_external_write");
+ tag = callback_register_tag("MyLibrary::MyObject");
+#endif
+}
+
+MyObject *ObjectCreate() {
+ MyObject *ref = (MyObject *)malloc(sizeof(MyObject));
+#if defined(USE_TSAN_CALLBACKS)
+ callback_assign_tag(ref, tag);
+#endif
+ return ref;
+}
+
+long ObjectRead(MyObject *ref) {
+#if defined(USE_TSAN_CALLBACKS)
+ callback_read(ref, __builtin_return_address(0), tag);
+#endif
+ return ref->_val;
+}
+
+void ObjectWrite(MyObject *ref, long val) {
+#if defined(USE_TSAN_CALLBACKS)
+ callback_write(ref, __builtin_return_address(0), tag);
+#endif
+ ref->_val = val;
+}
+
+void ObjectWriteAnother(MyObject *ref, long val) {
+#if defined(USE_TSAN_CALLBACKS)
+ callback_write(ref, __builtin_return_address(0), tag);
+#endif
+ ref->_another = val;
+}
+
+#else // defined(SHARED_LIB)
+
+int main(int argc, char *argv[]) {
+ InitializeLibrary();
+
+ {
+ MyObjectRef ref = ObjectCreate();
+ std::thread t1([ref]{ ObjectRead(ref); });
+ std::thread t2([ref]{ ObjectRead(ref); });
+ t1.join();
+ t2.join();
+ }
+
+ // CHECK-NOT: WARNING: ThreadSanitizer
+
+ fprintf(stderr, "RR test done\n");
+ // CHECK: RR test done
+
+ {
+ MyObjectRef ref = ObjectCreate();
+ std::thread t1([ref]{ ObjectRead(ref); });
+ std::thread t2([ref]{ ObjectWrite(ref, 66); });
+ t1.join();
+ t2.join();
+ }
+
+ // TEST1: WARNING: ThreadSanitizer: data race
+ // TEST1: {{Write|Read}} of size 8 at
+ // TEST1: Previous {{write|read}} of size 8 at
+ // TEST1: Location is heap block of size 16 at
+
+ // TEST2-NOT: WARNING: ThreadSanitizer
+
+ // TEST3: WARNING: ThreadSanitizer: race on a library object
+ // TEST3: {{Mutating|read-only}} access of object MyLibrary::MyObject at
+ // TEST3: {{ObjectWrite|ObjectRead}}
+ // TEST3: Previous {{mutating|read-only}} access of object MyLibrary::MyObject at
+ // TEST3: {{ObjectWrite|ObjectRead}}
+ // TEST3: Location is MyLibrary::MyObject object of size 16 at
+ // TEST3: {{ObjectCreate}}
+
+ fprintf(stderr, "RW test done\n");
+ // CHECK: RW test done
+
+ {
+ MyObjectRef ref = ObjectCreate();
+ std::thread t1([ref]{ ObjectWrite(ref, 76); });
+ std::thread t2([ref]{ ObjectWriteAnother(ref, 77); });
+ t1.join();
+ t2.join();
+ }
+
+ // TEST1-NOT: WARNING: ThreadSanitizer: data race
+
+ // TEST2-NOT: WARNING: ThreadSanitizer
+
+ // TEST3: WARNING: ThreadSanitizer: race on a library object
+ // TEST3: Mutating access of object MyLibrary::MyObject at
+ // TEST3: {{ObjectWrite|ObjectWriteAnother}}
+ // TEST3: Previous mutating access of object MyLibrary::MyObject at
+ // TEST3: {{ObjectWrite|ObjectWriteAnother}}
+ // TEST3: Location is MyLibrary::MyObject object of size 16 at
+ // TEST3: {{ObjectCreate}}
+
+ fprintf(stderr, "WW test done\n");
+ // CHECK: WW test done
+}
+
+#endif // defined(SHARED_LIB)
diff --git a/test/tsan/Darwin/gcd-after-null.mm b/test/tsan/Darwin/gcd-after-null.mm
new file mode 100644
index 000000000000..7c9913c0fb17
--- /dev/null
+++ b/test/tsan/Darwin/gcd-after-null.mm
@@ -0,0 +1,23 @@
+// Regression test to make sure we don't crash when dispatch_after is called with a NULL queue.
+
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+int main(int argc, const char *argv[]) {
+ fprintf(stderr, "start\n");
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_MSEC)), NULL, ^{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetMain());
+ });
+ });
+ CFRunLoopRun();
+
+ fprintf(stderr, "done\n");
+ return 0;
+}
+
+// CHECK: start
+// CHECK: done
diff --git a/test/tsan/Darwin/gcd-after.mm b/test/tsan/Darwin/gcd-after.mm
index 49b6bc6f71e9..4d66c508554a 100644
--- a/test/tsan/Darwin/gcd-after.mm
+++ b/test/tsan/Darwin/gcd-after.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-apply-race.mm b/test/tsan/Darwin/gcd-apply-race.mm
index 028be1ac5b1c..a7bf663a9fe2 100644
--- a/test/tsan/Darwin/gcd-apply-race.mm
+++ b/test/tsan/Darwin/gcd-apply-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-apply.mm b/test/tsan/Darwin/gcd-apply.mm
index a7dc3740dc7b..d9d256203aeb 100644
--- a/test/tsan/Darwin/gcd-apply.mm
+++ b/test/tsan/Darwin/gcd-apply.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-async-norace.mm b/test/tsan/Darwin/gcd-async-norace.mm
index c7e28b4ce791..83f8c0d6fb58 100644
--- a/test/tsan/Darwin/gcd-async-norace.mm
+++ b/test/tsan/Darwin/gcd-async-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-async-race.mm b/test/tsan/Darwin/gcd-async-race.mm
index 1002a56b0a16..cb8fb4bf5eca 100644
--- a/test/tsan/Darwin/gcd-async-race.mm
+++ b/test/tsan/Darwin/gcd-async-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-barrier-race.mm b/test/tsan/Darwin/gcd-barrier-race.mm
index c42eaebded2b..c11e147ff7cd 100644
--- a/test/tsan/Darwin/gcd-barrier-race.mm
+++ b/test/tsan/Darwin/gcd-barrier-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-barrier.mm b/test/tsan/Darwin/gcd-barrier.mm
index 6f58cae7d8f5..9d4dcb215027 100644
--- a/test/tsan/Darwin/gcd-barrier.mm
+++ b/test/tsan/Darwin/gcd-barrier.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-blocks.mm b/test/tsan/Darwin/gcd-blocks.mm
index e0082605f24e..1aac7e1f2ef6 100644
--- a/test/tsan/Darwin/gcd-blocks.mm
+++ b/test/tsan/Darwin/gcd-blocks.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-data.mm b/test/tsan/Darwin/gcd-data.mm
index a5154dc3598d..d451cf5e8efa 100644
--- a/test/tsan/Darwin/gcd-data.mm
+++ b/test/tsan/Darwin/gcd-data.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-fd.mm b/test/tsan/Darwin/gcd-fd.mm
index 75da9cd4252d..838cf20ca98b 100644
--- a/test/tsan/Darwin/gcd-fd.mm
+++ b/test/tsan/Darwin/gcd-fd.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-groups-destructor.mm b/test/tsan/Darwin/gcd-groups-destructor.mm
index 19c2c9bd147f..05c65c04b665 100644
--- a/test/tsan/Darwin/gcd-groups-destructor.mm
+++ b/test/tsan/Darwin/gcd-groups-destructor.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-groups-leave.mm b/test/tsan/Darwin/gcd-groups-leave.mm
index 6ecf85f5ff0d..49fd8e2101c8 100644
--- a/test/tsan/Darwin/gcd-groups-leave.mm
+++ b/test/tsan/Darwin/gcd-groups-leave.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-groups-norace.mm b/test/tsan/Darwin/gcd-groups-norace.mm
index 64ec386ca40f..e8501692fe80 100644
--- a/test/tsan/Darwin/gcd-groups-norace.mm
+++ b/test/tsan/Darwin/gcd-groups-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-groups-stress.mm b/test/tsan/Darwin/gcd-groups-stress.mm
index 457d9afd9c93..cfe4deb0a518 100644
--- a/test/tsan/Darwin/gcd-groups-stress.mm
+++ b/test/tsan/Darwin/gcd-groups-stress.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-io-barrier-race.mm b/test/tsan/Darwin/gcd-io-barrier-race.mm
index fffc19bd16de..137c3b26700c 100644
--- a/test/tsan/Darwin/gcd-io-barrier-race.mm
+++ b/test/tsan/Darwin/gcd-io-barrier-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-io-barrier.mm b/test/tsan/Darwin/gcd-io-barrier.mm
index fe30138f6036..af92b03c1c70 100644
--- a/test/tsan/Darwin/gcd-io-barrier.mm
+++ b/test/tsan/Darwin/gcd-io-barrier.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-io-cleanup.mm b/test/tsan/Darwin/gcd-io-cleanup.mm
index b15fa0dc2532..570e37dd04cd 100644
--- a/test/tsan/Darwin/gcd-io-cleanup.mm
+++ b/test/tsan/Darwin/gcd-io-cleanup.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-io-race.mm b/test/tsan/Darwin/gcd-io-race.mm
index 0bec28fdb758..99000fca1587 100644
--- a/test/tsan/Darwin/gcd-io-race.mm
+++ b/test/tsan/Darwin/gcd-io-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
// REQUIRES: disabled
diff --git a/test/tsan/Darwin/gcd-io.mm b/test/tsan/Darwin/gcd-io.mm
index 4a1726dac8c7..70ded40417d7 100644
--- a/test/tsan/Darwin/gcd-io.mm
+++ b/test/tsan/Darwin/gcd-io.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-once.mm b/test/tsan/Darwin/gcd-once.mm
index 3e4a5335607c..70e588aaf711 100644
--- a/test/tsan/Darwin/gcd-once.mm
+++ b/test/tsan/Darwin/gcd-once.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-semaphore-norace.mm b/test/tsan/Darwin/gcd-semaphore-norace.mm
index 20bc5724d165..fd5d14655182 100644
--- a/test/tsan/Darwin/gcd-semaphore-norace.mm
+++ b/test/tsan/Darwin/gcd-semaphore-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-serial-queue-norace.mm b/test/tsan/Darwin/gcd-serial-queue-norace.mm
index 95efbb764c53..8754b618df2a 100644
--- a/test/tsan/Darwin/gcd-serial-queue-norace.mm
+++ b/test/tsan/Darwin/gcd-serial-queue-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-cancel.mm b/test/tsan/Darwin/gcd-source-cancel.mm
index 86e1b28a61c4..8aa6f106932f 100644
--- a/test/tsan/Darwin/gcd-source-cancel.mm
+++ b/test/tsan/Darwin/gcd-source-cancel.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-cancel2.mm b/test/tsan/Darwin/gcd-source-cancel2.mm
index 956fe87298bb..92b31d7d0dab 100644
--- a/test/tsan/Darwin/gcd-source-cancel2.mm
+++ b/test/tsan/Darwin/gcd-source-cancel2.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-event.mm b/test/tsan/Darwin/gcd-source-event.mm
index e50cb568de1e..e707b6551000 100644
--- a/test/tsan/Darwin/gcd-source-event.mm
+++ b/test/tsan/Darwin/gcd-source-event.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-event2.mm b/test/tsan/Darwin/gcd-source-event2.mm
index c45d481a0028..b10e4741a3f6 100644
--- a/test/tsan/Darwin/gcd-source-event2.mm
+++ b/test/tsan/Darwin/gcd-source-event2.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-registration.mm b/test/tsan/Darwin/gcd-source-registration.mm
index db22613eddae..d6d339f94dbb 100644
--- a/test/tsan/Darwin/gcd-source-registration.mm
+++ b/test/tsan/Darwin/gcd-source-registration.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-registration2.mm b/test/tsan/Darwin/gcd-source-registration2.mm
index 4431bc9d6898..63657873cae3 100644
--- a/test/tsan/Darwin/gcd-source-registration2.mm
+++ b/test/tsan/Darwin/gcd-source-registration2.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-source-serial.mm b/test/tsan/Darwin/gcd-source-serial.mm
index c0989fcc732a..992203074c15 100644
--- a/test/tsan/Darwin/gcd-source-serial.mm
+++ b/test/tsan/Darwin/gcd-source-serial.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-suspend.mm b/test/tsan/Darwin/gcd-suspend.mm
index 3e8818a2d56e..561e7c0b79c8 100644
--- a/test/tsan/Darwin/gcd-suspend.mm
+++ b/test/tsan/Darwin/gcd-suspend.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-sync-norace.mm b/test/tsan/Darwin/gcd-sync-norace.mm
index c683524f73b6..18bf97320793 100644
--- a/test/tsan/Darwin/gcd-sync-norace.mm
+++ b/test/tsan/Darwin/gcd-sync-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-sync-race.mm b/test/tsan/Darwin/gcd-sync-race.mm
index 650faa4e082c..b7f3266dc09b 100644
--- a/test/tsan/Darwin/gcd-sync-race.mm
+++ b/test/tsan/Darwin/gcd-sync-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/gcd-target-queue-norace.mm b/test/tsan/Darwin/gcd-target-queue-norace.mm
index 36cb1b9298de..fbfa65806bdb 100644
--- a/test/tsan/Darwin/gcd-target-queue-norace.mm
+++ b/test/tsan/Darwin/gcd-target-queue-norace.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/ignore-noninstrumented.mm b/test/tsan/Darwin/ignore-noninstrumented.mm
index 5e4453102a9c..528e07b9a721 100644
--- a/test/tsan/Darwin/ignore-noninstrumented.mm
+++ b/test/tsan/Darwin/ignore-noninstrumented.mm
@@ -3,7 +3,7 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// Check that without the flag, there are false positives.
-// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
+// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
// With ignore_noninstrumented_modules=1, no races are reported.
// RUN: %env_tsan_opts=ignore_noninstrumented_modules=1 %run %t 2>&1 | FileCheck %s
diff --git a/test/tsan/Darwin/ignored-interceptors.mm b/test/tsan/Darwin/ignored-interceptors.mm
index d51314281844..1105132a3cb6 100644
--- a/test/tsan/Darwin/ignored-interceptors.mm
+++ b/test/tsan/Darwin/ignored-interceptors.mm
@@ -6,13 +6,13 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
// Check that without the flag, there are false positives.
-// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
+// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
// With ignore_interceptors_accesses=1, no races are reported.
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0:ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
// With ignore_interceptors_accesses=1, races in user's code are still reported.
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
+// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0:ignore_interceptors_accesses=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/libcxx-call-once.mm b/test/tsan/Darwin/libcxx-call-once.mm
index 5388e495c9c2..ba4615fa3ab9 100644
--- a/test/tsan/Darwin/libcxx-call-once.mm
+++ b/test/tsan/Darwin/libcxx-call-once.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation -std=c++11
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/libcxx-future.mm b/test/tsan/Darwin/libcxx-future.mm
index 902f267ecb89..720c2e089b47 100644
--- a/test/tsan/Darwin/libcxx-future.mm
+++ b/test/tsan/Darwin/libcxx-future.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#include <iostream>
#include <future>
diff --git a/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm b/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm
index eea02dc561e1..a9a3a96f2ada 100644
--- a/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm
+++ b/test/tsan/Darwin/libcxx-shared-ptr-recursive.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/libcxx-shared-ptr-stress.mm b/test/tsan/Darwin/libcxx-shared-ptr-stress.mm
index 7c36729f010f..e5cd7edc6bb7 100644
--- a/test/tsan/Darwin/libcxx-shared-ptr-stress.mm
+++ b/test/tsan/Darwin/libcxx-shared-ptr-stress.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/libcxx-shared-ptr.mm b/test/tsan/Darwin/libcxx-shared-ptr.mm
index 6187c438fec0..057ff22874c9 100644
--- a/test/tsan/Darwin/libcxx-shared-ptr.mm
+++ b/test/tsan/Darwin/libcxx-shared-ptr.mm
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/lit.local.cfg b/test/tsan/Darwin/lit.local.cfg
index a85dfcd24c08..e74e82dbf474 100644
--- a/test/tsan/Darwin/lit.local.cfg
+++ b/test/tsan/Darwin/lit.local.cfg
@@ -7,3 +7,5 @@ root = getRoot(config)
if root.host_os not in ['Darwin']:
config.unsupported = True
+
+config.environment['TSAN_OPTIONS'] += ':ignore_noninstrumented_modules=1'
diff --git a/test/tsan/Darwin/main_tid.mm b/test/tsan/Darwin/main_tid.mm
new file mode 100644
index 000000000000..af658e4b96e5
--- /dev/null
+++ b/test/tsan/Darwin/main_tid.mm
@@ -0,0 +1,46 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
+
+#import <pthread.h>
+#import <stdio.h>
+#import <stdlib.h>
+
+extern "C" {
+void __tsan_on_report(void *report);
+int __tsan_get_report_thread(void *report, unsigned long idx, int *tid,
+ unsigned long *os_id, int *running,
+ const char **name, int *parent_tid, void **trace,
+ unsigned long trace_size);
+}
+
+void __tsan_on_report(void *report) {
+ fprintf(stderr, "__tsan_on_report(%p)\n", report);
+
+ int tid;
+ unsigned long os_id;
+ int running;
+ const char *name;
+ int parent_tid;
+ void *trace[16] = {0};
+ __tsan_get_report_thread(report, 0, &tid, &os_id, &running, &name, &parent_tid, trace, 16);
+ fprintf(stderr, "tid = %d, os_id = %lu\n", tid, os_id);
+}
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+
+ uint64_t threadid;
+ pthread_threadid_np(NULL, &threadid);
+ fprintf(stderr, "pthread_threadid_np = %llu\n", threadid);
+
+ pthread_mutex_t m;
+ pthread_mutex_init(&m, NULL);
+ pthread_mutex_unlock(&m);
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: pthread_threadid_np = [[ADDR:[0-9]+]]
+// CHECK: WARNING: ThreadSanitizer
+// CHECK: tid = 0, os_id = [[ADDR]]
+// CHECK: Done.
diff --git a/test/tsan/Darwin/norace-objcxx-run-time.mm b/test/tsan/Darwin/norace-objcxx-run-time.mm
index 0cf729e7f2d8..1de431a076c7 100644
--- a/test/tsan/Darwin/norace-objcxx-run-time.mm
+++ b/test/tsan/Darwin/norace-objcxx-run-time.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
// Check that we do not report races between:
// - Object retain and initialize
diff --git a/test/tsan/Darwin/objc-double-property.mm b/test/tsan/Darwin/objc-double-property.mm
index 51b10f21c9ca..c99151d28048 100644
--- a/test/tsan/Darwin/objc-double-property.mm
+++ b/test/tsan/Darwin/objc-double-property.mm
@@ -1,7 +1,7 @@
-// RUN: %clangxx_tsan -O0 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_tsan -O1 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_tsan -O2 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_tsan -O3 %s -o %t -framework Foundation && %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O0 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O2 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O3 %s -o %t -framework Foundation && %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/objc-simple.mm b/test/tsan/Darwin/objc-simple.mm
index a8fc35592962..b62d0eb8702d 100644
--- a/test/tsan/Darwin/objc-simple.mm
+++ b/test/tsan/Darwin/objc-simple.mm
@@ -1,7 +1,7 @@
// Test that a simple Obj-C program runs and exits without any warnings.
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
diff --git a/test/tsan/Darwin/workerthreads.mm b/test/tsan/Darwin/workerthreads.mm
new file mode 100644
index 000000000000..18369fd62dd3
--- /dev/null
+++ b/test/tsan/Darwin/workerthreads.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+ print_address("addr=", 1, &global);
+ barrier_init(&barrier, 2);
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ global = 43;
+ barrier_wait(&barrier);
+ });
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ barrier_wait(&barrier);
+ global = 44;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 8
+// CHECK: Previous write of size 8
+// CHECK: Location is global
+// CHECK: Thread {{.*}} is a GCD worker thread
+// CHECK-NOT: failed to restore the stack
+// CHECK: Thread {{.*}} is a GCD worker thread
+// CHECK-NOT: failed to restore the stack
+// CHECK: Done.
diff --git a/test/tsan/Darwin/xpc-cancel.mm b/test/tsan/Darwin/xpc-cancel.mm
new file mode 100644
index 000000000000..5e326b7e4973
--- /dev/null
+++ b/test/tsan/Darwin/xpc-cancel.mm
@@ -0,0 +1,37 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+#import <xpc/xpc.h>
+
+long global;
+
+int main(int argc, const char *argv[]) {
+ fprintf(stderr, "Hello world.\n");
+
+ dispatch_queue_t server_q = dispatch_queue_create("server.queue", DISPATCH_QUEUE_CONCURRENT);
+ xpc_connection_t server_conn = xpc_connection_create(NULL, server_q);
+
+ xpc_connection_set_event_handler(server_conn, ^(xpc_object_t client) {
+ if (client == XPC_ERROR_CONNECTION_INTERRUPTED || client == XPC_ERROR_CONNECTION_INVALID) {
+ global = 43;
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ }
+ });
+ xpc_connection_resume(server_conn);
+
+ global = 42;
+
+ xpc_connection_cancel(server_conn);
+
+ CFRunLoopRun();
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK: Done.
diff --git a/test/tsan/Darwin/xpc-race.mm b/test/tsan/Darwin/xpc-race.mm
index 9141da42e3a0..eaef4e06c1f6 100644
--- a/test/tsan/Darwin/xpc-race.mm
+++ b/test/tsan/Darwin/xpc-race.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %deflake %run %t 2>&1 | FileCheck %s
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <xpc/xpc.h>
diff --git a/test/tsan/Darwin/xpc.mm b/test/tsan/Darwin/xpc.mm
index a939b02ef21a..2d6de269b59f 100644
--- a/test/tsan/Darwin/xpc.mm
+++ b/test/tsan/Darwin/xpc.mm
@@ -1,5 +1,5 @@
// RUN: %clang_tsan %s -o %t -framework Foundation
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
+// RUN: %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <xpc/xpc.h>