xref: /llvm-project/compiler-rt/test/tsan/Darwin/external.cpp (revision bcaeed49cb063de9fe504aa29e1cadff8a7be710)
1 // RUN: %clangxx_tsan %p/external-lib.cpp -shared \
2 // RUN:                               -o %t-lib-instrumented.dylib \
3 // RUN:   -install_name @rpath/`basename %t-lib-instrumented.dylib`
4 
5 // RUN: %clangxx_tsan %p/external-lib.cpp -shared -fno-sanitize=thread \
6 // RUN:                               -o %t-lib-noninstrumented.dylib \
7 // RUN:   -install_name @rpath/`basename %t-lib-noninstrumented.dylib`
8 
9 // RUN: %clangxx_tsan %p/external-lib.cpp -shared -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \
10 // RUN:                               -o %t-lib-noninstrumented-callbacks.dylib \
11 // RUN:   -install_name @rpath/`basename %t-lib-noninstrumented-callbacks.dylib`
12 
13 // RUN: %clangxx_tsan %s %t-lib-instrumented.dylib -o %t-lib-instrumented
14 // RUN: %clangxx_tsan %s %t-lib-noninstrumented.dylib -o %t-lib-noninstrumented
15 // RUN: %clangxx_tsan %s %t-lib-noninstrumented-callbacks.dylib -o %t-lib-noninstrumented-callbacks
16 
17 // RUN: %deflake %run %t-lib-instrumented              2>&1 \
18 // RUN:   | FileCheck %s --check-prefix=CHECK --check-prefix=TEST1
19 // RUN:          %run %t-lib-noninstrumented           2>&1 \
20 // RUN:   | FileCheck %s --check-prefix=CHECK --check-prefix=TEST2
21 // RUN: %deflake %run %t-lib-noninstrumented-callbacks 2>&1 \
22 // RUN:   | FileCheck %s --check-prefix=CHECK --check-prefix=TEST3
23 
24 #include <thread>
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 struct MyObject;
30 typedef MyObject *MyObjectRef;
31 extern "C" {
32   void InitializeLibrary();
33   MyObject *ObjectCreate();
34   long ObjectRead(MyObject *);
35   void ObjectWrite(MyObject *, long);
36   void ObjectWriteAnother(MyObject *, long);
37 }
38 
main(int argc,char * argv[])39 int main(int argc, char *argv[]) {
40   InitializeLibrary();
41 
42   {
43     MyObjectRef ref = ObjectCreate();
44     std::thread t1([ref]{ ObjectRead(ref); });
45     std::thread t2([ref]{ ObjectRead(ref); });
46     t1.join();
47     t2.join();
48   }
49 
50   // CHECK-NOT: WARNING: ThreadSanitizer
51 
52   fprintf(stderr, "RR test done\n");
53   // CHECK: RR test done
54 
55   {
56     MyObjectRef ref = ObjectCreate();
57     std::thread t1([ref]{ ObjectRead(ref); });
58     std::thread t2([ref]{ ObjectWrite(ref, 66); });
59     t1.join();
60     t2.join();
61   }
62 
63   // TEST1: WARNING: ThreadSanitizer: data race
64   // TEST1: {{Write|Read}} of size 8 at
65   // TEST1: Previous {{write|read}} of size 8 at
66   // TEST1: Location is heap block of size 16 at
67 
68   // TEST2-NOT: WARNING: ThreadSanitizer
69 
70   // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject
71   // TEST3: {{Modifying|read-only}} access of MyLibrary::MyObject at
72   // TEST3: {{ObjectWrite|ObjectRead}}
73   // TEST3: Previous {{modifying|read-only}} access of MyLibrary::MyObject at
74   // TEST3: {{ObjectWrite|ObjectRead}}
75   // TEST3: Location is MyLibrary::MyObject of size 16 at
76   // TEST3: {{ObjectCreate}}
77   // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectRead}}
78 
79   fprintf(stderr, "RW test done\n");
80   // CHECK: RW test done
81 
82   {
83     MyObjectRef ref = ObjectCreate();
84     std::thread t1([ref]{ ObjectWrite(ref, 76); });
85     std::thread t2([ref]{ ObjectWriteAnother(ref, 77); });
86     t1.join();
87     t2.join();
88   }
89 
90   // TEST1-NOT: WARNING: ThreadSanitizer: data race
91 
92   // TEST2-NOT: WARNING: ThreadSanitizer
93 
94   // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject
95   // TEST3: Modifying access of MyLibrary::MyObject at
96   // TEST3: {{ObjectWrite|ObjectWriteAnother}}
97   // TEST3: Previous modifying access of MyLibrary::MyObject at
98   // TEST3: {{ObjectWrite|ObjectWriteAnother}}
99   // TEST3: Location is MyLibrary::MyObject of size 16 at
100   // TEST3: {{ObjectCreate}}
101   // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectWriteAnother}}
102 
103   fprintf(stderr, "WW test done\n");
104   // CHECK: WW test done
105 }
106