summaryrefslogtreecommitdiff
path: root/test/tsan
diff options
context:
space:
mode:
authorKuba Mracek <mracek@apple.com>2017-05-03 16:51:01 +0000
committerKuba Mracek <mracek@apple.com>2017-05-03 16:51:01 +0000
commit4e8f70074eb0b1b8612f770d269791afaac38f74 (patch)
tree145f99b95c637f2424f8340a2352ce2d92a251e1 /test/tsan
parentf5be24d91f5c9975ce71c5343b7c5731ce560d42 (diff)
[tsan] Detect races on modifying accesses in Swift code
This patch allows the Swift compiler to emit calls to `__tsan_external_write` before starting any modifying access, which will cause TSan to detect races on arrays, dictionaries and other classes defined in non-instrumented modules. Races on collections from the Swift standard library and user-defined structs and a frequent cause of subtle bugs and it's important that TSan detects those on top of existing LLVM IR instrumentation, which already detects races in direct memory accesses. Differential Revision: https://reviews.llvm.org/D31630 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@302050 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan')
-rw-r--r--test/tsan/Darwin/external-dups.cc4
-rw-r--r--test/tsan/Darwin/external-swift.cc92
-rw-r--r--test/tsan/Darwin/external.cc14
3 files changed, 102 insertions, 8 deletions
diff --git a/test/tsan/Darwin/external-dups.cc b/test/tsan/Darwin/external-dups.cc
index 79432bac4..ca1eb3e7c 100644
--- a/test/tsan/Darwin/external-dups.cc
+++ b/test/tsan/Darwin/external-dups.cc
@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
- // CHECK: WARNING: ThreadSanitizer: race on a library object
+ // CHECK: WARNING: ThreadSanitizer: race on HelloWorld
t1.join();
t2.join();
}
@@ -46,7 +46,7 @@ int main(int argc, char *argv[]) {
barrier_wait(&barrier);
ExternalWrite(opaque_object);
});
- // CHECK: WARNING: ThreadSanitizer: race on a library object
+ // CHECK: WARNING: ThreadSanitizer: race on HelloWorld
t1.join();
t2.join();
}
diff --git a/test/tsan/Darwin/external-swift.cc b/test/tsan/Darwin/external-swift.cc
new file mode 100644
index 000000000..f6f9e7f4e
--- /dev/null
+++ b/test/tsan/Darwin/external-swift.cc
@@ -0,0 +1,92 @@
+// RUN: %clangxx_tsan %s -o %t
+// RUN: %deflake %run %t 2>&1 | FileCheck %s
+
+#include <thread>
+
+#import "../test.h"
+
+extern "C" {
+void __tsan_write8(void *addr);
+}
+
+static void *tag = (void *)0x1;
+
+__attribute__((no_sanitize("thread")))
+void ExternalWrite(void *addr) {
+ __tsan_external_write(addr, nullptr, tag);
+}
+
+__attribute__((no_sanitize("thread")))
+void RegularWrite(void *addr) {
+ __tsan_write8(addr);
+}
+
+int main(int argc, char *argv[]) {
+ barrier_init(&barrier, 2);
+ fprintf(stderr, "Start.\n");
+ // CHECK: Start.
+
+ {
+ void *opaque_object = malloc(16);
+ std::thread t1([opaque_object] {
+ ExternalWrite(opaque_object);
+ barrier_wait(&barrier);
+ });
+ std::thread t2([opaque_object] {
+ barrier_wait(&barrier);
+ ExternalWrite(opaque_object);
+ });
+ // CHECK: WARNING: ThreadSanitizer: Swift access race
+ // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: SUMMARY: ThreadSanitizer: Swift access race
+ t1.join();
+ t2.join();
+ }
+
+ fprintf(stderr, "external+external test done.\n");
+ // CHECK: external+external test done.
+
+ {
+ void *opaque_object = malloc(16);
+ std::thread t1([opaque_object] {
+ ExternalWrite(opaque_object);
+ barrier_wait(&barrier);
+ });
+ std::thread t2([opaque_object] {
+ barrier_wait(&barrier);
+ RegularWrite(opaque_object);
+ });
+ // CHECK: WARNING: ThreadSanitizer: Swift access race
+ // CHECK: Write of size 8 at {{.*}} by thread {{.*}}
+ // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: SUMMARY: ThreadSanitizer: Swift access race
+ t1.join();
+ t2.join();
+ }
+
+ fprintf(stderr, "external+regular test done.\n");
+ // CHECK: external+regular test done.
+
+ {
+ void *opaque_object = malloc(16);
+ std::thread t1([opaque_object] {
+ RegularWrite(opaque_object);
+ barrier_wait(&barrier);
+ });
+ std::thread t2([opaque_object] {
+ barrier_wait(&barrier);
+ ExternalWrite(opaque_object);
+ });
+ // CHECK: WARNING: ThreadSanitizer: Swift access race
+ // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
+ // CHECK: Previous write of size 8 at {{.*}} by thread {{.*}}
+ // CHECK: SUMMARY: ThreadSanitizer: Swift access race
+ t1.join();
+ t2.join();
+ }
+
+ fprintf(stderr, "regular+external test done.\n");
+ // CHECK: regular+external test done.
+}
+
diff --git a/test/tsan/Darwin/external.cc b/test/tsan/Darwin/external.cc
index 211694ab7..e72281afa 100644
--- a/test/tsan/Darwin/external.cc
+++ b/test/tsan/Darwin/external.cc
@@ -67,13 +67,14 @@ int main(int argc, char *argv[]) {
// TEST2-NOT: WARNING: ThreadSanitizer
- // TEST3: WARNING: ThreadSanitizer: race on a library object
- // TEST3: {{Mutating|read-only}} access of MyLibrary::MyObject at
+ // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject
+ // TEST3: {{Modifying|read-only}} access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectRead}}
- // TEST3: Previous {{mutating|read-only}} access of MyLibrary::MyObject at
+ // TEST3: Previous {{modifying|read-only}} access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectRead}}
// TEST3: Location is MyLibrary::MyObject of size 16 at
// TEST3: {{ObjectCreate}}
+ // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectRead}}
fprintf(stderr, "RW test done\n");
// CHECK: RW test done
@@ -90,13 +91,14 @@ int main(int argc, char *argv[]) {
// TEST2-NOT: WARNING: ThreadSanitizer
- // TEST3: WARNING: ThreadSanitizer: race on a library object
- // TEST3: Mutating access of MyLibrary::MyObject at
+ // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject
+ // TEST3: Modifying access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectWriteAnother}}
- // TEST3: Previous mutating access of MyLibrary::MyObject at
+ // TEST3: Previous modifying access of MyLibrary::MyObject at
// TEST3: {{ObjectWrite|ObjectWriteAnother}}
// TEST3: Location is MyLibrary::MyObject of size 16 at
// TEST3: {{ObjectCreate}}
+ // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectWriteAnother}}
fprintf(stderr, "WW test done\n");
// CHECK: WW test done