1 // RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
8 #define NOINLINE __attribute__((noinline))
10 volatile uint64_t objs
[8*2*(2 + 4 + 8)][2];
13 uint16_t __sanitizer_unaligned_load16(volatile void *addr
);
14 uint32_t __sanitizer_unaligned_load32(volatile void *addr
);
15 uint64_t __sanitizer_unaligned_load64(volatile void *addr
);
16 void __sanitizer_unaligned_store16(volatile void *addr
, uint16_t v
);
17 void __sanitizer_unaligned_store32(volatile void *addr
, uint32_t v
);
18 void __sanitizer_unaligned_store64(volatile void *addr
, uint64_t v
);
21 // All this mess is to generate unique stack for each race,
22 // otherwise tsan will suppress similar stacks.
24 static NOINLINE
void access(volatile char *p
, int sz
, int rw
) {
27 case 0: __sanitizer_unaligned_store16(p
, 0); break;
28 case 1: __sanitizer_unaligned_store32(p
, 0); break;
29 case 2: __sanitizer_unaligned_store64(p
, 0); break;
34 case 0: __sanitizer_unaligned_load16(p
); break;
35 case 1: __sanitizer_unaligned_load32(p
); break;
36 case 2: __sanitizer_unaligned_load64(p
); break;
42 static int accesssize(int sz
) {
51 template<int off
, int off2
>
52 static NOINLINE
void access3(bool main
, int sz1
, bool rw
, volatile char *p
) {
69 access2(bool main
, int sz1
, int off2
, bool rw
, volatile char *obj
) {
71 access3
<off
, 0>(main
, sz1
, rw
, obj
);
73 access3
<off
, 1>(main
, sz1
, rw
, obj
);
75 access3
<off
, 2>(main
, sz1
, rw
, obj
);
77 access3
<off
, 3>(main
, sz1
, rw
, obj
);
79 access3
<off
, 4>(main
, sz1
, rw
, obj
);
81 access3
<off
, 5>(main
, sz1
, rw
, obj
);
83 access3
<off
, 6>(main
, sz1
, rw
, obj
);
85 access3
<off
, 7>(main
, sz1
, rw
, obj
);
89 access1(bool main
, int off
, int sz1
, int off2
, bool rw
, char *obj
) {
91 access2
<0>(main
, sz1
, off2
, rw
, obj
);
93 access2
<1>(main
, sz1
, off2
, rw
, obj
);
95 access2
<2>(main
, sz1
, off2
, rw
, obj
);
97 access2
<3>(main
, sz1
, off2
, rw
, obj
);
99 access2
<4>(main
, sz1
, off2
, rw
, obj
);
101 access2
<5>(main
, sz1
, off2
, rw
, obj
);
103 access2
<6>(main
, sz1
, off2
, rw
, obj
);
105 access2
<7>(main
, sz1
, off2
, rw
, obj
);
108 NOINLINE
void Test(bool main
) {
109 volatile uint64_t *obj
= objs
[0];
110 for (int off
= 0; off
< 8; off
++) {
111 for (int sz1
= 0; sz1
< 3; sz1
++) {
112 for (int off2
= 0; off2
< accesssize(sz1
); off2
++) {
113 for (int rw
= 0; rw
< 2; rw
++) {
114 // printf("thr=%d off=%d sz1=%d off2=%d rw=%d p=%p\n",
115 // main, off, sz1, off2, rw, obj);
116 access1(main
, off
, sz1
, off2
, rw
, (char*)obj
);
124 void *Thread(void *p
) {
133 pthread_create(&th
, 0, Thread
, 0);
138 // CHECK: WARNING: ThreadSanitizer: data race
139 // CHECK: ThreadSanitizer: reported 224 warnings