blob: cbc947787d786341ad9255b304c852b18362cb40 [file] [log] [blame]
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
2
3
4//-----------------------------------------//
5// Helper fields
6//-----------------------------------------//
7
8
9class __attribute__((lockable)) Mutex {
10 public:
11 void Lock() __attribute__((exclusive_lock_function));
12 void ReaderLock() __attribute__((shared_lock_function));
13 void Unlock() __attribute__((unlock_function));
14 bool TryLock() __attribute__((exclusive_trylock_function(true)));
15 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
16 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
17};
18
19
20Mutex sls_mu;
21
22Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
23int sls_guard_var __attribute__((guarded_var)) = 0;
24int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
25
26bool getBool();
27
28class MutexWrapper {
29public:
30 Mutex mu;
31 // int x __attribute__((guarded_by(mu))); // FIXME: scoping error
32};
33
34MutexWrapper sls_mw;
35
36void sls_fun_0() {
37 sls_mw.mu.Lock();
38 // sls_mw.x = 5; // FIXME: turn mu into sls_mw.mu
39 sls_mw.mu.Unlock();
40}
41
42
43void sls_fun_2() {
44 sls_mu.Lock();
45 int x = sls_guard_var;
46 sls_mu.Unlock();
47}
48
49void sls_fun_3() {
50 sls_mu.Lock();
51 sls_guard_var = 2;
52 sls_mu.Unlock();
53}
54
55void sls_fun_4() {
56 sls_mu2.Lock();
57 sls_guard_var = 2;
58 sls_mu2.Unlock();
59}
60
61void sls_fun_5() {
62 sls_mu.Lock();
63 int x = sls_guardby_var;
64 sls_mu.Unlock();
65}
66
67void sls_fun_6() {
68 sls_mu.Lock();
69 sls_guardby_var = 2;
70 sls_mu.Unlock();
71}
72
73void sls_fun_7() {
74 sls_mu.Lock();
75 sls_mu2.Lock();
76 sls_mu2.Unlock();
77 sls_mu.Unlock();
78}
79
80void sls_fun_8() {
81 sls_mu.Lock();
82 if (getBool())
83 sls_mu.Unlock();
84 else
85 sls_mu.Unlock();
86}
87
88void sls_fun_9() {
89 if (getBool())
90 sls_mu.Lock();
91 else
92 sls_mu.Lock();
93 sls_mu.Unlock();
94}
95
96void sls_fun_good_6() {
97 if (getBool()) {
98 sls_mu.Lock();
99 } else {
100 if (getBool()) {
101 getBool(); // EMPTY
102 } else {
103 getBool(); // EMPTY
104 }
105 sls_mu.Lock();
106 }
107 sls_mu.Unlock();
108}
109
110void sls_fun_good_7() {
111 sls_mu.Lock();
112 while (getBool()) {
113 sls_mu.Unlock();
114 if (getBool()) {
115 if (getBool()) {
116 sls_mu.Lock();
117 continue;
118 }
119 }
120 sls_mu.Lock();
121 }
122 sls_mu.Unlock();
123}
124
125void sls_fun_bad_1() {
126 sls_mu.Unlock(); // \
127 expected-warning {{unlocking 'sls_mu' that was not acquired}}
128}
129
130void sls_fun_bad_2() {
131 sls_mu.Lock();
132 sls_mu.Lock(); // \
133 expected-warning {{locking 'sls_mu' that is already acquired}}
134 sls_mu.Unlock();
135}
136
137void sls_fun_bad_3() {
138 sls_mu.Lock(); // \
139 expected-warning {{lock 'sls_mu' is not released at the end of function 'sls_fun_bad_3'}}
140}
141
142void sls_fun_bad_4() {
143 if (getBool())
144 sls_mu.Lock(); // \
145 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
146 else
147 sls_mu2.Lock(); // \
148 expected-warning {{lock 'sls_mu2' is not released at the end of its scope}}
149}
150
151void sls_fun_bad_5() {
152 sls_mu.Lock(); // \
153 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
154 if (getBool())
155 sls_mu.Unlock();
156}
157
158void sls_fun_bad_6() {
159 if (getBool()) {
160 sls_mu.Lock(); // \
161 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
162 } else {
163 if (getBool()) {
164 getBool(); // EMPTY
165 } else {
166 getBool(); // EMPTY
167 }
168 }
169 sls_mu.Unlock(); // \
170 expected-warning {{unlocking 'sls_mu' that was not acquired}}
171}
172
173void sls_fun_bad_7() {
174 sls_mu.Lock();
175 while (getBool()) { // \
176 expected-warning {{expecting lock 'sls_mu' to be held at start of each loop}}
177 sls_mu.Unlock();
178 if (getBool()) {
179 if (getBool()) {
180 continue;
181 }
182 }
183 sls_mu.Lock(); // \
184 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
185 }
186 sls_mu.Unlock();
187}
188
189void sls_fun_bad_8() {
190 sls_mu.Lock();
191 do {
192 sls_mu.Unlock(); // \
193 expected-warning {{expecting lock 'sls_mu' to be held at start of each loop}}
194 } while (getBool());
195}
196
197void sls_fun_bad_9() {
198 do {
199 sls_mu.Lock(); // \
200 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
201 } while (getBool());
202 sls_mu.Unlock();
203}
204
205void sls_fun_bad_10() {
206 sls_mu.Lock(); // \
207 expected-warning {{lock 'sls_mu' is not released at the end of function 'sls_fun_bad_10'}}
208 while(getBool()) { // \
209 expected-warning {{expecting lock 'sls_mu' to be held at start of each loop}}
210 sls_mu.Unlock();
211 }
212}
213
214void sls_fun_bad_11() {
215 while (getBool()) {
216 sls_mu.Lock(); // \
217 expected-warning {{lock 'sls_mu' is not released at the end of its scope}}
218 }
219 sls_mu.Unlock(); // \
220 expected-warning {{unlocking 'sls_mu' that was not acquired}}
221}
222
223
224//-----------------------------------------//
225// Handling lock expressions in attribute args
226// -------------------------------------------//
227
228Mutex aa_mu;
229
230class GlobalLocker {
231public:
232 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
233 void globalUnlock() __attribute__((unlock_function(aa_mu)));
234};
235
236GlobalLocker glock;
237
238void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
239void aa_elr_fun() { }
240
241void aa_fun_1() {
242 glock.globalLock();
243 glock.globalUnlock();
244}
245
246void aa_fun_2() {
247 aa_mu.Lock();
248 aa_elr_fun();
249 aa_mu.Unlock();
250}
251
252void aa_fun_bad_1() {
253 glock.globalUnlock(); // \
254 expected-warning {{unlocking 'aa_mu' that was not acquired}}
255}
256
257void aa_fun_bad_2() {
258 glock.globalLock();
259 glock.globalLock(); // \
260 expected-warning {{locking 'aa_mu' that is already acquired}}
261 glock.globalUnlock();
262}
263
264void aa_fun_bad_3() {
265 glock.globalLock(); // \
266 expected-warning {{lock 'aa_mu' is not released at the end of function 'aa_fun_bad_3'}}
267}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000268
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000269//--------------------------------------------------//
270// Regression tests for unusual method names
271//--------------------------------------------------//
272
273Mutex wmu;
274
275// Test diagnostics for other method names.
276class WeirdMethods {
277 WeirdMethods() {
278 wmu.Lock(); // \
279 expected-warning {{lock 'wmu' is not released at the end of function 'WeirdMethods'}}
280 }
281 ~WeirdMethods() {
282 wmu.Lock(); // \
283 expected-warning {{lock 'wmu' is not released at the end of function '~WeirdMethods'}}
284 }
285 void operator++() {
286 wmu.Lock(); // \
287 expected-warning {{lock 'wmu' is not released at the end of function 'operator++'}}
288 }
289 operator int*() {
290 wmu.Lock(); // \
291 expected-warning {{lock 'wmu' is not released at the end of function 'operator int *'}}
292 return 0;
293 }
294};
295
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000296//-----------------------------------------------//
297// Errors for guarded by or guarded var variables
298// ----------------------------------------------//
299
300int *pgb_gvar __attribute__((pt_guarded_var));
301int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
302
303class PGBFoo {
304 public:
305 int x;
306 int *pgb_field __attribute__((guarded_by(sls_mu2)))
307 __attribute__((pt_guarded_by(sls_mu)));
308 void testFoo() {
309 pgb_field = &x; // \
310 expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}}
311 *pgb_field = x; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
312 expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
313 x = *pgb_field; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
314 expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
315 (*pgb_field)++; // expected-warning {{accessing variable 'pgb_field' requires lock 'sls_mu2'}} \
316 expected-warning {{accessing the value pointed to by 'pgb_field' requires lock 'sls_mu'}}
317 }
318};
319
320class GBFoo {
321 public:
322 int gb_field __attribute__((guarded_by(sls_mu)));
323
324 void testFoo() {
325 gb_field = 0; // \
326 expected-warning {{accessing variable 'gb_field' requires lock 'sls_mu'}}
327 }
328};
329
330GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
331
332void gb_fun_0() {
333 sls_mu.Lock();
334 int x = *pgb_var;
335 sls_mu.Unlock();
336}
337
338void gb_fun_1() {
339 sls_mu.Lock();
340 *pgb_var = 2;
341 sls_mu.Unlock();
342}
343
344void gb_fun_2() {
345 int x;
346 pgb_var = &x;
347}
348
349void gb_fun_3() {
350 int *x = pgb_var;
351}
352
353void gb_bad_0() {
354 sls_guard_var = 1; // \
355 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
356}
357
358void gb_bad_1() {
359 int x = sls_guard_var; // \
360 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
361}
362
363void gb_bad_2() {
364 sls_guardby_var = 1; // \
365 expected-warning {{accessing variable 'sls_guardby_var' requires lock 'sls_mu'}}
366}
367
368void gb_bad_3() {
369 int x = sls_guardby_var; // \
370 expected-warning {{accessing variable 'sls_guardby_var' requires lock 'sls_mu'}}
371}
372
373void gb_bad_4() {
374 *pgb_gvar = 1; // \
375 expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
376}
377
378void gb_bad_5() {
379 int x = *pgb_gvar; // \
380 expected-warning {{accessing the value pointed to by 'pgb_gvar' requires some lock}}
381}
382
383void gb_bad_6() {
384 *pgb_var = 1; // \
385 expected-warning {{accessing the value pointed to by 'pgb_var' requires lock 'sls_mu'}}
386}
387
388void gb_bad_7() {
389 int x = *pgb_var; // \
390 expected-warning {{accessing the value pointed to by 'pgb_var' requires lock 'sls_mu'}}
391}
392
393void gb_bad_8() {
394 GBFoo G;
395 G.gb_field = 0; // \
396 expected-warning {{accessing variable 'gb_field' requires lock 'sls_mu'}}
397}
398
399void gb_bad_9() {
400 sls_guard_var++; // \
401 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
402 sls_guard_var--; // \
403 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
404 ++sls_guard_var; // \
405 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
406 --sls_guard_var; // \
407 expected-warning {{accessing variable 'sls_guard_var' requires some lock}}
408}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000409