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