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
29struct MyObject;
30typedef MyObject *MyObjectRef;
31extern "C" {
32 void InitializeLibrary();
33 MyObject *ObjectCreate();
34 long ObjectRead(MyObject *);
35 void ObjectWrite(MyObject *, long);
36 void ObjectWriteAnother(MyObject *, long);
37}
38
39int 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, format: "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, format: "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, format: "WW test done\n");
104 // CHECK: WW test done
105}
106

source code of compiler-rt/test/tsan/Darwin/external.cpp