1 // RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -fno-exceptions -o %t && %run %t
2 //
3 // Use -fno-exceptions to turn off exceptions to avoid instrumenting
4 // __cxa_begin_catch, std::terminate and __gxx_personality_v0.
5 //
6 // TODO: Support builtin atomics. For example, https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
7 // DFSan instrumentation pass cannot identify builtin callsites yet.
8 
9 #include <sanitizer/dfsan_interface.h>
10 
11 #include <assert.h>
12 #include <atomic>
13 #include <pthread.h>
14 
15 std::atomic<int> atomic_i{0};
16 
17 static void *ThreadFn(void *arg) {
18   if ((size_t)arg % 2) {
19     int i = 10;
20     dfsan_set_label(8, (void *)&i, sizeof(i));
21     atomic_i.store(i, std::memory_order_relaxed);
22 
23     return 0;
24   }
25   int j = atomic_i.load();
26   assert(dfsan_get_label(j) == 0 || dfsan_get_label(j) == 2);
27 
28   return 0;
29 }
30 
31 int main(void) {
32   int i = 10;
33   dfsan_set_label(2, (void *)&i, sizeof(i));
34   atomic_i.store(i, std::memory_order_relaxed);
35   const int kNumThreads = 24;
36   pthread_t t[kNumThreads];
37   for (int i = 0; i < kNumThreads; ++i) {
38     pthread_create(&t[i], 0, ThreadFn, (void *)i);
39   }
40   for (int i = 0; i < kNumThreads; ++i) {
41     pthread_join(t[i], 0);
42   }
43   return 0;
44 }
45