1 // RUN: %clangxx_tsan %s -o %t
2 // RUN: %deflake %run %t 2>&1 | FileCheck %s
3 
4 #include <thread>
5 
6 #import "../test.h"
7 
8 extern "C" {
9 void __tsan_write8(void *addr);
10 }
11 
12 static void *tag = (void *)0x1;
13 
14 __attribute__((no_sanitize("thread")))
ExternalWrite(void * addr)15 void ExternalWrite(void *addr) {
16   __tsan_external_write(addr, nullptr, tag);
17 }
18 
19 __attribute__((no_sanitize("thread")))
RegularWrite(void * addr)20 void RegularWrite(void *addr) {
21   __tsan_write8(addr);
22 }
23 
main(int argc,char * argv[])24 int main(int argc, char *argv[]) {
25   barrier_init(&barrier, 2);
26   fprintf(stderr, "Start.\n");
27   // CHECK: Start.
28 
29   {
30     void *opaque_object = malloc(16);
31     std::thread t1([opaque_object] {
32       ExternalWrite(opaque_object);
33       barrier_wait(&barrier);
34     });
35     std::thread t2([opaque_object] {
36       barrier_wait(&barrier);
37       ExternalWrite(opaque_object);
38     });
39     // CHECK: WARNING: ThreadSanitizer: Swift access race
40     // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
41     // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
42     // CHECK: SUMMARY: ThreadSanitizer: Swift access race
43     t1.join();
44     t2.join();
45   }
46 
47   fprintf(stderr, "external+external test done.\n");
48   // CHECK: external+external test done.
49 
50   {
51     void *opaque_object = malloc(16);
52     std::thread t1([opaque_object] {
53       ExternalWrite(opaque_object);
54       barrier_wait(&barrier);
55     });
56     std::thread t2([opaque_object] {
57       barrier_wait(&barrier);
58       RegularWrite(opaque_object);
59     });
60     // CHECK: WARNING: ThreadSanitizer: Swift access race
61     // CHECK: Write of size 8 at {{.*}} by thread {{.*}}
62     // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}}
63     // CHECK: SUMMARY: ThreadSanitizer: Swift access race
64     t1.join();
65     t2.join();
66   }
67 
68   fprintf(stderr, "external+regular test done.\n");
69   // CHECK: external+regular test done.
70 
71   {
72     void *opaque_object = malloc(16);
73     std::thread t1([opaque_object] {
74       RegularWrite(opaque_object);
75       barrier_wait(&barrier);
76     });
77     std::thread t2([opaque_object] {
78       barrier_wait(&barrier);
79       ExternalWrite(opaque_object);
80     });
81     // CHECK: WARNING: ThreadSanitizer: Swift access race
82     // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}}
83     // CHECK: Previous write of size 8 at {{.*}} by thread {{.*}}
84     // CHECK: SUMMARY: ThreadSanitizer: Swift access race
85     t1.join();
86     t2.join();
87   }
88 
89   fprintf(stderr, "regular+external test done.\n");
90   // CHECK: regular+external test done.
91 }
92 
93