aboutsummaryrefslogtreecommitdiff
path: root/lib/tsan/lit_tests/unaligned_norace.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan/lit_tests/unaligned_norace.cc')
-rw-r--r--lib/tsan/lit_tests/unaligned_norace.cc84
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/tsan/lit_tests/unaligned_norace.cc b/lib/tsan/lit_tests/unaligned_norace.cc
new file mode 100644
index 000000000000..792224b80126
--- /dev/null
+++ b/lib/tsan/lit_tests/unaligned_norace.cc
@@ -0,0 +1,84 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+uint64_t objs[8*3*3*2][3];
+
+extern "C" {
+uint16_t __tsan_unaligned_read2(void *addr);
+uint32_t __tsan_unaligned_read4(void *addr);
+uint64_t __tsan_unaligned_read8(void *addr);
+void __tsan_unaligned_write2(void *addr, uint16_t v);
+void __tsan_unaligned_write4(void *addr, uint32_t v);
+void __tsan_unaligned_write8(void *addr, uint64_t v);
+}
+
+static void access(char *p, int sz, int rw) {
+ if (rw) {
+ switch (sz) {
+ case 0: __tsan_unaligned_write2(p, 0); break;
+ case 1: __tsan_unaligned_write4(p, 0); break;
+ case 2: __tsan_unaligned_write8(p, 0); break;
+ default: exit(1);
+ }
+ } else {
+ switch (sz) {
+ case 0: __tsan_unaligned_read2(p); break;
+ case 1: __tsan_unaligned_read4(p); break;
+ case 2: __tsan_unaligned_read8(p); break;
+ default: exit(1);
+ }
+ }
+}
+
+static int accesssize(int sz) {
+ switch (sz) {
+ case 0: return 2;
+ case 1: return 4;
+ case 2: return 8;
+ }
+ exit(1);
+}
+
+void Test(bool main) {
+ uint64_t *obj = objs[0];
+ for (int off = 0; off < 8; off++) {
+ for (int sz1 = 0; sz1 < 3; sz1++) {
+ for (int sz2 = 0; sz2 < 3; sz2++) {
+ for (int rw = 0; rw < 2; rw++) {
+ char *p = (char*)obj + off;
+ if (main) {
+ // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
+ // main, off, sz1, sz2, rw, p);
+ access(p, sz1, true);
+ } else {
+ p += accesssize(sz1);
+ // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
+ // main, off, sz1, sz2, rw, p);
+ access(p, sz2, rw);
+ }
+ obj += 3;
+ }
+ }
+ }
+ }
+}
+
+void *Thread(void *p) {
+ (void)p;
+ Test(false);
+ return 0;
+}
+
+int main() {
+ pthread_t th;
+ pthread_create(&th, 0, Thread, 0);
+ Test(true);
+ pthread_join(th, 0);
+ printf("OK\n");
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: OK