blob: f9ba5ec0916264ef4a2fcac6671fa6fb8d8911cd [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() {
179 sls_mu.Lock();
180 while (getBool()) { // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000181 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
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() {
195 sls_mu.Lock();
196 do {
197 sls_mu.Unlock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000198 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000199 } while (getBool());
200}
201
202void sls_fun_bad_9() {
203 do {
204 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000205 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
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 Sadowski8bccabe2011-09-08 21:52:50 +0000212 // expected-warning{{mutex 'sls_mu' is still held at the end of function 'sls_fun_bad_10'}}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000213 while(getBool()) { // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000214 // expected-warning{{expecting lock on 'sls_mu' to be held at start of each loop}}
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 Sadowski8bccabe2011-09-08 21:52:50 +0000222 // expected-warning{{mutex 'sls_mu' is still held at the end of its scope}}
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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +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 Sadowskia49d1d82011-09-09 16:07:55 +0000404 // expected-warning{{writing variable 'sls_guard_var' requires lock on 'any mutex' to be held exclusively}}
405 --sls_guard_var;// \
406 // 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() {
522 sls_mu.ReaderLock();
523 do {
524 sls_mu.Unlock();
525 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000526 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000527 } while (getBool());
528 sls_mu.Unlock();
529}
530
531void shared_fun_3() {
532 if (getBool())
533 sls_mu.Lock();
534 else
535 sls_mu.Lock();
536 *pgb_var = 1;
537 sls_mu.Unlock();
538}
539
540void shared_fun_4() {
541 if (getBool())
542 sls_mu.ReaderLock();
543 else
544 sls_mu.ReaderLock();
545 int x = sls_guardby_var;
546 sls_mu.Unlock();
547}
548
549void shared_fun_8() {
550 if (getBool())
551 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000552 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000553 else
554 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000555 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000556 sls_mu.Unlock();
557}
558
559void shared_bad_0() {
560 sls_mu.Lock();
561 do {
562 sls_mu.Unlock();
563 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000564 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000565 } while (getBool());
566 sls_mu.Unlock();
567}
568
569void shared_bad_1() {
570 if (getBool())
571 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000572 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000573 else
574 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000575 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000576 *pgb_var = 1;
577 sls_mu.Unlock();
578}
579
580void shared_bad_2() {
581 if (getBool())
582 sls_mu.ReaderLock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000583 // expected-warning {{lock 'sls_mu' is exclusive and shared in the same scope}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000584 else
585 sls_mu.Lock(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000586 // expected-note {{the other lock of mutex 'sls_mu' is here}}
Caitlin Sadowskia53257c2011-09-08 18:19:38 +0000587 *pgb_var = 1;
588 sls_mu.Unlock();
589}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000590
591// FIXME: Add support for functions (not only methods)
592class LRBar {
593 public:
594 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
595 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
596 void le_fun() __attribute__((locks_excluded(sls_mu)));
597};
598
599class LRFoo {
600 public:
601 void test() __attribute__((exclusive_locks_required(sls_mu)));
602 void testShared() __attribute__((shared_locks_required(sls_mu2)));
603};
604
605void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
606void elr_fun() {}
607
608LRFoo MyLRFoo;
609LRBar Bar;
610
611void es_fun_0() {
612 aa_mu.Lock();
613 Bar.aa_elr_fun();
614 aa_mu.Unlock();
615}
616
617void es_fun_1() {
618 aa_mu.Lock();
619 Bar.aa_elr_fun_s();
620 aa_mu.Unlock();
621}
622
623void es_fun_2() {
624 aa_mu.ReaderLock();
625 Bar.aa_elr_fun_s();
626 aa_mu.Unlock();
627}
628
629void es_fun_3() {
630 sls_mu.Lock();
631 MyLRFoo.test();
632 sls_mu.Unlock();
633}
634
635void es_fun_4() {
636 sls_mu2.Lock();
637 MyLRFoo.testShared();
638 sls_mu2.Unlock();
639}
640
641void es_fun_5() {
642 sls_mu2.ReaderLock();
643 MyLRFoo.testShared();
644 sls_mu2.Unlock();
645}
646
647void es_fun_6() {
648 Bar.le_fun();
649}
650
651void es_fun_7() {
652 sls_mu.Lock();
653 elr_fun();
654 sls_mu.Unlock();
655}
656
Caitlin Sadowskiaf370612011-09-08 18:35:21 +0000657void es_fun_8() __attribute__((no_thread_safety_analysis));
658
659void es_fun_8() {
660 Bar.aa_elr_fun_s();
661}
662
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000663void es_bad_0() {
664 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000665 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000666}
667
668void es_bad_1() {
669 aa_mu.ReaderLock();
670 Bar.aa_elr_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000671 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000672 aa_mu.Unlock();
673}
674
675void es_bad_2() {
676 Bar.aa_elr_fun_s(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000677 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000678}
679
680void es_bad_3() {
681 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000682 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000683}
684
685void es_bad_4() {
686 MyLRFoo.testShared(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000687 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000688}
689
690void es_bad_5() {
691 sls_mu.ReaderLock();
692 MyLRFoo.test(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000693 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000694 sls_mu.Unlock();
695}
696
697void es_bad_6() {
698 sls_mu.Lock();
699 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000700 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000701 sls_mu.Unlock();
702}
703
704void es_bad_7() {
705 sls_mu.ReaderLock();
706 Bar.le_fun(); // \
Caitlin Sadowski8bccabe2011-09-08 21:52:50 +0000707 // expected-warning {{cannot call function 'le_fun' while holding mutex 'sls_mu'}}
Caitlin Sadowski978191e2011-09-08 18:27:31 +0000708 sls_mu.Unlock();
709}
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000710
711//-----------------------------------------------//
712// Unparseable lock expressions
713// ----------------------------------------------//
714
715Mutex UPmu;
716// FIXME: add support for lock expressions involving arrays.
717Mutex mua[5];
718
719int x __attribute__((guarded_by(UPmu = sls_mu))); // \
720 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
721int y __attribute__((guarded_by(mua[0]))); // \
722 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
723
724
725void testUnparse() {
726 // no errors, since the lock expressions are not resolved
727 x = 5;
728 y = 5;
729}
730
731void testUnparse2() {
732 mua[0].Lock(); // \
733 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
734 (&(mua[0]) + 4)->Lock(); // \
735 // expected-warning{{cannot resolve lock expression to a specific lockable object}}
736}
737