blob: 5107d5b9a046cb378c0a2a15dd8759aeb3ee7b81 [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;
Caitlin Sadowski194418f2011-09-14 20:00:24 +000031 int x __attribute__((guarded_by(mu)));
32 void MyLock() __attribute__((exclusive_lock_function(mu)));
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000033};
34
35MutexWrapper sls_mw;
36
37void sls_fun_0() {
38 sls_mw.mu.Lock();
Caitlin Sadowski194418f2011-09-14 20:00:24 +000039 sls_mw.x = 5;
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000040 sls_mw.mu.Unlock();
41}
42
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +000043void 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
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000125void sls_fun_good_8() {
126 sls_mw.MyLock();
127 sls_mw.mu.Unlock();
128}
129
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000130void sls_fun_bad_1() {
131 sls_mu.Unlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000132 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000133}
134
135void sls_fun_bad_2() {
136 sls_mu.Lock();
137 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000138 // expected-warning{{locking 'sls_mu' that is already locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000139 sls_mu.Unlock();
140}
141
142void sls_fun_bad_3() {
143 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000144 // expected-warning{{mutex 'sls_mu' is still held at the end of function 'sls_fun_bad_3'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000145}
146
147void sls_fun_bad_4() {
148 if (getBool())
149 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000150 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000151 else
152 sls_mu2.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000153 // expected-warning{{mutex 'sls_mu2' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000154}
155
156void sls_fun_bad_5() {
157 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000158 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000159 if (getBool())
160 sls_mu.Unlock();
161}
162
163void sls_fun_bad_6() {
164 if (getBool()) {
165 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000166 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000167 } else {
168 if (getBool()) {
169 getBool(); // EMPTY
170 } else {
171 getBool(); // EMPTY
172 }
173 }
174 sls_mu.Unlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000175 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000176}
177
178void sls_fun_bad_7() {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000179 sls_mu.Lock(); // \
180 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
181 while (getBool()) {
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000182 sls_mu.Unlock();
183 if (getBool()) {
184 if (getBool()) {
185 continue;
186 }
187 }
188 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000189 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000190 }
191 sls_mu.Unlock();
192}
193
194void sls_fun_bad_8() {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000195 sls_mu.Lock(); // \
196 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000197 do {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000198 sls_mu.Unlock();
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000199 } while (getBool());
200}
201
202void sls_fun_bad_9() {
203 do {
204 sls_mu.Lock(); // \
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000205 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000206 } while (getBool());
207 sls_mu.Unlock();
208}
209
210void sls_fun_bad_10() {
211 sls_mu.Lock(); // \
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000212 // expected-warning{{mutex 'sls_mu' is still held at the end of function 'sls_fun_bad_10'}} \
213 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
214 while(getBool()) {
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000215 sls_mu.Unlock();
216 }
217}
218
219void sls_fun_bad_11() {
220 while (getBool()) {
221 sls_mu.Lock(); // \
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000222 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000223 }
224 sls_mu.Unlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000225 // expected-warning{{unlocking 'sls_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000226}
227
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000228//-----------------------------------------//
229// Handling lock expressions in attribute args
230// -------------------------------------------//
231
232Mutex aa_mu;
233
234class GlobalLocker {
235public:
236 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
237 void globalUnlock() __attribute__((unlock_function(aa_mu)));
238};
239
240GlobalLocker glock;
241
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000242void aa_fun_1() {
243 glock.globalLock();
244 glock.globalUnlock();
245}
246
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000247void aa_fun_bad_1() {
248 glock.globalUnlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000249 // expected-warning{{unlocking 'aa_mu' that was not locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000250}
251
252void aa_fun_bad_2() {
253 glock.globalLock();
254 glock.globalLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000255 // expected-warning{{locking 'aa_mu' that is already locked}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000256 glock.globalUnlock();
257}
258
259void aa_fun_bad_3() {
260 glock.globalLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000261 // expected-warning{{mutex 'aa_mu' is still held at the end of function 'aa_fun_bad_3'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000262}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000263
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000264//--------------------------------------------------//
265// Regression tests for unusual method names
266//--------------------------------------------------//
267
268Mutex wmu;
269
270// Test diagnostics for other method names.
271class WeirdMethods {
272 WeirdMethods() {
273 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000274 // expected-warning {{mutex 'wmu' is still held at the end of function 'WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000275 }
276 ~WeirdMethods() {
277 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000278 // expected-warning {{mutex 'wmu' is still held at the end of function '~WeirdMethods'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000279 }
280 void operator++() {
281 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000282 // expected-warning {{mutex 'wmu' is still held at the end of function 'operator++'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000283 }
284 operator int*() {
285 wmu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000286 // expected-warning {{mutex 'wmu' is still held at the end of function 'operator int *'}}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000287 return 0;
288 }
289};
290
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000291//-----------------------------------------------//
292// Errors for guarded by or guarded var variables
293// ----------------------------------------------//
294
295int *pgb_gvar __attribute__((pt_guarded_var));
296int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
297
298class PGBFoo {
299 public:
300 int x;
301 int *pgb_field __attribute__((guarded_by(sls_mu2)))
302 __attribute__((pt_guarded_by(sls_mu)));
303 void testFoo() {
304 pgb_field = &x; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000305 // expected-warning {{writing variable 'pgb_field' requires lock on 'sls_mu2' to be held exclusively}}
306 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
307 // expected-warning {{writing the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held exclusively}}
308 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
309 // expected-warning {{reading the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held}}
310 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires lock on 'sls_mu2' to be held}} \
311 // expected-warning {{writing the value pointed to by 'pgb_field' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000312 }
313};
314
315class GBFoo {
316 public:
317 int gb_field __attribute__((guarded_by(sls_mu)));
318
319 void testFoo() {
320 gb_field = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000321 // expected-warning {{writing variable 'gb_field' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000322 }
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000323
324 void testNoAnal() __attribute__((no_thread_safety_analysis)) {
325 gb_field = 0;
326 }
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000327};
328
329GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
330
331void gb_fun_0() {
332 sls_mu.Lock();
333 int x = *pgb_var;
334 sls_mu.Unlock();
335}
336
337void gb_fun_1() {
338 sls_mu.Lock();
339 *pgb_var = 2;
340 sls_mu.Unlock();
341}
342
343void gb_fun_2() {
344 int x;
345 pgb_var = &x;
346}
347
348void gb_fun_3() {
349 int *x = pgb_var;
350}
351
352void gb_bad_0() {
353 sls_guard_var = 1; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000354 // expected-warning{{writing variable 'sls_guard_var' requires lock on any mutex to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000355}
356
357void gb_bad_1() {
358 int x = sls_guard_var; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000359 // expected-warning{{reading variable 'sls_guard_var' requires lock on any mutex to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000360}
361
362void gb_bad_2() {
363 sls_guardby_var = 1; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000364 // expected-warning {{writing variable 'sls_guardby_var' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000365}
366
367void gb_bad_3() {
368 int x = sls_guardby_var; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000369 // expected-warning {{reading variable 'sls_guardby_var' requires lock on 'sls_mu' to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000370}
371
372void gb_bad_4() {
373 *pgb_gvar = 1; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000374 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires lock on any mutex to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000375}
376
377void gb_bad_5() {
378 int x = *pgb_gvar; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000379 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires lock on any mutex to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000380}
381
382void gb_bad_6() {
383 *pgb_var = 1; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000384 // expected-warning {{writing the value pointed to by 'pgb_var' requires lock on 'sls_mu' to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000385}
386
387void gb_bad_7() {
388 int x = *pgb_var; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000389 // expected-warning {{reading the value pointed to by 'pgb_var' requires lock on 'sls_mu' to be held}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000390}
391
392void gb_bad_8() {
393 GBFoo G;
394 G.gb_field = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000395 // expected-warning {{writing variable 'gb_field' requires lock on 'sls_mu'}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000396}
397
398void gb_bad_9() {
399 sls_guard_var++; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000400 // expected-warning{{writing variable 'sls_guard_var' requires lock on any mutex to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000401 sls_guard_var--; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000402 // expected-warning{{writing variable 'sls_guard_var' requires lock on any mutex to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000403 ++sls_guard_var; // \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000404 // expected-warning{{writing variable 'sls_guard_var' requires lock on any mutex to be held exclusively}}
Caitlin Sadowskia49d1d82011-09-09 16:07:55 +0000405 --sls_guard_var;// \
Caitlin Sadowskidf8327c2011-09-14 20:09:09 +0000406 // expected-warning{{writing variable 'sls_guard_var' requires lock on any mutex to be held exclusively}}
Caitlin Sadowski05b436e2011-08-29 22:27:51 +0000407}
Caitlin Sadowskib4d0a962011-08-29 17:12:27 +0000408
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000409//-----------------------------------------------//
410// Warnings on variables with late parsed attributes
411// ----------------------------------------------//
412
413class LateFoo {
414public:
415 int a __attribute__((guarded_by(mu)));
416 int b;
417
418 void foo() __attribute__((exclusive_locks_required(mu))) { }
419
420 void test() {
421 a = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000422 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000423 b = a; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000424 // expected-warning {{reading variable 'a' requires lock on 'mu' to be held}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000425 c = 0; // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000426 // expected-warning {{writing variable 'c' requires lock on 'mu' to be held exclusively}}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000427 }
428
429 int c __attribute__((guarded_by(mu)));
430
431 Mutex mu;
432};
433
Caitlin Sadowski99107eb2011-09-09 16:21:55 +0000434class LateBar {
435 public:
436 int a_ __attribute__((guarded_by(mu1_)));
437 int b_;
438 int *q __attribute__((pt_guarded_by(mu)));
439 Mutex mu1_;
440 Mutex mu;
441 LateFoo Foo;
442 LateFoo Foo2;
443 LateFoo *FooPointer;
444};
445
446LateBar b1, *b3;
447
448void late_0() {
449 LateFoo FooA;
450 LateFoo FooB;
451 FooA.mu.Lock();
452 FooA.a = 5;
453 FooA.mu.Unlock();
454}
455
456void late_1() {
457 LateBar BarA;
458 BarA.FooPointer->mu.Lock();
459 BarA.FooPointer->a = 2;
460 BarA.FooPointer->mu.Unlock();
461}
462
463void late_bad_0() {
464 LateFoo fooA;
465 LateFoo fooB;
466 fooA.mu.Lock();
467 fooB.a = 5; // \
468 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
469 fooA.mu.Unlock();
470}
471
472void late_bad_1() {
473 Mutex mu;
474 mu.Lock();
475 b1.mu1_.Lock();
476 int res = b1.a_ + b3->b_;
477 b3->b_ = *b1.q; // \
478 // expected-warning{{reading the value pointed to by 'q' requires lock on 'mu' to be held}}
479 b1.mu1_.Unlock();
480 b1.b_ = res;
481 mu.Unlock();
482}
483
484void late_bad_2() {
485 LateBar BarA;
486 BarA.FooPointer->mu.Lock();
487 BarA.Foo.a = 2; // \
488 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
489 BarA.FooPointer->mu.Unlock();
490}
491
492void late_bad_3() {
493 LateBar BarA;
494 BarA.Foo.mu.Lock();
495 BarA.FooPointer->a = 2; // \
496 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
497 BarA.Foo.mu.Unlock();
498}
499
500void late_bad_4() {
501 LateBar BarA;
502 BarA.Foo.mu.Lock();
503 BarA.Foo2.a = 2; // \
504 // expected-warning{{writing variable 'a' requires lock on 'mu' to be held exclusively}}
505 BarA.Foo.mu.Unlock();
506}
507
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000508//-----------------------------------------------//
509// Extra warnings for shared vs. exclusive locks
510// ----------------------------------------------//
511
512void shared_fun_0() {
513 sls_mu.Lock();
514 do {
515 sls_mu.Unlock();
516 sls_mu.Lock();
517 } while (getBool());
518 sls_mu.Unlock();
519}
520
521void shared_fun_1() {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000522 sls_mu.ReaderLock(); // \
523 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000524 do {
525 sls_mu.Unlock();
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000526 sls_mu.Lock(); // \
527 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000528 } while (getBool());
529 sls_mu.Unlock();
530}
531
532void shared_fun_3() {
533 if (getBool())
534 sls_mu.Lock();
535 else
536 sls_mu.Lock();
537 *pgb_var = 1;
538 sls_mu.Unlock();
539}
540
541void shared_fun_4() {
542 if (getBool())
543 sls_mu.ReaderLock();
544 else
545 sls_mu.ReaderLock();
546 int x = sls_guardby_var;
547 sls_mu.Unlock();
548}
549
550void shared_fun_8() {
551 if (getBool())
552 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000553 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000554 else
555 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000556 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000557 sls_mu.Unlock();
558}
559
560void shared_bad_0() {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000561 sls_mu.Lock(); // \
562 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000563 do {
564 sls_mu.Unlock();
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +0000565 sls_mu.ReaderLock(); // \
566 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000567 } while (getBool());
568 sls_mu.Unlock();
569}
570
571void shared_bad_1() {
572 if (getBool())
573 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000574 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000575 else
576 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000577 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000578 *pgb_var = 1;
579 sls_mu.Unlock();
580}
581
582void shared_bad_2() {
583 if (getBool())
584 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000585 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000586 else
587 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000588 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000589 *pgb_var = 1;
590 sls_mu.Unlock();
591}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000592
593// FIXME: Add support for functions (not only methods)
594class LRBar {
595 public:
596 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
597 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
598 void le_fun() __attribute__((locks_excluded(sls_mu)));
599};
600
601class LRFoo {
602 public:
603 void test() __attribute__((exclusive_locks_required(sls_mu)));
604 void testShared() __attribute__((shared_locks_required(sls_mu2)));
605};
606
607void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
608void elr_fun() {}
609
610LRFoo MyLRFoo;
611LRBar Bar;
612
613void es_fun_0() {
614 aa_mu.Lock();
615 Bar.aa_elr_fun();
616 aa_mu.Unlock();
617}
618
619void es_fun_1() {
620 aa_mu.Lock();
621 Bar.aa_elr_fun_s();
622 aa_mu.Unlock();
623}
624
625void es_fun_2() {
626 aa_mu.ReaderLock();
627 Bar.aa_elr_fun_s();
628 aa_mu.Unlock();
629}
630
631void es_fun_3() {
632 sls_mu.Lock();
633 MyLRFoo.test();
634 sls_mu.Unlock();
635}
636
637void es_fun_4() {
638 sls_mu2.Lock();
639 MyLRFoo.testShared();
640 sls_mu2.Unlock();
641}
642
643void es_fun_5() {
644 sls_mu2.ReaderLock();
645 MyLRFoo.testShared();
646 sls_mu2.Unlock();
647}
648
649void es_fun_6() {
650 Bar.le_fun();
651}
652
653void es_fun_7() {
654 sls_mu.Lock();
655 elr_fun();
656 sls_mu.Unlock();
657}
658
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000659void es_fun_8() __attribute__((no_thread_safety_analysis));
660
661void es_fun_8() {
662 Bar.aa_elr_fun_s();
663}
664
Caitlin Sadowskicb967512011-09-15 17:43:08 +0000665void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
666void es_fun_9() {
667 Bar.aa_elr_fun_s();
668}
669
670void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
671void es_fun_10() {
672 Bar.aa_elr_fun_s();
673}
674
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000675void es_bad_0() {
676 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000677 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000678}
679
680void es_bad_1() {
681 aa_mu.ReaderLock();
682 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000683 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000684 aa_mu.Unlock();
685}
686
687void es_bad_2() {
688 Bar.aa_elr_fun_s(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000689 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000690}
691
692void es_bad_3() {
693 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000694 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000695}
696
697void es_bad_4() {
698 MyLRFoo.testShared(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000699 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000700}
701
702void es_bad_5() {
703 sls_mu.ReaderLock();
704 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000705 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000706 sls_mu.Unlock();
707}
708
709void es_bad_6() {
710 sls_mu.Lock();
711 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000712 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000713 sls_mu.Unlock();
714}
715
716void es_bad_7() {
717 sls_mu.ReaderLock();
718 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000719 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000720 sls_mu.Unlock();
721}
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000722
723//-----------------------------------------------//
724// Unparseable lock expressions
725// ----------------------------------------------//
726
727Mutex UPmu;
728// FIXME: add support for lock expressions involving arrays.
729Mutex mua[5];
730
731int x __attribute__((guarded_by(UPmu = sls_mu))); // \
732 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
733int y __attribute__((guarded_by(mua[0]))); // \
734 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
735
736
737void testUnparse() {
738 // no errors, since the lock expressions are not resolved
739 x = 5;
740 y = 5;
741}
742
743void testUnparse2() {
744 mua[0].Lock(); // \
745 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
746 (&(mua[0]) + 4)->Lock(); // \
747 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
748}
749