1 // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
5 #define NOINLINE __attribute__((noinline))
7 volatile uint64_t objs
[8*2*(2 + 4 + 8)][2];
9 // All this mess is to generate unique stack for each race,
10 // otherwise tsan will suppress similar stacks.
12 static NOINLINE
void access(volatile void *p
, int sz
, int rw
) {
15 case 0: __sanitizer_unaligned_store16((void *)p
, 0); break;
16 case 1: __sanitizer_unaligned_store32((void *)p
, 0); break;
17 case 2: __sanitizer_unaligned_store64((void *)p
, 0); break;
22 case 0: __sanitizer_unaligned_load16((void *)p
); break;
23 case 1: __sanitizer_unaligned_load32((void *)p
); break;
24 case 2: __sanitizer_unaligned_load64((void *)p
); break;
30 static int accesssize(int sz
) {
39 template<int off
, int off2
>
40 static NOINLINE
void access3(bool main
, int sz1
, bool rw
, volatile char *p
) {
57 access2(bool main
, int sz1
, int off2
, bool rw
, volatile char *obj
) {
59 access3
<off
, 0>(main
, sz1
, rw
, obj
);
61 access3
<off
, 1>(main
, sz1
, rw
, obj
);
63 access3
<off
, 2>(main
, sz1
, rw
, obj
);
65 access3
<off
, 3>(main
, sz1
, rw
, obj
);
67 access3
<off
, 4>(main
, sz1
, rw
, obj
);
69 access3
<off
, 5>(main
, sz1
, rw
, obj
);
71 access3
<off
, 6>(main
, sz1
, rw
, obj
);
73 access3
<off
, 7>(main
, sz1
, rw
, obj
);
77 access1(bool main
, int off
, int sz1
, int off2
, bool rw
, char *obj
) {
79 access2
<0>(main
, sz1
, off2
, rw
, obj
);
81 access2
<1>(main
, sz1
, off2
, rw
, obj
);
83 access2
<2>(main
, sz1
, off2
, rw
, obj
);
85 access2
<3>(main
, sz1
, off2
, rw
, obj
);
87 access2
<4>(main
, sz1
, off2
, rw
, obj
);
89 access2
<5>(main
, sz1
, off2
, rw
, obj
);
91 access2
<6>(main
, sz1
, off2
, rw
, obj
);
93 access2
<7>(main
, sz1
, off2
, rw
, obj
);
96 NOINLINE
void Test(bool main
) {
97 volatile uint64_t *obj
= objs
[0];
98 for (int off
= 0; off
< 8; off
++) {
99 for (int sz1
= 0; sz1
< 3; sz1
++) {
100 for (int off2
= 0; off2
< accesssize(sz1
); off2
++) {
101 for (int rw
= 0; rw
< 2; rw
++) {
102 // printf("thr=%d off=%d sz1=%d off2=%d rw=%d p=%p\n",
103 // main, off, sz1, off2, rw, obj);
104 access1(main
, off
, sz1
, off2
, rw
, (char*)obj
);
112 void *Thread(void *p
) {
114 barrier_wait(&barrier
);
120 barrier_init(&barrier
, 2);
122 pthread_create(&th
, 0, Thread
, 0);
124 barrier_wait(&barrier
);
128 // CHECK: WARNING: ThreadSanitizer: data race
129 // CHECK: ThreadSanitizer: reported 224 warnings