[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / PCH / thread-safety-attrs.cpp
blobd33917e518597787d0f57b60d902055cb77a3048
1 // Test this without pch.
2 // RUN: %clang_cc1 -include %s -fsyntax-only -verify -Wthread-safety -std=c++11 %s
4 // Test with pch.
5 // RUN: %clang_cc1 -emit-pch -o %t %s -std=c++11
6 // RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify -Wthread-safety -std=c++11 %s
8 #ifndef HEADER
9 #define HEADER
11 #define LOCKABLE __attribute__ ((lockable))
12 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
13 #define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
14 #define GUARDED_VAR __attribute__ ((guarded_var))
15 #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
16 #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
17 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
18 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
19 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
20 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
21 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
22 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
23 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
24 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
25 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
26 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
27 __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
28 #define SHARED_LOCKS_REQUIRED(...) \
29 __attribute__ ((shared_locks_required(__VA_ARGS__)))
30 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
33 class __attribute__((lockable)) Mutex {
34 public:
35 void Lock() __attribute__((exclusive_lock_function));
36 void ReaderLock() __attribute__((shared_lock_function));
37 void Unlock() __attribute__((unlock_function));
38 bool TryLock() __attribute__((exclusive_trylock_function(true)));
39 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
40 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
43 class __attribute__((scoped_lockable)) MutexLock {
44 public:
45 MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
46 ~MutexLock() __attribute__((unlock_function));
49 class __attribute__((scoped_lockable)) ReaderMutexLock {
50 public:
51 ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
52 ~ReaderMutexLock() __attribute__((unlock_function));
55 class SCOPED_LOCKABLE ReleasableMutexLock {
56 public:
57 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
58 ~ReleasableMutexLock() UNLOCK_FUNCTION();
60 void Release() UNLOCK_FUNCTION();
64 // The universal lock, written "*", allows checking to be selectively turned
65 // off for a particular piece of code.
66 void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
67 void endNoWarnOnReads() UNLOCK_FUNCTION("*");
68 void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
69 void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
72 // For testing handling of smart pointers.
73 template<class T>
74 class SmartPtr {
75 public:
76 SmartPtr(T* p) : ptr_(p) { }
77 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
78 ~SmartPtr();
80 T* get() const { return ptr_; }
81 T* operator->() const { return ptr_; }
82 T& operator*() const { return *ptr_; }
84 private:
85 T* ptr_;
89 // For testing destructor calls and cleanup.
90 class MyString {
91 public:
92 MyString(const char* s);
93 ~MyString();
98 Mutex sls_mu;
100 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
101 int sls_guard_var __attribute__((guarded_var)) = 0;
102 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
104 bool getBool();
106 class MutexWrapper {
107 public:
108 Mutex mu;
109 int x __attribute__((guarded_by(mu)));
110 void MyLock() __attribute__((exclusive_lock_function(mu)));
113 #else
115 MutexWrapper sls_mw;
117 void sls_fun_0() {
118 sls_mw.mu.Lock();
119 sls_mw.x = 5;
120 sls_mw.mu.Unlock();
123 void sls_fun_2() {
124 sls_mu.Lock();
125 int x = sls_guard_var;
126 sls_mu.Unlock();
129 void sls_fun_3() {
130 sls_mu.Lock();
131 sls_guard_var = 2;
132 sls_mu.Unlock();
135 void sls_fun_4() {
136 sls_mu2.Lock();
137 sls_guard_var = 2;
138 sls_mu2.Unlock();
141 void sls_fun_5() {
142 sls_mu.Lock();
143 int x = sls_guardby_var;
144 sls_mu.Unlock();
147 void sls_fun_6() {
148 sls_mu.Lock();
149 sls_guardby_var = 2;
150 sls_mu.Unlock();
153 void sls_fun_7() {
154 sls_mu.Lock();
155 sls_mu2.Lock();
156 sls_mu2.Unlock();
157 sls_mu.Unlock();
160 void sls_fun_8() {
161 sls_mu.Lock();
162 if (getBool())
163 sls_mu.Unlock();
164 else
165 sls_mu.Unlock();
168 void sls_fun_9() {
169 if (getBool())
170 sls_mu.Lock();
171 else
172 sls_mu.Lock();
173 sls_mu.Unlock();
176 void sls_fun_good_6() {
177 if (getBool()) {
178 sls_mu.Lock();
179 } else {
180 if (getBool()) {
181 getBool(); // EMPTY
182 } else {
183 getBool(); // EMPTY
185 sls_mu.Lock();
187 sls_mu.Unlock();
190 void sls_fun_good_7() {
191 sls_mu.Lock();
192 while (getBool()) {
193 sls_mu.Unlock();
194 if (getBool()) {
195 if (getBool()) {
196 sls_mu.Lock();
197 continue;
200 sls_mu.Lock();
202 sls_mu.Unlock();
205 void sls_fun_good_8() {
206 sls_mw.MyLock();
207 sls_mw.mu.Unlock();
210 void sls_fun_bad_1() {
211 sls_mu.Unlock(); // \
212 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
215 void sls_fun_bad_2() {
216 sls_mu.Lock(); // expected-note{{mutex acquired here}}
217 sls_mu.Lock(); // \
218 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
219 sls_mu.Unlock();
222 void sls_fun_bad_3() {
223 sls_mu.Lock(); // expected-note {{mutex acquired here}}
224 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
226 void sls_fun_bad_4() {
227 if (getBool())
228 sls_mu.Lock(); // expected-note{{mutex acquired here}}
229 else
230 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
231 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
232 // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
234 void sls_fun_bad_5() {
235 sls_mu.Lock(); // expected-note {{mutex acquired here}}
236 if (getBool())
237 sls_mu.Unlock();
238 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
240 void sls_fun_bad_6() {
241 if (getBool()) {
242 sls_mu.Lock(); // expected-note {{mutex acquired here}}
243 } else {
244 if (getBool()) {
245 getBool(); // EMPTY
246 } else {
247 getBool(); // EMPTY
250 sls_mu.Unlock(); // \
251 expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
252 expected-warning{{releasing mutex 'sls_mu' that was not held}}
255 void sls_fun_bad_7() {
256 sls_mu.Lock();
257 while (getBool()) { // \
258 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
259 sls_mu.Unlock();
260 if (getBool()) {
261 if (getBool()) {
262 continue;
265 sls_mu.Lock(); // expected-note {{mutex acquired here}}
267 sls_mu.Unlock();
270 void sls_fun_bad_8() {
271 sls_mu.Lock(); // expected-note{{mutex acquired here}}
273 do {
274 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
275 } while (getBool());
278 void sls_fun_bad_9() {
279 do {
280 sls_mu.Lock(); // \
281 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
282 // expected-note{{mutex acquired here}}
283 } while (getBool());
284 sls_mu.Unlock();
287 void sls_fun_bad_10() {
288 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
289 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
290 sls_mu.Unlock();
292 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
294 void sls_fun_bad_11() {
295 while (getBool()) { // \
296 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
297 sls_mu.Lock(); // expected-note {{mutex acquired here}}
299 sls_mu.Unlock(); // \
300 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
303 void sls_fun_bad_12() {
304 sls_mu.Lock(); // expected-note {{mutex acquired here}}
305 while (getBool()) {
306 sls_mu.Unlock();
307 if (getBool()) {
308 if (getBool()) {
309 break;
312 sls_mu.Lock();
314 sls_mu.Unlock(); // \
315 expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
316 expected-warning{{releasing mutex 'sls_mu' that was not held}}
319 #endif