1 // RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s 2 #include <pthread.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <stdint.h> 6 7 uint64_t objs[8*3*3*2][3]; 8 9 extern "C" { 10 uint16_t __tsan_unaligned_read2(void *addr); 11 uint32_t __tsan_unaligned_read4(void *addr); 12 uint64_t __tsan_unaligned_read8(void *addr); 13 void __tsan_unaligned_write2(void *addr, uint16_t v); 14 void __tsan_unaligned_write4(void *addr, uint32_t v); 15 void __tsan_unaligned_write8(void *addr, uint64_t v); 16 } 17 18 static void access(char *p, int sz, int rw) { 19 if (rw) { 20 switch (sz) { 21 case 0: __tsan_unaligned_write2(p, 0); break; 22 case 1: __tsan_unaligned_write4(p, 0); break; 23 case 2: __tsan_unaligned_write8(p, 0); break; 24 default: exit(1); 25 } 26 } else { 27 switch (sz) { 28 case 0: __tsan_unaligned_read2(p); break; 29 case 1: __tsan_unaligned_read4(p); break; 30 case 2: __tsan_unaligned_read8(p); break; 31 default: exit(1); 32 } 33 } 34 } 35 36 static int accesssize(int sz) { 37 switch (sz) { 38 case 0: return 2; 39 case 1: return 4; 40 case 2: return 8; 41 } 42 exit(1); 43 } 44 45 void Test(bool main) { 46 uint64_t *obj = objs[0]; 47 for (int off = 0; off < 8; off++) { 48 for (int sz1 = 0; sz1 < 3; sz1++) { 49 for (int sz2 = 0; sz2 < 3; sz2++) { 50 for (int rw = 0; rw < 2; rw++) { 51 char *p = (char*)obj + off; 52 if (main) { 53 // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n", 54 // main, off, sz1, sz2, rw, p); 55 access(p, sz1, true); 56 } else { 57 p += accesssize(sz1); 58 // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n", 59 // main, off, sz1, sz2, rw, p); 60 access(p, sz2, rw); 61 } 62 obj += 3; 63 } 64 } 65 } 66 } 67 } 68 69 void *Thread(void *p) { 70 (void)p; 71 Test(false); 72 return 0; 73 } 74 75 int main() { 76 pthread_t th; 77 pthread_create(&th, 0, Thread, 0); 78 Test(true); 79 pthread_join(th, 0); 80 printf("OK\n"); 81 } 82 83 // CHECK-NOT: WARNING: ThreadSanitizer: 84 // CHECK: OK 85