aboutsummaryrefslogtreecommitdiff
path: root/test/tsan/Darwin
diff options
context:
space:
mode:
Diffstat (limited to 'test/tsan/Darwin')
-rw-r--r--test/tsan/Darwin/gcd-async-norace.mm26
-rw-r--r--test/tsan/Darwin/gcd-async-race.mm38
-rw-r--r--test/tsan/Darwin/gcd-groups-norace.mm53
-rw-r--r--test/tsan/Darwin/gcd-groups-stress.mm43
-rw-r--r--test/tsan/Darwin/gcd-once.mm55
-rw-r--r--test/tsan/Darwin/gcd-semaphore-norace.mm29
-rw-r--r--test/tsan/Darwin/gcd-serial-queue-norace.mm40
-rw-r--r--test/tsan/Darwin/gcd-sync-norace.mm32
-rw-r--r--test/tsan/Darwin/gcd-sync-race.mm44
-rw-r--r--test/tsan/Darwin/lit.local.cfg9
-rw-r--r--test/tsan/Darwin/objc-race.mm55
-rw-r--r--test/tsan/Darwin/objc-simple.mm13
-rw-r--r--test/tsan/Darwin/osspinlock-norace.cc30
-rw-r--r--test/tsan/Darwin/symbolizer-atos.cc26
-rw-r--r--test/tsan/Darwin/symbolizer-dladdr.cc27
15 files changed, 520 insertions, 0 deletions
diff --git a/test/tsan/Darwin/gcd-async-norace.mm b/test/tsan/Darwin/gcd-async-norace.mm
new file mode 100644
index 000000000000..b987e00656fb
--- /dev/null
+++ b/test/tsan/Darwin/gcd-async-norace.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ global = 43;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-async-race.mm b/test/tsan/Darwin/gcd-async-race.mm
new file mode 100644
index 000000000000..31163f972896
--- /dev/null
+++ b/test/tsan/Darwin/gcd-async-race.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &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();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'global' at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
+// CHECK: Done.
diff --git a/test/tsan/Darwin/gcd-groups-norace.mm b/test/tsan/Darwin/gcd-groups-norace.mm
new file mode 100644
index 000000000000..fb4d804ed8c7
--- /dev/null
+++ b/test/tsan/Darwin/gcd-groups-norace.mm
@@ -0,0 +1,53 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+
+ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ global = 42;
+
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_async(g, q, ^{
+ global = 43;
+ });
+ dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+ global = 44;
+
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ global = 45;
+ dispatch_group_leave(g);
+ });
+ dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+ global = 46;
+
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ global = 47;
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify(g, q, ^{
+ global = 48;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-groups-stress.mm b/test/tsan/Darwin/gcd-groups-stress.mm
new file mode 100644
index 000000000000..62a80085ed8d
--- /dev/null
+++ b/test/tsan/Darwin/gcd-groups-stress.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+void notify_callback(void *context) {
+ // Do nothing.
+}
+
+int main() {
+ NSLog(@"Hello world.");
+
+ dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+
+ for (int i = 0; i < 300000; i++) {
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify(g, q, ^{
+ // Do nothing.
+ });
+ dispatch_release(g);
+ }
+
+ for (int i = 0; i < 300000; i++) {
+ dispatch_group_t g = dispatch_group_create();
+ dispatch_group_enter(g);
+ dispatch_async(q, ^{
+ dispatch_group_leave(g);
+ });
+ dispatch_group_notify_f(g, q, nullptr, &notify_callback);
+ dispatch_release(g);
+ }
+
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
+// CHECK-NOT: CHECK failed
diff --git a/test/tsan/Darwin/gcd-once.mm b/test/tsan/Darwin/gcd-once.mm
new file mode 100644
index 000000000000..17757d203751
--- /dev/null
+++ b/test/tsan/Darwin/gcd-once.mm
@@ -0,0 +1,55 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+static const long kNumThreads = 4;
+
+long global;
+long global2;
+
+static dispatch_once_t once_token;
+static dispatch_once_t once_token2;
+
+void f(void *) {
+ global2 = 42;
+ usleep(100000);
+}
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+
+ dispatch_once(&once_token, ^{
+ global = 42;
+ usleep(100000);
+ });
+ long x = global;
+
+ dispatch_once_f(&once_token2, NULL, f);
+ long x2 = global2;
+
+ fprintf(stderr, "global = %ld\n", x);
+ fprintf(stderr, "global2 = %ld\n", x2);
+ return 0;
+}
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+ barrier_init(&barrier, kNumThreads);
+
+ pthread_t t[kNumThreads];
+ for (int i = 0; i < kNumThreads; i++) {
+ pthread_create(&t[i], 0, Thread, 0);
+ }
+ for (int i = 0; i < kNumThreads; i++) {
+ pthread_join(t[i], 0);
+ }
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-semaphore-norace.mm b/test/tsan/Darwin/gcd-semaphore-norace.mm
new file mode 100644
index 000000000000..cd52a79ca65a
--- /dev/null
+++ b/test/tsan/Darwin/gcd-semaphore-norace.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+ global = 43;
+ dispatch_semaphore_signal(sem);
+ });
+
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
+ global = 44;
+
+ NSLog(@"Done.");
+ return 0;
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-serial-queue-norace.mm b/test/tsan/Darwin/gcd-serial-queue-norace.mm
new file mode 100644
index 000000000000..8f6de27695a5
--- /dev/null
+++ b/test/tsan/Darwin/gcd-serial-queue-norace.mm
@@ -0,0 +1,40 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+
+ dispatch_queue_t q1 = dispatch_queue_create("my.queue1", DISPATCH_QUEUE_CONCURRENT);
+ dispatch_queue_t q2 = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_SERIAL);
+
+ global = 42;
+ for (int i = 0; i < 10; i++) {
+ dispatch_async(q1, ^{
+ for (int i = 0; i < 100; i++) {
+ dispatch_sync(q2, ^{
+ global++;
+ });
+ }
+ });
+ }
+
+ dispatch_barrier_async(q1, ^{
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-sync-norace.mm b/test/tsan/Darwin/gcd-sync-norace.mm
new file mode 100644
index 000000000000..f21cfdedbce1
--- /dev/null
+++ b/test/tsan/Darwin/gcd-sync-norace.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+long global;
+
+static const long nIter = 1000;
+
+int main() {
+ NSLog(@"Hello world.");
+
+ global = 42;
+ for (int i = 0; i < nIter; i++) {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ global = i;
+
+ if (i == nIter - 1) {
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ }
+ });
+ });
+ }
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/gcd-sync-race.mm b/test/tsan/Darwin/gcd-sync-race.mm
new file mode 100644
index 000000000000..62901d9b2612
--- /dev/null
+++ b/test/tsan/Darwin/gcd-sync-race.mm
@@ -0,0 +1,44 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+long global;
+
+int main() {
+ NSLog(@"Hello world.");
+ NSLog(@"addr=%p\n", &global);
+ barrier_init(&barrier, 2);
+
+ dispatch_queue_t q1 = dispatch_queue_create("my.queue1", DISPATCH_QUEUE_CONCURRENT);
+ dispatch_queue_t q2 = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);
+
+ global = 42;
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(q1, ^{
+ global = 43;
+ barrier_wait(&barrier);
+ });
+ });
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ dispatch_sync(q2, ^{
+ barrier_wait(&barrier);
+ global = 44;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+}
+
+// CHECK: Hello world.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'global' at [[ADDR]] (global_race.cc.exe+0x{{[0-9,a-f]+}})
+// CHECK: Done.
diff --git a/test/tsan/Darwin/lit.local.cfg b/test/tsan/Darwin/lit.local.cfg
new file mode 100644
index 000000000000..a85dfcd24c08
--- /dev/null
+++ b/test/tsan/Darwin/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Darwin']:
+ config.unsupported = True
diff --git a/test/tsan/Darwin/objc-race.mm b/test/tsan/Darwin/objc-race.mm
new file mode 100644
index 000000000000..bd93d2f1c2ea
--- /dev/null
+++ b/test/tsan/Darwin/objc-race.mm
@@ -0,0 +1,55 @@
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %deflake %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+#import "../test.h"
+
+@interface MyClass : NSObject {
+ long instance_variable;
+}
+- (void)method:(long)value;
+@end
+
+@implementation MyClass
+
+- (void)method:(long)value {
+ self->instance_variable = value;
+}
+
+@end
+
+int main() {
+ NSLog(@"Hello world.");
+ barrier_init(&barrier, 2);
+
+ MyClass *my_object = [MyClass new];
+ [my_object method:42];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [my_object method:43];
+ barrier_wait(&barrier);
+ });
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ barrier_wait(&barrier);
+ [my_object method:44];
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ });
+ });
+
+ CFRunLoopRun();
+ NSLog(@"Done.");
+ return 0;
+}
+
+// CHECK: Hello world.
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Write of size 8
+// CHECK: #0 -[MyClass method:]
+// CHECK: Write of size 8
+// CHECK: #0 -[MyClass method:]
+// CHECK: Location is heap block
+// CHECK: Done.
diff --git a/test/tsan/Darwin/objc-simple.mm b/test/tsan/Darwin/objc-simple.mm
new file mode 100644
index 000000000000..a4bf1f1beaa0
--- /dev/null
+++ b/test/tsan/Darwin/objc-simple.mm
@@ -0,0 +1,13 @@
+// Test that a simple Obj-C program runs and exits without any warnings.
+
+// RUN: %clang_tsan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1
+
+#import <Foundation/Foundation.h>
+
+int main() {
+ NSLog(@"Hello world");
+}
+
+// CHECK: Hello world
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/osspinlock-norace.cc b/test/tsan/Darwin/osspinlock-norace.cc
new file mode 100644
index 000000000000..2ac3989c223e
--- /dev/null
+++ b/test/tsan/Darwin/osspinlock-norace.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <libkern/OSAtomic.h>
+#include <pthread.h>
+#include <stdio.h>
+
+int Global;
+OSSpinLock lock;
+
+void *Thread(void *x) {
+ OSSpinLockLock(&lock);
+ Global++;
+ OSSpinLockUnlock(&lock);
+ return NULL;
+}
+
+int main() {
+ fprintf(stderr, "Hello world.\n");
+
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread, NULL);
+ pthread_create(&t[1], NULL, Thread, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+
+ fprintf(stderr, "Done.\n");
+}
+
+// CHECK: Hello world.
+// CHECK: Done.
+// CHECK-NOT: WARNING: ThreadSanitizer
diff --git a/test/tsan/Darwin/symbolizer-atos.cc b/test/tsan/Darwin/symbolizer-atos.cc
new file mode 100644
index 000000000000..960fecc98641
--- /dev/null
+++ b/test/tsan/Darwin/symbolizer-atos.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %env_tsan_opts=verbosity=2:external_symbolizer_path=/usr/bin/atos %deflake %run %t | FileCheck %s
+#include "../test.h"
+
+int GlobalData[10];
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+ GlobalData[2] = 42;
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ print_address("addr=", 1, GlobalData);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ GlobalData[2] = 43;
+ barrier_wait(&barrier);
+ pthread_join(t, 0);
+}
+
+// CHECK: Using atos at user-specified path: /usr/bin/atos
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'GlobalData' at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}})
diff --git a/test/tsan/Darwin/symbolizer-dladdr.cc b/test/tsan/Darwin/symbolizer-dladdr.cc
new file mode 100644
index 000000000000..3b213dda85d4
--- /dev/null
+++ b/test/tsan/Darwin/symbolizer-dladdr.cc
@@ -0,0 +1,27 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %env_tsan_opts=verbosity=2:external_symbolizer_path= %deflake %run %t | FileCheck %s
+#include "../test.h"
+
+int GlobalData[10];
+
+void *Thread(void *a) {
+ barrier_wait(&barrier);
+ GlobalData[2] = 42;
+ return 0;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ print_address("addr=", 1, GlobalData);
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ GlobalData[2] = 43;
+ barrier_wait(&barrier);
+ pthread_join(t, 0);
+}
+
+// CHECK: External symbolizer is explicitly disabled.
+// CHECK: Using dladdr symbolizer.
+// CHECK: addr=[[ADDR:0x[0-9,a-f]+]]
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Location is global 'GlobalData' at [[ADDR]] ({{.*}}+0x{{[0-9,a-f]+}})