1// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s 2#include <pthread.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <stdint.h> 6 7uint64_t objs[8*3*3*2][3]; 8 9extern "C" { 10uint16_t __tsan_unaligned_read2(void *addr); 11uint32_t __tsan_unaligned_read4(void *addr); 12uint64_t __tsan_unaligned_read8(void *addr); 13void __tsan_unaligned_write2(void *addr, uint16_t v); 14void __tsan_unaligned_write4(void *addr, uint32_t v); 15void __tsan_unaligned_write8(void *addr, uint64_t v); 16} 17 18static 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 36static 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 45void 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 69void *Thread(void *p) { 70 (void)p; 71 Test(false); 72 return 0; 73} 74 75int 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