1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -fcxx-exceptions %s
2
3 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
4 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
5
6 #define LOCKABLE __attribute__ ((lockable))
7 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
8 #define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
9 #define GUARDED_VAR __attribute__ ((guarded_var))
10 #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
11 #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
12 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
13 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
14 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
15 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
16 #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
17 #define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__)))
18 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
19 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
20 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
21 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
22 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
23 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
24 __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
25 #define SHARED_LOCKS_REQUIRED(...) \
26 __attribute__ ((shared_locks_required(__VA_ARGS__)))
27 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
28
29
30 class __attribute__((lockable)) Mutex {
31 public:
32 void Lock() __attribute__((exclusive_lock_function));
33 void ReaderLock() __attribute__((shared_lock_function));
34 void Unlock() __attribute__((unlock_function));
35 bool TryLock() __attribute__((exclusive_trylock_function(true)));
36 bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
37 void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
38
39 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
40 void AssertReaderHeld() ASSERT_SHARED_LOCK();
41 };
42
43 class __attribute__((scoped_lockable)) MutexLock {
44 public:
45 MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
46 ~MutexLock() __attribute__((unlock_function));
47 };
48
49 class __attribute__((scoped_lockable)) ReaderMutexLock {
50 public:
51 ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu)));
52 ~ReaderMutexLock() __attribute__((unlock_function));
53 };
54
55 class SCOPED_LOCKABLE ReleasableMutexLock {
56 public:
57 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
58 ~ReleasableMutexLock() UNLOCK_FUNCTION();
59
60 void Release() UNLOCK_FUNCTION();
61 };
62
63
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("*");
70
71
72 // For testing handling of smart pointers.
73 template<class T>
74 class SmartPtr {
75 public:
SmartPtr(T * p)76 SmartPtr(T* p) : ptr_(p) { }
SmartPtr(const SmartPtr<T> & p)77 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
78 ~SmartPtr();
79
get() const80 T* get() const { return ptr_; }
operator ->() const81 T* operator->() const { return ptr_; }
operator *() const82 T& operator*() const { return *ptr_; }
83
84 private:
85 T* ptr_;
86 };
87
88
89 // For testing destructor calls and cleanup.
90 class MyString {
91 public:
92 MyString(const char* s);
93 ~MyString();
94 };
95
96
97
98 Mutex sls_mu;
99
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;
103
104 bool getBool();
105
106 class MutexWrapper {
107 public:
108 Mutex mu;
109 int x __attribute__((guarded_by(mu)));
110 void MyLock() __attribute__((exclusive_lock_function(mu)));
111 };
112
113 MutexWrapper sls_mw;
114
sls_fun_0()115 void sls_fun_0() {
116 sls_mw.mu.Lock();
117 sls_mw.x = 5;
118 sls_mw.mu.Unlock();
119 }
120
sls_fun_2()121 void sls_fun_2() {
122 sls_mu.Lock();
123 int x = sls_guard_var;
124 sls_mu.Unlock();
125 }
126
sls_fun_3()127 void sls_fun_3() {
128 sls_mu.Lock();
129 sls_guard_var = 2;
130 sls_mu.Unlock();
131 }
132
sls_fun_4()133 void sls_fun_4() {
134 sls_mu2.Lock();
135 sls_guard_var = 2;
136 sls_mu2.Unlock();
137 }
138
sls_fun_5()139 void sls_fun_5() {
140 sls_mu.Lock();
141 int x = sls_guardby_var;
142 sls_mu.Unlock();
143 }
144
sls_fun_6()145 void sls_fun_6() {
146 sls_mu.Lock();
147 sls_guardby_var = 2;
148 sls_mu.Unlock();
149 }
150
sls_fun_7()151 void sls_fun_7() {
152 sls_mu.Lock();
153 sls_mu2.Lock();
154 sls_mu2.Unlock();
155 sls_mu.Unlock();
156 }
157
sls_fun_8()158 void sls_fun_8() {
159 sls_mu.Lock();
160 if (getBool())
161 sls_mu.Unlock();
162 else
163 sls_mu.Unlock();
164 }
165
sls_fun_9()166 void sls_fun_9() {
167 if (getBool())
168 sls_mu.Lock();
169 else
170 sls_mu.Lock();
171 sls_mu.Unlock();
172 }
173
sls_fun_good_6()174 void sls_fun_good_6() {
175 if (getBool()) {
176 sls_mu.Lock();
177 } else {
178 if (getBool()) {
179 getBool(); // EMPTY
180 } else {
181 getBool(); // EMPTY
182 }
183 sls_mu.Lock();
184 }
185 sls_mu.Unlock();
186 }
187
sls_fun_good_7()188 void sls_fun_good_7() {
189 sls_mu.Lock();
190 while (getBool()) {
191 sls_mu.Unlock();
192 if (getBool()) {
193 if (getBool()) {
194 sls_mu.Lock();
195 continue;
196 }
197 }
198 sls_mu.Lock();
199 }
200 sls_mu.Unlock();
201 }
202
sls_fun_good_8()203 void sls_fun_good_8() {
204 sls_mw.MyLock();
205 sls_mw.mu.Unlock();
206 }
207
sls_fun_bad_1()208 void sls_fun_bad_1() {
209 sls_mu.Unlock(); // \
210 // expected-warning{{unlocking 'sls_mu' that was not locked}}
211 }
212
sls_fun_bad_2()213 void sls_fun_bad_2() {
214 sls_mu.Lock();
215 sls_mu.Lock(); // \
216 // expected-warning{{locking 'sls_mu' that is already locked}}
217 sls_mu.Unlock();
218 }
219
sls_fun_bad_3()220 void sls_fun_bad_3() {
221 sls_mu.Lock(); // expected-note {{mutex acquired here}}
222 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
223
sls_fun_bad_4()224 void sls_fun_bad_4() {
225 if (getBool())
226 sls_mu.Lock(); // expected-note{{mutex acquired here}}
227 else
228 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
229 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \
230 // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
231
sls_fun_bad_5()232 void sls_fun_bad_5() {
233 sls_mu.Lock(); // expected-note {{mutex acquired here}}
234 if (getBool())
235 sls_mu.Unlock();
236 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
237
sls_fun_bad_6()238 void sls_fun_bad_6() {
239 if (getBool()) {
240 sls_mu.Lock(); // expected-note {{mutex acquired here}}
241 } else {
242 if (getBool()) {
243 getBool(); // EMPTY
244 } else {
245 getBool(); // EMPTY
246 }
247 }
248 sls_mu.Unlock(); // \
249 expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
250 expected-warning{{unlocking 'sls_mu' that was not locked}}
251 }
252
sls_fun_bad_7()253 void sls_fun_bad_7() {
254 sls_mu.Lock();
255 while (getBool()) {
256 sls_mu.Unlock();
257 if (getBool()) {
258 if (getBool()) {
259 continue; // \
260 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
261 }
262 }
263 sls_mu.Lock(); // expected-note {{mutex acquired here}}
264 }
265 sls_mu.Unlock();
266 }
267
sls_fun_bad_8()268 void sls_fun_bad_8() {
269 sls_mu.Lock(); // expected-note{{mutex acquired here}}
270
271 do {
272 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
273 } while (getBool());
274 }
275
sls_fun_bad_9()276 void sls_fun_bad_9() {
277 do {
278 sls_mu.Lock(); // \
279 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
280 // expected-note{{mutex acquired here}}
281 } while (getBool());
282 sls_mu.Unlock();
283 }
284
sls_fun_bad_10()285 void sls_fun_bad_10() {
286 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
287 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
288 sls_mu.Unlock();
289 }
290 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
291
sls_fun_bad_11()292 void sls_fun_bad_11() {
293 while (getBool()) { // \
294 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
295 sls_mu.Lock(); // expected-note {{mutex acquired here}}
296 }
297 sls_mu.Unlock(); // \
298 // expected-warning{{unlocking 'sls_mu' that was not locked}}
299 }
300
sls_fun_bad_12()301 void sls_fun_bad_12() {
302 sls_mu.Lock(); // expected-note {{mutex acquired here}}
303 while (getBool()) {
304 sls_mu.Unlock();
305 if (getBool()) {
306 if (getBool()) {
307 break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
308 }
309 }
310 sls_mu.Lock();
311 }
312 sls_mu.Unlock();
313 }
314
315 //-----------------------------------------//
316 // Handling lock expressions in attribute args
317 // -------------------------------------------//
318
319 Mutex aa_mu;
320
321 class GlobalLocker {
322 public:
323 void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
324 void globalUnlock() __attribute__((unlock_function(aa_mu)));
325 };
326
327 GlobalLocker glock;
328
aa_fun_1()329 void aa_fun_1() {
330 glock.globalLock();
331 glock.globalUnlock();
332 }
333
aa_fun_bad_1()334 void aa_fun_bad_1() {
335 glock.globalUnlock(); // \
336 // expected-warning{{unlocking 'aa_mu' that was not locked}}
337 }
338
aa_fun_bad_2()339 void aa_fun_bad_2() {
340 glock.globalLock();
341 glock.globalLock(); // \
342 // expected-warning{{locking 'aa_mu' that is already locked}}
343 glock.globalUnlock();
344 }
345
aa_fun_bad_3()346 void aa_fun_bad_3() {
347 glock.globalLock(); // expected-note{{mutex acquired here}}
348 } // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
349
350 //--------------------------------------------------//
351 // Regression tests for unusual method names
352 //--------------------------------------------------//
353
354 Mutex wmu;
355
356 // Test diagnostics for other method names.
357 class WeirdMethods {
358 // FIXME: can't currently check inside constructors and destructors.
WeirdMethods()359 WeirdMethods() {
360 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
361 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
~WeirdMethods()362 ~WeirdMethods() {
363 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
364 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
operator ++()365 void operator++() {
366 wmu.Lock(); // expected-note {{mutex acquired here}}
367 } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
operator int*()368 operator int*() {
369 wmu.Lock(); // expected-note {{mutex acquired here}}
370 return 0;
371 } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
372 };
373
374 //-----------------------------------------------//
375 // Errors for guarded by or guarded var variables
376 // ----------------------------------------------//
377
378 int *pgb_gvar __attribute__((pt_guarded_var));
379 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
380
381 class PGBFoo {
382 public:
383 int x;
384 int *pgb_field __attribute__((guarded_by(sls_mu2)))
385 __attribute__((pt_guarded_by(sls_mu)));
testFoo()386 void testFoo() {
387 pgb_field = &x; // \
388 // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
389 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
390 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
391 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
392 // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
393 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
394 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
395 }
396 };
397
398 class GBFoo {
399 public:
400 int gb_field __attribute__((guarded_by(sls_mu)));
401
testFoo()402 void testFoo() {
403 gb_field = 0; // \
404 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
405 }
406
testNoAnal()407 void testNoAnal() __attribute__((no_thread_safety_analysis)) {
408 gb_field = 0;
409 }
410 };
411
412 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
413
gb_fun_0()414 void gb_fun_0() {
415 sls_mu.Lock();
416 int x = *pgb_var;
417 sls_mu.Unlock();
418 }
419
gb_fun_1()420 void gb_fun_1() {
421 sls_mu.Lock();
422 *pgb_var = 2;
423 sls_mu.Unlock();
424 }
425
gb_fun_2()426 void gb_fun_2() {
427 int x;
428 pgb_var = &x;
429 }
430
gb_fun_3()431 void gb_fun_3() {
432 int *x = pgb_var;
433 }
434
gb_bad_0()435 void gb_bad_0() {
436 sls_guard_var = 1; // \
437 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
438 }
439
gb_bad_1()440 void gb_bad_1() {
441 int x = sls_guard_var; // \
442 // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
443 }
444
gb_bad_2()445 void gb_bad_2() {
446 sls_guardby_var = 1; // \
447 // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
448 }
449
gb_bad_3()450 void gb_bad_3() {
451 int x = sls_guardby_var; // \
452 // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
453 }
454
gb_bad_4()455 void gb_bad_4() {
456 *pgb_gvar = 1; // \
457 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
458 }
459
gb_bad_5()460 void gb_bad_5() {
461 int x = *pgb_gvar; // \
462 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
463 }
464
gb_bad_6()465 void gb_bad_6() {
466 *pgb_var = 1; // \
467 // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
468 }
469
gb_bad_7()470 void gb_bad_7() {
471 int x = *pgb_var; // \
472 // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
473 }
474
gb_bad_8()475 void gb_bad_8() {
476 GBFoo G;
477 G.gb_field = 0; // \
478 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
479 }
480
gb_bad_9()481 void gb_bad_9() {
482 sls_guard_var++; // \
483 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
484 sls_guard_var--; // \
485 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
486 ++sls_guard_var; // \
487 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
488 --sls_guard_var;// \
489 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
490 }
491
492 //-----------------------------------------------//
493 // Warnings on variables with late parsed attributes
494 // ----------------------------------------------//
495
496 class LateFoo {
497 public:
498 int a __attribute__((guarded_by(mu)));
499 int b;
500
foo()501 void foo() __attribute__((exclusive_locks_required(mu))) { }
502
test()503 void test() {
504 a = 0; // \
505 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
506 b = a; // \
507 // expected-warning {{reading variable 'a' requires locking 'mu'}}
508 c = 0; // \
509 // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
510 }
511
512 int c __attribute__((guarded_by(mu)));
513
514 Mutex mu;
515 };
516
517 class LateBar {
518 public:
519 int a_ __attribute__((guarded_by(mu1_)));
520 int b_;
521 int *q __attribute__((pt_guarded_by(mu)));
522 Mutex mu1_;
523 Mutex mu;
524 LateFoo Foo;
525 LateFoo Foo2;
526 LateFoo *FooPointer;
527 };
528
529 LateBar b1, *b3;
530
late_0()531 void late_0() {
532 LateFoo FooA;
533 LateFoo FooB;
534 FooA.mu.Lock();
535 FooA.a = 5;
536 FooA.mu.Unlock();
537 }
538
late_1()539 void late_1() {
540 LateBar BarA;
541 BarA.FooPointer->mu.Lock();
542 BarA.FooPointer->a = 2;
543 BarA.FooPointer->mu.Unlock();
544 }
545
late_bad_0()546 void late_bad_0() {
547 LateFoo fooA;
548 LateFoo fooB;
549 fooA.mu.Lock();
550 fooB.a = 5; // \
551 // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
552 // expected-note{{found near match 'fooA.mu'}}
553 fooA.mu.Unlock();
554 }
555
late_bad_1()556 void late_bad_1() {
557 Mutex mu;
558 mu.Lock();
559 b1.mu1_.Lock();
560 int res = b1.a_ + b3->b_;
561 b3->b_ = *b1.q; // \
562 // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
563 b1.mu1_.Unlock();
564 b1.b_ = res;
565 mu.Unlock();
566 }
567
late_bad_2()568 void late_bad_2() {
569 LateBar BarA;
570 BarA.FooPointer->mu.Lock();
571 BarA.Foo.a = 2; // \
572 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
573 // expected-note{{found near match 'BarA.FooPointer->mu'}}
574 BarA.FooPointer->mu.Unlock();
575 }
576
late_bad_3()577 void late_bad_3() {
578 LateBar BarA;
579 BarA.Foo.mu.Lock();
580 BarA.FooPointer->a = 2; // \
581 // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
582 // expected-note{{found near match 'BarA.Foo.mu'}}
583 BarA.Foo.mu.Unlock();
584 }
585
late_bad_4()586 void late_bad_4() {
587 LateBar BarA;
588 BarA.Foo.mu.Lock();
589 BarA.Foo2.a = 2; // \
590 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
591 // expected-note{{found near match 'BarA.Foo.mu'}}
592 BarA.Foo.mu.Unlock();
593 }
594
595 //-----------------------------------------------//
596 // Extra warnings for shared vs. exclusive locks
597 // ----------------------------------------------//
598
shared_fun_0()599 void shared_fun_0() {
600 sls_mu.Lock();
601 do {
602 sls_mu.Unlock();
603 sls_mu.Lock();
604 } while (getBool());
605 sls_mu.Unlock();
606 }
607
shared_fun_1()608 void shared_fun_1() {
609 sls_mu.ReaderLock(); // \
610 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
611 do {
612 sls_mu.Unlock();
613 sls_mu.Lock(); // \
614 // expected-note {{the other lock of mutex 'sls_mu' is here}}
615 } while (getBool());
616 sls_mu.Unlock();
617 }
618
shared_fun_3()619 void shared_fun_3() {
620 if (getBool())
621 sls_mu.Lock();
622 else
623 sls_mu.Lock();
624 *pgb_var = 1;
625 sls_mu.Unlock();
626 }
627
shared_fun_4()628 void shared_fun_4() {
629 if (getBool())
630 sls_mu.ReaderLock();
631 else
632 sls_mu.ReaderLock();
633 int x = sls_guardby_var;
634 sls_mu.Unlock();
635 }
636
shared_fun_8()637 void shared_fun_8() {
638 if (getBool())
639 sls_mu.Lock(); // \
640 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
641 else
642 sls_mu.ReaderLock(); // \
643 // expected-note {{the other lock of mutex 'sls_mu' is here}}
644 sls_mu.Unlock();
645 }
646
shared_bad_0()647 void shared_bad_0() {
648 sls_mu.Lock(); // \
649 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
650 do {
651 sls_mu.Unlock();
652 sls_mu.ReaderLock(); // \
653 // expected-note {{the other lock of mutex 'sls_mu' is here}}
654 } while (getBool());
655 sls_mu.Unlock();
656 }
657
shared_bad_1()658 void shared_bad_1() {
659 if (getBool())
660 sls_mu.Lock(); // \
661 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
662 else
663 sls_mu.ReaderLock(); // \
664 // expected-note {{the other lock of mutex 'sls_mu' is here}}
665 *pgb_var = 1;
666 sls_mu.Unlock();
667 }
668
shared_bad_2()669 void shared_bad_2() {
670 if (getBool())
671 sls_mu.ReaderLock(); // \
672 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
673 else
674 sls_mu.Lock(); // \
675 // expected-note {{the other lock of mutex 'sls_mu' is here}}
676 *pgb_var = 1;
677 sls_mu.Unlock();
678 }
679
680 // FIXME: Add support for functions (not only methods)
681 class LRBar {
682 public:
683 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
684 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
685 void le_fun() __attribute__((locks_excluded(sls_mu)));
686 };
687
688 class LRFoo {
689 public:
690 void test() __attribute__((exclusive_locks_required(sls_mu)));
691 void testShared() __attribute__((shared_locks_required(sls_mu2)));
692 };
693
694 void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
elr_fun()695 void elr_fun() {}
696
697 LRFoo MyLRFoo;
698 LRBar Bar;
699
es_fun_0()700 void es_fun_0() {
701 aa_mu.Lock();
702 Bar.aa_elr_fun();
703 aa_mu.Unlock();
704 }
705
es_fun_1()706 void es_fun_1() {
707 aa_mu.Lock();
708 Bar.aa_elr_fun_s();
709 aa_mu.Unlock();
710 }
711
es_fun_2()712 void es_fun_2() {
713 aa_mu.ReaderLock();
714 Bar.aa_elr_fun_s();
715 aa_mu.Unlock();
716 }
717
es_fun_3()718 void es_fun_3() {
719 sls_mu.Lock();
720 MyLRFoo.test();
721 sls_mu.Unlock();
722 }
723
es_fun_4()724 void es_fun_4() {
725 sls_mu2.Lock();
726 MyLRFoo.testShared();
727 sls_mu2.Unlock();
728 }
729
es_fun_5()730 void es_fun_5() {
731 sls_mu2.ReaderLock();
732 MyLRFoo.testShared();
733 sls_mu2.Unlock();
734 }
735
es_fun_6()736 void es_fun_6() {
737 Bar.le_fun();
738 }
739
es_fun_7()740 void es_fun_7() {
741 sls_mu.Lock();
742 elr_fun();
743 sls_mu.Unlock();
744 }
745
746 void es_fun_8() __attribute__((no_thread_safety_analysis));
747
es_fun_8()748 void es_fun_8() {
749 Bar.aa_elr_fun_s();
750 }
751
752 void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
es_fun_9()753 void es_fun_9() {
754 Bar.aa_elr_fun_s();
755 }
756
757 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
es_fun_10()758 void es_fun_10() {
759 Bar.aa_elr_fun_s();
760 }
761
es_bad_0()762 void es_bad_0() {
763 Bar.aa_elr_fun(); // \
764 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
765 }
766
es_bad_1()767 void es_bad_1() {
768 aa_mu.ReaderLock();
769 Bar.aa_elr_fun(); // \
770 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
771 aa_mu.Unlock();
772 }
773
es_bad_2()774 void es_bad_2() {
775 Bar.aa_elr_fun_s(); // \
776 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
777 }
778
es_bad_3()779 void es_bad_3() {
780 MyLRFoo.test(); // \
781 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
782 }
783
es_bad_4()784 void es_bad_4() {
785 MyLRFoo.testShared(); // \
786 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
787 }
788
es_bad_5()789 void es_bad_5() {
790 sls_mu.ReaderLock();
791 MyLRFoo.test(); // \
792 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
793 sls_mu.Unlock();
794 }
795
es_bad_6()796 void es_bad_6() {
797 sls_mu.Lock();
798 Bar.le_fun(); // \
799 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
800 sls_mu.Unlock();
801 }
802
es_bad_7()803 void es_bad_7() {
804 sls_mu.ReaderLock();
805 Bar.le_fun(); // \
806 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
807 sls_mu.Unlock();
808 }
809
810
811 //-----------------------------------------------//
812 // Unparseable lock expressions
813 // ----------------------------------------------//
814
815 // FIXME -- derive new tests for unhandled expressions
816
817
818 //----------------------------------------------------------------------------//
819 // The following test cases are ported from the gcc thread safety implementation
820 // They are each wrapped inside a namespace with the test number of the gcc test
821 //
822 // FIXME: add all the gcc tests, once this analysis passes them.
823 //----------------------------------------------------------------------------//
824
825 //-----------------------------------------//
826 // Good testcases (no errors)
827 //-----------------------------------------//
828
829 namespace thread_annot_lock_20 {
830 class Bar {
831 public:
832 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
833 static int b_ GUARDED_BY(mu1_);
834 static Mutex mu1_;
835 static int a_ GUARDED_BY(mu1_);
836 };
837
838 Bar b1;
839
func1()840 int Bar::func1()
841 {
842 int res = 5;
843
844 if (a_ == 4)
845 res = b_;
846 return res;
847 }
848 } // end namespace thread_annot_lock_20
849
850 namespace thread_annot_lock_22 {
851 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
852 // uses in class definitions.
853 Mutex mu;
854
855 class Bar {
856 public:
857 int a_ GUARDED_BY(mu1_);
858 int b_;
859 int *q PT_GUARDED_BY(mu);
860 Mutex mu1_ ACQUIRED_AFTER(mu);
861 };
862
863 Bar b1, *b3;
864 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
865 int res GUARDED_BY(mu) = 5;
866
func(int i)867 int func(int i)
868 {
869 int x;
870 mu.Lock();
871 b1.mu1_.Lock();
872 res = b1.a_ + b3->b_;
873 *p = i;
874 b1.a_ = res + b3->b_;
875 b3->b_ = *b1.q;
876 b1.mu1_.Unlock();
877 b1.b_ = res;
878 x = res;
879 mu.Unlock();
880 return x;
881 }
882 } // end namespace thread_annot_lock_22
883
884 namespace thread_annot_lock_27_modified {
885 // test lock annotations applied to function definitions
886 // Modified: applied annotations only to function declarations
887 Mutex mu1;
888 Mutex mu2 ACQUIRED_AFTER(mu1);
889
890 class Foo {
891 public:
892 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
893 };
894
method1(int i)895 int Foo::method1(int i) {
896 return i;
897 }
898
899
900 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
foo(int i)901 int foo(int i) {
902 return i;
903 }
904
905 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
bar(int i)906 static int bar(int i) {
907 return i;
908 }
909
main()910 void main() {
911 Foo a;
912
913 mu1.Lock();
914 mu2.Lock();
915 a.method1(1);
916 foo(2);
917 mu2.Unlock();
918 bar(3);
919 mu1.Unlock();
920 }
921 } // end namespace thread_annot_lock_27_modified
922
923
924 namespace thread_annot_lock_38 {
925 // Test the case where a template member function is annotated with lock
926 // attributes in a non-template class.
927 class Foo {
928 public:
929 void func1(int y) LOCKS_EXCLUDED(mu_);
930 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
931 private:
932 Mutex mu_;
933 };
934
935 Foo *foo;
936
main()937 void main()
938 {
939 foo->func1(5);
940 foo->func2(5);
941 }
942 } // end namespace thread_annot_lock_38
943
944 namespace thread_annot_lock_43 {
945 // Tests lock canonicalization
946 class Foo {
947 public:
948 Mutex *mu_;
949 };
950
951 class FooBar {
952 public:
953 Foo *foo_;
GetA()954 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
955 int a_ GUARDED_BY(foo_->mu_);
956 };
957
958 FooBar *fb;
959
main()960 void main()
961 {
962 int x;
963 fb->foo_->mu_->Lock();
964 x = fb->GetA();
965 fb->foo_->mu_->Unlock();
966 }
967 } // end namespace thread_annot_lock_43
968
969 namespace thread_annot_lock_49 {
970 // Test the support for use of lock expression in the annotations
971 class Foo {
972 public:
973 Mutex foo_mu_;
974 };
975
976 class Bar {
977 private:
978 Foo *foo;
979 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
980
981 public:
Test1()982 void Test1() {
983 foo->foo_mu_.Lock();
984 bar_mu_.Lock();
985 bar_mu_.Unlock();
986 foo->foo_mu_.Unlock();
987 }
988 };
989
main()990 void main() {
991 Bar bar;
992 bar.Test1();
993 }
994 } // end namespace thread_annot_lock_49
995
996 namespace thread_annot_lock_61_modified {
997 // Modified to fix the compiler errors
998 // Test the fix for a bug introduced by the support of pass-by-reference
999 // paramters.
operator <<thread_annot_lock_61_modified::Foo1000 struct Foo { Foo &operator<< (bool) {return *this;} };
1001 Foo &getFoo();
functhread_annot_lock_61_modified::Bar1002 struct Bar { Foo &func () {return getFoo();} };
operator &thread_annot_lock_61_modified::Bas1003 struct Bas { void operator& (Foo &) {} };
mumble()1004 void mumble()
1005 {
1006 Bas() & Bar().func() << "" << "";
1007 Bas() & Bar().func() << "";
1008 }
1009 } // end namespace thread_annot_lock_61_modified
1010
1011
1012 namespace thread_annot_lock_65 {
1013 // Test the fix for a bug in the support of allowing reader locks for
1014 // non-const, non-modifying overload functions. (We didn't handle the builtin
1015 // properly.)
1016 enum MyFlags {
1017 Zero,
1018 One,
1019 Two,
1020 Three,
1021 Four,
1022 Five,
1023 Six,
1024 Seven,
1025 Eight,
1026 Nine
1027 };
1028
1029 inline MyFlags
operator |(MyFlags a,MyFlags b)1030 operator|(MyFlags a, MyFlags b)
1031 {
1032 return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1033 }
1034
1035 inline MyFlags&
operator |=(MyFlags & a,MyFlags b)1036 operator|=(MyFlags& a, MyFlags b)
1037 {
1038 return a = a | b;
1039 }
1040 } // end namespace thread_annot_lock_65
1041
1042 namespace thread_annot_lock_66_modified {
1043 // Modified: Moved annotation to function defn
1044 // Test annotations on out-of-line definitions of member functions where the
1045 // annotations refer to locks that are also data members in the class.
1046 Mutex mu;
1047
1048 class Foo {
1049 public:
1050 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1051 int data GUARDED_BY(mu1);
1052 Mutex *mu1;
1053 Mutex *mu2;
1054 };
1055
method1(int i)1056 int Foo::method1(int i)
1057 {
1058 return data + i;
1059 }
1060
main()1061 void main()
1062 {
1063 Foo a;
1064
1065 a.mu2->Lock();
1066 a.mu1->Lock();
1067 mu.Lock();
1068 a.method1(1);
1069 mu.Unlock();
1070 a.mu1->Unlock();
1071 a.mu2->Unlock();
1072 }
1073 } // end namespace thread_annot_lock_66_modified
1074
1075 namespace thread_annot_lock_68_modified {
1076 // Test a fix to a bug in the delayed name binding with nested template
1077 // instantiation. We use a stack to make sure a name is not resolved to an
1078 // inner context.
1079 template <typename T>
1080 class Bar {
1081 Mutex mu_;
1082 };
1083
1084 template <typename T>
1085 class Foo {
1086 public:
func(T x)1087 void func(T x) {
1088 mu_.Lock();
1089 count_ = x;
1090 mu_.Unlock();
1091 }
1092
1093 private:
1094 T count_ GUARDED_BY(mu_);
1095 Bar<T> bar_;
1096 Mutex mu_;
1097 };
1098
main()1099 void main()
1100 {
1101 Foo<int> *foo;
1102 foo->func(5);
1103 }
1104 } // end namespace thread_annot_lock_68_modified
1105
1106 namespace thread_annot_lock_30_modified {
1107 // Test delay parsing of lock attribute arguments with nested classes.
1108 // Modified: trylocks replaced with exclusive_lock_fun
1109 int a = 0;
1110
1111 class Bar {
1112 struct Foo;
1113
1114 public:
1115 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1116
func()1117 int func() {
1118 MyLock();
1119 // if (foo == 0) {
1120 // return 0;
1121 // }
1122 a = 5;
1123 mu.Unlock();
1124 return 1;
1125 }
1126
1127 class FooBar {
1128 int x;
1129 int y;
1130 };
1131
1132 private:
1133 Mutex mu;
1134 };
1135
1136 Bar *bar;
1137
main()1138 void main()
1139 {
1140 bar->func();
1141 }
1142 } // end namespace thread_annot_lock_30_modified
1143
1144 namespace thread_annot_lock_47 {
1145 // Test the support for annotations on virtual functions.
1146 // This is a good test case. (i.e. There should be no warning emitted by the
1147 // compiler.)
1148 class Base {
1149 public:
1150 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1151 virtual void func2() LOCKS_EXCLUDED(mu_);
1152 Mutex mu_;
1153 };
1154
1155 class Child : public Base {
1156 public:
1157 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1158 virtual void func2() LOCKS_EXCLUDED(mu_);
1159 };
1160
main()1161 void main() {
1162 Child *c;
1163 Base *b = c;
1164
1165 b->mu_.Lock();
1166 b->func1();
1167 b->mu_.Unlock();
1168 b->func2();
1169
1170 c->mu_.Lock();
1171 c->func1();
1172 c->mu_.Unlock();
1173 c->func2();
1174 }
1175 } // end namespace thread_annot_lock_47
1176
1177 //-----------------------------------------//
1178 // Tests which produce errors
1179 //-----------------------------------------//
1180
1181 namespace thread_annot_lock_13 {
1182 Mutex mu1;
1183 Mutex mu2;
1184
1185 int g GUARDED_BY(mu1);
1186 int w GUARDED_BY(mu2);
1187
1188 class Foo {
1189 public:
1190 void bar() LOCKS_EXCLUDED(mu_, mu1);
1191 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1192
1193 private:
1194 int a_ GUARDED_BY(mu_);
1195 public:
1196 Mutex mu_ ACQUIRED_AFTER(mu1);
1197 };
1198
foo()1199 int Foo::foo()
1200 {
1201 int res;
1202 w = 5;
1203 res = a_ + 5;
1204 return res;
1205 }
1206
bar()1207 void Foo::bar()
1208 {
1209 int x;
1210 mu_.Lock();
1211 x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
1212 a_ = x + 1;
1213 mu_.Unlock();
1214 if (x > 5) {
1215 mu1.Lock();
1216 g = 2;
1217 mu1.Unlock();
1218 }
1219 }
1220
main()1221 void main()
1222 {
1223 Foo f1, *f2;
1224 f1.mu_.Lock();
1225 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
1226 mu2.Lock();
1227 f1.foo();
1228 mu2.Unlock();
1229 f1.mu_.Unlock();
1230 f2->mu_.Lock();
1231 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
1232 f2->mu_.Unlock();
1233 mu2.Lock();
1234 w = 2;
1235 mu2.Unlock();
1236 }
1237 } // end namespace thread_annot_lock_13
1238
1239 namespace thread_annot_lock_18_modified {
1240 // Modified: Trylocks removed
1241 // Test the ability to distnguish between the same lock field of
1242 // different objects of a class.
1243 class Bar {
1244 public:
1245 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1246 void MyUnlock() UNLOCK_FUNCTION(mu1_);
1247 int a_ GUARDED_BY(mu1_);
1248
1249 private:
1250 Mutex mu1_;
1251 };
1252
1253 Bar *b1, *b2;
1254
func()1255 void func()
1256 {
1257 b1->MyLock();
1258 b1->a_ = 5;
1259 b2->a_ = 3; // \
1260 // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
1261 // expected-note {{found near match 'b1->mu1_'}}
1262 b2->MyLock();
1263 b2->MyUnlock();
1264 b1->MyUnlock();
1265 }
1266 } // end namespace thread_annot_lock_18_modified
1267
1268 namespace thread_annot_lock_21 {
1269 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1270 // uses in class definitions.
1271 Mutex mu;
1272
1273 class Bar {
1274 public:
1275 int a_ GUARDED_BY(mu1_);
1276 int b_;
1277 int *q PT_GUARDED_BY(mu);
1278 Mutex mu1_ ACQUIRED_AFTER(mu);
1279 };
1280
1281 Bar b1, *b3;
1282 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1283
1284 int res GUARDED_BY(mu) = 5;
1285
func(int i)1286 int func(int i)
1287 {
1288 int x;
1289 b3->mu1_.Lock();
1290 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
1291 // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
1292 // expected-note {{found near match 'b3->mu1_'}}
1293 *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
1294 // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
1295 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
1296 // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
1297 // expected-note {{found near match 'b3->mu1_'}}
1298 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
1299 b3->mu1_.Unlock();
1300 b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1301 x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
1302 return x;
1303 }
1304 } // end namespace thread_annot_lock_21
1305
1306 namespace thread_annot_lock_35_modified {
1307 // Test the analyzer's ability to distinguish the lock field of different
1308 // objects.
1309 class Foo {
1310 private:
1311 Mutex lock_;
1312 int a_ GUARDED_BY(lock_);
1313
1314 public:
Func(Foo * child)1315 void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1316 Foo *new_foo = new Foo;
1317
1318 lock_.Lock();
1319
1320 child->Func(new_foo); // There shouldn't be any warning here as the
1321 // acquired lock is not in child.
1322 child->bar(7); // \
1323 // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
1324 // expected-note {{found near match 'lock_'}}
1325 child->a_ = 5; // \
1326 // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
1327 // expected-note {{found near match 'lock_'}}
1328 lock_.Unlock();
1329 }
1330
bar(int y)1331 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1332 a_ = y;
1333 }
1334 };
1335
1336 Foo *x;
1337
main()1338 void main() {
1339 Foo *child = new Foo;
1340 x->Func(child);
1341 }
1342 } // end namespace thread_annot_lock_35_modified
1343
1344 namespace thread_annot_lock_36_modified {
1345 // Modified to move the annotations to function defns.
1346 // Test the analyzer's ability to distinguish the lock field of different
1347 // objects
1348 class Foo {
1349 private:
1350 Mutex lock_;
1351 int a_ GUARDED_BY(lock_);
1352
1353 public:
1354 void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1355 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1356 };
1357
Func(Foo * child)1358 void Foo::Func(Foo* child) {
1359 Foo *new_foo = new Foo;
1360
1361 lock_.Lock();
1362
1363 child->lock_.Lock();
1364 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
1365 child->bar(7);
1366 child->a_ = 5;
1367 child->lock_.Unlock();
1368
1369 lock_.Unlock();
1370 }
1371
bar(int y)1372 void Foo::bar(int y) {
1373 a_ = y;
1374 }
1375
1376
1377 Foo *x;
1378
main()1379 void main() {
1380 Foo *child = new Foo;
1381 x->Func(child);
1382 }
1383 } // end namespace thread_annot_lock_36_modified
1384
1385
1386 namespace thread_annot_lock_42 {
1387 // Test support of multiple lock attributes of the same kind on a decl.
1388 class Foo {
1389 private:
1390 Mutex mu1, mu2, mu3;
1391 int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1392 int y GUARDED_BY(mu2);
1393
f2()1394 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1395 mu2.Lock();
1396 y = 2;
1397 mu2.Unlock();
1398 }
1399
1400 public:
f1()1401 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1402 x = 5;
1403 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
1404 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
1405 }
1406 };
1407
1408 Foo *foo;
1409
func()1410 void func()
1411 {
1412 foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
1413 // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
1414 }
1415 } // end namespace thread_annot_lock_42
1416
1417 namespace thread_annot_lock_46 {
1418 // Test the support for annotations on virtual functions.
1419 class Base {
1420 public:
1421 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1422 virtual void func2() LOCKS_EXCLUDED(mu_);
1423 Mutex mu_;
1424 };
1425
1426 class Child : public Base {
1427 public:
1428 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1429 virtual void func2() LOCKS_EXCLUDED(mu_);
1430 };
1431
main()1432 void main() {
1433 Child *c;
1434 Base *b = c;
1435
1436 b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
1437 b->mu_.Lock();
1438 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
1439 b->mu_.Unlock();
1440
1441 c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
1442 c->mu_.Lock();
1443 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
1444 c->mu_.Unlock();
1445 }
1446 } // end namespace thread_annot_lock_46
1447
1448 namespace thread_annot_lock_67_modified {
1449 // Modified: attributes on definitions moved to declarations
1450 // Test annotations on out-of-line definitions of member functions where the
1451 // annotations refer to locks that are also data members in the class.
1452 Mutex mu;
1453 Mutex mu3;
1454
1455 class Foo {
1456 public:
1457 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1458 int data GUARDED_BY(mu1);
1459 Mutex *mu1;
1460 Mutex *mu2;
1461 };
1462
method1(int i)1463 int Foo::method1(int i) {
1464 return data + i;
1465 }
1466
main()1467 void main()
1468 {
1469 Foo a;
1470 a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
1471 // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
1472 // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
1473 // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
1474 }
1475 } // end namespace thread_annot_lock_67_modified
1476
1477
1478 namespace substitution_test {
1479 class MyData {
1480 public:
1481 Mutex mu;
1482
1483 void lockData() __attribute__((exclusive_lock_function(mu)));
1484 void unlockData() __attribute__((unlock_function(mu)));
1485
doSomething()1486 void doSomething() __attribute__((exclusive_locks_required(mu))) { }
1487 };
1488
1489
1490 class DataLocker {
1491 public:
1492 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu)));
1493 void unlockData(MyData *d) __attribute__((unlock_function(d->mu)));
1494 };
1495
1496
1497 class Foo {
1498 public:
foo(MyData * d)1499 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { }
1500
bar1(MyData * d)1501 void bar1(MyData* d) {
1502 d->lockData();
1503 foo(d);
1504 d->unlockData();
1505 }
1506
bar2(MyData * d)1507 void bar2(MyData* d) {
1508 DataLocker dlr;
1509 dlr.lockData(d);
1510 foo(d);
1511 dlr.unlockData(d);
1512 }
1513
bar3(MyData * d1,MyData * d2)1514 void bar3(MyData* d1, MyData* d2) {
1515 DataLocker dlr;
1516 dlr.lockData(d1); // expected-note {{mutex acquired here}}
1517 dlr.unlockData(d2); // \
1518 // expected-warning {{unlocking 'd2->mu' that was not locked}}
1519 } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
1520
bar4(MyData * d1,MyData * d2)1521 void bar4(MyData* d1, MyData* d2) {
1522 DataLocker dlr;
1523 dlr.lockData(d1);
1524 foo(d2); // \
1525 // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
1526 // expected-note {{found near match 'd1->mu'}}
1527 dlr.unlockData(d1);
1528 }
1529 };
1530 } // end namespace substituation_test
1531
1532
1533
1534 namespace constructor_destructor_tests {
1535 Mutex fooMu;
1536 int myVar GUARDED_BY(fooMu);
1537
1538 class Foo {
1539 public:
Foo()1540 Foo() __attribute__((exclusive_lock_function(fooMu))) { }
~Foo()1541 ~Foo() __attribute__((unlock_function(fooMu))) { }
1542 };
1543
fooTest()1544 void fooTest() {
1545 Foo foo;
1546 myVar = 0;
1547 }
1548 }
1549
1550
1551 namespace template_member_test {
1552
1553 struct S { int n; };
1554 struct T {
1555 Mutex m;
1556 S *s GUARDED_BY(this->m);
1557 };
1558 Mutex m;
1559 struct U {
1560 union {
1561 int n;
1562 };
1563 } *u GUARDED_BY(m);
1564
1565 template<typename U>
1566 struct IndirectLock {
DoNaughtyThingstemplate_member_test::IndirectLock1567 int DoNaughtyThings(T *t) {
1568 u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
1569 return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
1570 }
1571 };
1572
1573 template struct IndirectLock<int>; // expected-note {{here}}
1574
1575 struct V {
1576 void f(int);
1577 void f(double);
1578
1579 Mutex m;
1580 V *p GUARDED_BY(this->m);
1581 };
1582 template<typename U> struct W {
1583 V v;
ftemplate_member_test::W1584 void f(U u) {
1585 v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
1586 }
1587 };
1588 template struct W<int>; // expected-note {{here}}
1589
1590 }
1591
1592 namespace test_scoped_lockable {
1593
1594 struct TestScopedLockable {
1595 Mutex mu1;
1596 Mutex mu2;
1597 int a __attribute__((guarded_by(mu1)));
1598 int b __attribute__((guarded_by(mu2)));
1599
1600 bool getBool();
1601
foo1test_scoped_lockable::TestScopedLockable1602 void foo1() {
1603 MutexLock mulock(&mu1);
1604 a = 5;
1605 }
1606
foo2test_scoped_lockable::TestScopedLockable1607 void foo2() {
1608 ReaderMutexLock mulock1(&mu1);
1609 if (getBool()) {
1610 MutexLock mulock2a(&mu2);
1611 b = a + 1;
1612 }
1613 else {
1614 MutexLock mulock2b(&mu2);
1615 b = a + 2;
1616 }
1617 }
1618
foo3test_scoped_lockable::TestScopedLockable1619 void foo3() {
1620 MutexLock mulock_a(&mu1);
1621 MutexLock mulock_b(&mu1); // \
1622 // expected-warning {{locking 'mu1' that is already locked}}
1623 }
1624
foo4test_scoped_lockable::TestScopedLockable1625 void foo4() {
1626 MutexLock mulock1(&mu1), mulock2(&mu2);
1627 a = b+1;
1628 b = a+1;
1629 }
1630 };
1631
1632 } // end namespace test_scoped_lockable
1633
1634
1635 namespace FunctionAttrTest {
1636
1637 class Foo {
1638 public:
1639 Mutex mu_;
1640 int a GUARDED_BY(mu_);
1641 };
1642
1643 Foo fooObj;
1644
1645 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1646
bar()1647 void bar() {
1648 foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
1649 fooObj.mu_.Lock();
1650 foo();
1651 fooObj.mu_.Unlock();
1652 }
1653
1654 }; // end namespace FunctionAttrTest
1655
1656
1657 namespace TryLockTest {
1658
1659 struct TestTryLock {
1660 Mutex mu;
1661 int a GUARDED_BY(mu);
1662 bool cond;
1663
foo1TryLockTest::TestTryLock1664 void foo1() {
1665 if (mu.TryLock()) {
1666 a = 1;
1667 mu.Unlock();
1668 }
1669 }
1670
foo2TryLockTest::TestTryLock1671 void foo2() {
1672 if (!mu.TryLock()) return;
1673 a = 2;
1674 mu.Unlock();
1675 }
1676
foo3TryLockTest::TestTryLock1677 void foo3() {
1678 bool b = mu.TryLock();
1679 if (b) {
1680 a = 3;
1681 mu.Unlock();
1682 }
1683 }
1684
foo4TryLockTest::TestTryLock1685 void foo4() {
1686 bool b = mu.TryLock();
1687 if (!b) return;
1688 a = 4;
1689 mu.Unlock();
1690 }
1691
foo5TryLockTest::TestTryLock1692 void foo5() {
1693 while (mu.TryLock()) {
1694 a = a + 1;
1695 mu.Unlock();
1696 }
1697 }
1698
foo6TryLockTest::TestTryLock1699 void foo6() {
1700 bool b = mu.TryLock();
1701 b = !b;
1702 if (b) return;
1703 a = 6;
1704 mu.Unlock();
1705 }
1706
foo7TryLockTest::TestTryLock1707 void foo7() {
1708 bool b1 = mu.TryLock();
1709 bool b2 = !b1;
1710 bool b3 = !b2;
1711 if (b3) {
1712 a = 7;
1713 mu.Unlock();
1714 }
1715 }
1716
1717 // Test use-def chains: join points
foo8TryLockTest::TestTryLock1718 void foo8() {
1719 bool b = mu.TryLock();
1720 bool b2 = b;
1721 if (cond)
1722 b = true;
1723 if (b) { // b should be unknown at this point, because of the join point
1724 a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1725 }
1726 if (b2) { // b2 should be known at this point.
1727 a = 8;
1728 mu.Unlock();
1729 }
1730 }
1731
1732 // Test use-def-chains: back edges
foo9TryLockTest::TestTryLock1733 void foo9() {
1734 bool b = mu.TryLock();
1735
1736 for (int i = 0; i < 10; ++i);
1737
1738 if (b) { // b is still known, because the loop doesn't alter it
1739 a = 9;
1740 mu.Unlock();
1741 }
1742 }
1743
1744 // Test use-def chains: back edges
foo10TryLockTest::TestTryLock1745 void foo10() {
1746 bool b = mu.TryLock();
1747
1748 while (cond) {
1749 if (b) { // b should be uknown at this point b/c of the loop
1750 a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
1751 }
1752 b = !b;
1753 }
1754 }
1755
1756 // Test merge of exclusive trylock
foo11TryLockTest::TestTryLock1757 void foo11() {
1758 if (cond) {
1759 if (!mu.TryLock())
1760 return;
1761 }
1762 else {
1763 mu.Lock();
1764 }
1765 a = 10;
1766 mu.Unlock();
1767 }
1768
1769 // Test merge of shared trylock
foo12TryLockTest::TestTryLock1770 void foo12() {
1771 if (cond) {
1772 if (!mu.ReaderTryLock())
1773 return;
1774 }
1775 else {
1776 mu.ReaderLock();
1777 }
1778 int i = a;
1779 mu.Unlock();
1780 }
1781 }; // end TestTrylock
1782
1783 } // end namespace TrylockTest
1784
1785
1786 namespace TestTemplateAttributeInstantiation {
1787
1788 class Foo1 {
1789 public:
1790 Mutex mu_;
1791 int a GUARDED_BY(mu_);
1792 };
1793
1794 class Foo2 {
1795 public:
1796 int a GUARDED_BY(mu_);
1797 Mutex mu_;
1798 };
1799
1800
1801 class Bar {
1802 public:
1803 // Test non-dependent expressions in attributes on template functions
1804 template <class T>
barND(Foo1 * foo,T * fooT)1805 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
1806 foo->a = 0;
1807 }
1808
1809 // Test dependent expressions in attributes on template functions
1810 template <class T>
barD(Foo1 * foo,T * fooT)1811 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
1812 fooT->a = 0;
1813 }
1814 };
1815
1816
1817 template <class T>
1818 class BarT {
1819 public:
1820 Foo1 fooBase;
1821 T fooBaseT;
1822
1823 // Test non-dependent expression in ordinary method on template class
barND()1824 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
1825 fooBase.a = 0;
1826 }
1827
1828 // Test dependent expressions in ordinary methods on template class
barD()1829 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
1830 fooBaseT.a = 0;
1831 }
1832
1833 // Test dependent expressions in template method in template class
1834 template <class T2>
barTD(T2 * fooT)1835 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
1836 fooBaseT.a = 0;
1837 fooT->a = 0;
1838 }
1839 };
1840
1841 template <class T>
1842 class Cell {
1843 public:
1844 Mutex mu_;
1845 // Test dependent guarded_by
1846 T data GUARDED_BY(mu_);
1847
fooEx()1848 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1849 data = 0;
1850 }
1851
foo()1852 void foo() {
1853 mu_.Lock();
1854 data = 0;
1855 mu_.Unlock();
1856 }
1857 };
1858
test()1859 void test() {
1860 Bar b;
1861 BarT<Foo2> bt;
1862 Foo1 f1;
1863 Foo2 f2;
1864
1865 f1.mu_.Lock();
1866 f2.mu_.Lock();
1867 bt.fooBase.mu_.Lock();
1868 bt.fooBaseT.mu_.Lock();
1869
1870 b.barND(&f1, &f2);
1871 b.barD(&f1, &f2);
1872 bt.barND();
1873 bt.barD();
1874 bt.barTD(&f2);
1875
1876 f1.mu_.Unlock();
1877 bt.barTD(&f1); // \
1878 // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
1879 // expected-note {{found near match 'bt.fooBase.mu_'}}
1880
1881 bt.fooBase.mu_.Unlock();
1882 bt.fooBaseT.mu_.Unlock();
1883 f2.mu_.Unlock();
1884
1885 Cell<int> cell;
1886 cell.data = 0; // \
1887 // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
1888 cell.foo();
1889 cell.mu_.Lock();
1890 cell.fooEx();
1891 cell.mu_.Unlock();
1892 }
1893
1894
1895 template <class T>
1896 class CellDelayed {
1897 public:
1898 // Test dependent guarded_by
1899 T data GUARDED_BY(mu_);
1900 static T static_data GUARDED_BY(static_mu_);
1901
fooEx(CellDelayed<T> * other)1902 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
1903 this->data = other->data;
1904 }
1905
1906 template <class T2>
fooExT(CellDelayed<T2> * otherT)1907 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
1908 this->data = otherT->data;
1909 }
1910
foo()1911 void foo() {
1912 mu_.Lock();
1913 data = 0;
1914 mu_.Unlock();
1915 }
1916
1917 Mutex mu_;
1918 static Mutex static_mu_;
1919 };
1920
testDelayed()1921 void testDelayed() {
1922 CellDelayed<int> celld;
1923 CellDelayed<int> celld2;
1924 celld.foo();
1925 celld.mu_.Lock();
1926 celld2.mu_.Lock();
1927
1928 celld.fooEx(&celld2);
1929 celld.fooExT(&celld2);
1930
1931 celld2.mu_.Unlock();
1932 celld.mu_.Unlock();
1933 }
1934
1935 }; // end namespace TestTemplateAttributeInstantiation
1936
1937
1938 namespace FunctionDeclDefTest {
1939
1940 class Foo {
1941 public:
1942 Mutex mu_;
1943 int a GUARDED_BY(mu_);
1944
1945 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
1946 };
1947
1948 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
foo1(Foo * f_defined)1949 void Foo::foo1(Foo *f_defined) {
1950 f_defined->a = 0;
1951 };
1952
test()1953 void test() {
1954 Foo myfoo;
1955 myfoo.foo1(&myfoo); // \
1956 // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
1957 myfoo.mu_.Lock();
1958 myfoo.foo1(&myfoo);
1959 myfoo.mu_.Unlock();
1960 }
1961
1962 };
1963
1964 namespace GoingNative {
1965
1966 struct __attribute__((lockable)) mutex {
1967 void lock() __attribute__((exclusive_lock_function));
1968 void unlock() __attribute__((unlock_function));
1969 // ...
1970 };
1971 bool foo();
1972 bool bar();
1973 mutex m;
test()1974 void test() {
1975 m.lock();
1976 while (foo()) {
1977 m.unlock();
1978 // ...
1979 if (bar()) {
1980 // ...
1981 if (foo())
1982 continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
1983 //...
1984 }
1985 // ...
1986 m.lock(); // expected-note {{mutex acquired here}}
1987 }
1988 m.unlock();
1989 }
1990
1991 }
1992
1993
1994
1995 namespace FunctionDefinitionTest {
1996
1997 class Foo {
1998 public:
1999 void foo1();
2000 void foo2();
2001 void foo3(Foo *other);
2002
2003 template<class T>
2004 void fooT1(const T& dummy1);
2005
2006 template<class T>
2007 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2008
2009 Mutex mu_;
2010 int a GUARDED_BY(mu_);
2011 };
2012
2013 template<class T>
2014 class FooT {
2015 public:
2016 void foo();
2017
2018 Mutex mu_;
2019 T a GUARDED_BY(mu_);
2020 };
2021
2022
foo1()2023 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2024 a = 1;
2025 }
2026
foo2()2027 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2028 a = 2;
2029 }
2030
foo3(Foo * other)2031 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2032 other->a = 3;
2033 }
2034
2035 template<class T>
fooT1(const T & dummy1)2036 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2037 a = dummy1;
2038 }
2039
2040 /* TODO -- uncomment with template instantiation of attributes.
2041 template<class T>
2042 void Foo::fooT2(const T& dummy2) {
2043 a = dummy2;
2044 }
2045 */
2046
fooF1(Foo * f)2047 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2048 f->a = 1;
2049 }
2050
2051 void fooF2(Foo *f);
fooF2(Foo * f)2052 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2053 f->a = 2;
2054 }
2055
2056 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
fooF3(Foo * f)2057 void fooF3(Foo *f) {
2058 f->a = 3;
2059 }
2060
2061 template<class T>
foo()2062 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2063 a = 0;
2064 }
2065
test()2066 void test() {
2067 int dummy = 0;
2068 Foo myFoo;
2069
2070 myFoo.foo2(); // \
2071 // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
2072 myFoo.foo3(&myFoo); // \
2073 // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
2074 myFoo.fooT1(dummy); // \
2075 // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
2076
2077 myFoo.fooT2(dummy); // \
2078 // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
2079
2080 fooF1(&myFoo); // \
2081 // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
2082 fooF2(&myFoo); // \
2083 // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
2084 fooF3(&myFoo); // \
2085 // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
2086
2087 myFoo.mu_.Lock();
2088 myFoo.foo2();
2089 myFoo.foo3(&myFoo);
2090 myFoo.fooT1(dummy);
2091
2092 myFoo.fooT2(dummy);
2093
2094 fooF1(&myFoo);
2095 fooF2(&myFoo);
2096 fooF3(&myFoo);
2097 myFoo.mu_.Unlock();
2098
2099 FooT<int> myFooT;
2100 myFooT.foo(); // \
2101 // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
2102 }
2103
2104 } // end namespace FunctionDefinitionTest
2105
2106
2107 namespace SelfLockingTest {
2108
2109 class LOCKABLE MyLock {
2110 public:
2111 int foo GUARDED_BY(this);
2112
2113 void lock() EXCLUSIVE_LOCK_FUNCTION();
2114 void unlock() UNLOCK_FUNCTION();
2115
doSomething()2116 void doSomething() {
2117 this->lock(); // allow 'this' as a lock expression
2118 foo = 0;
2119 doSomethingElse();
2120 this->unlock();
2121 }
2122
doSomethingElse()2123 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2124 foo = 1;
2125 };
2126
test()2127 void test() {
2128 foo = 2; // \
2129 // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
2130 }
2131 };
2132
2133
2134 class LOCKABLE MyLock2 {
2135 public:
2136 Mutex mu_;
2137 int foo GUARDED_BY(this);
2138
2139 // don't check inside lock and unlock functions
lock()2140 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
unlock()2141 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
2142
2143 // don't check inside constructors and destructors
MyLock2()2144 MyLock2() { foo = 1; }
~MyLock2()2145 ~MyLock2() { foo = 0; }
2146 };
2147
2148
2149 } // end namespace SelfLockingTest
2150
2151
2152 namespace InvalidNonstatic {
2153
2154 // Forward decl here causes bogus "invalid use of non-static data member"
2155 // on reference to mutex_ in guarded_by attribute.
2156 class Foo;
2157
2158 class Foo {
2159 Mutex* mutex_;
2160
2161 int foo __attribute__((guarded_by(mutex_)));
2162 };
2163
2164 } // end namespace InvalidNonStatic
2165
2166
2167 namespace NoReturnTest {
2168
2169 bool condition();
2170 void fatal() __attribute__((noreturn));
2171
2172 Mutex mu_;
2173
test1()2174 void test1() {
2175 MutexLock lock(&mu_);
2176 if (condition()) {
2177 fatal();
2178 return;
2179 }
2180 }
2181
2182 } // end namespace NoReturnTest
2183
2184
2185 namespace TestMultiDecl {
2186
2187 class Foo {
2188 public:
2189 int GUARDED_BY(mu_) a;
2190 int GUARDED_BY(mu_) b, c;
2191
foo()2192 void foo() {
2193 a = 0; // \
2194 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2195 b = 0; // \
2196 // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
2197 c = 0; // \
2198 // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
2199 }
2200
2201 private:
2202 Mutex mu_;
2203 };
2204
2205 } // end namespace TestMultiDecl
2206
2207
2208 namespace WarnNoDecl {
2209
2210 class Foo {
2211 void foo(int a); __attribute__(( // \
2212 // expected-warning {{declaration does not declare anything}}
2213 exclusive_locks_required(a))); // \
2214 // expected-warning {{attribute exclusive_locks_required ignored}}
2215 };
2216
2217 } // end namespace WarnNoDecl
2218
2219
2220
2221 namespace MoreLockExpressions {
2222
2223 class Foo {
2224 public:
2225 Mutex mu_;
2226 int a GUARDED_BY(mu_);
2227 };
2228
2229 class Bar {
2230 public:
2231 int b;
2232 Foo* f;
2233
getFoo()2234 Foo& getFoo() { return *f; }
getFoo2(int c)2235 Foo& getFoo2(int c) { return *f; }
getFoo3(int c,int d)2236 Foo& getFoo3(int c, int d) { return *f; }
2237
getFooey()2238 Foo& getFooey() { return *f; }
2239 };
2240
getBarFoo(Bar & bar,int c)2241 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
2242
test()2243 void test() {
2244 Foo foo;
2245 Foo *fooArray;
2246 Bar bar;
2247 int a;
2248 int b;
2249 int c;
2250
2251 bar.getFoo().mu_.Lock();
2252 bar.getFoo().a = 0;
2253 bar.getFoo().mu_.Unlock();
2254
2255 (bar.getFoo().mu_).Lock(); // test parenthesis
2256 bar.getFoo().a = 0;
2257 (bar.getFoo().mu_).Unlock();
2258
2259 bar.getFoo2(a).mu_.Lock();
2260 bar.getFoo2(a).a = 0;
2261 bar.getFoo2(a).mu_.Unlock();
2262
2263 bar.getFoo3(a, b).mu_.Lock();
2264 bar.getFoo3(a, b).a = 0;
2265 bar.getFoo3(a, b).mu_.Unlock();
2266
2267 getBarFoo(bar, a).mu_.Lock();
2268 getBarFoo(bar, a).a = 0;
2269 getBarFoo(bar, a).mu_.Unlock();
2270
2271 bar.getFoo2(10).mu_.Lock();
2272 bar.getFoo2(10).a = 0;
2273 bar.getFoo2(10).mu_.Unlock();
2274
2275 bar.getFoo2(a + 1).mu_.Lock();
2276 bar.getFoo2(a + 1).a = 0;
2277 bar.getFoo2(a + 1).mu_.Unlock();
2278
2279 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2280 (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
2281 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2282
2283 bar.getFoo().mu_.Lock();
2284 bar.getFooey().a = 0; // \
2285 // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
2286 // expected-note {{found near match 'bar.getFoo().mu_'}}
2287 bar.getFoo().mu_.Unlock();
2288
2289 bar.getFoo2(a).mu_.Lock();
2290 bar.getFoo2(b).a = 0; // \
2291 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
2292 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2293 bar.getFoo2(a).mu_.Unlock();
2294
2295 bar.getFoo3(a, b).mu_.Lock();
2296 bar.getFoo3(a, c).a = 0; // \
2297 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
2298 // expected-note {{'bar.getFoo3(a,b).mu_'}}
2299 bar.getFoo3(a, b).mu_.Unlock();
2300
2301 getBarFoo(bar, a).mu_.Lock();
2302 getBarFoo(bar, b).a = 0; // \
2303 // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
2304 // expected-note {{'getBarFoo(bar,a).mu_'}}
2305 getBarFoo(bar, a).mu_.Unlock();
2306
2307 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2308 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2309 // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
2310 // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
2311 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2312 }
2313
2314
2315 } // end namespace MoreLockExpressions
2316
2317
2318 namespace TrylockJoinPoint {
2319
2320 class Foo {
2321 Mutex mu;
2322 bool c;
2323
foo()2324 void foo() {
2325 if (c) {
2326 if (!mu.TryLock())
2327 return;
2328 } else {
2329 mu.Lock();
2330 }
2331 mu.Unlock();
2332 }
2333 };
2334
2335 } // end namespace TrylockJoinPoint
2336
2337
2338 namespace LockReturned {
2339
2340 class Foo {
2341 public:
2342 int a GUARDED_BY(mu_);
2343 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2344 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2345
2346 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2347
2348 Mutex* getMu() LOCK_RETURNED(mu_);
2349
2350 Mutex mu_;
2351
2352 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2353 };
2354
2355
2356 // Calls getMu() directly to lock and unlock
test1(Foo * f1,Foo * f2)2357 void test1(Foo* f1, Foo* f2) {
2358 f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
2359 f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
2360
2361 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
2362 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
2363 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
2364
2365 f1->getMu()->Lock();
2366
2367 f1->a = 0;
2368 f1->foo();
2369 f1->foo2(f2); // \
2370 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
2371 // expected-note {{found near match 'f1->mu_'}}
2372
2373 Foo::getMu(f2)->Lock();
2374 f1->foo2(f2);
2375 Foo::getMu(f2)->Unlock();
2376
2377 Foo::sfoo(f1);
2378
2379 f1->getMu()->Unlock();
2380 }
2381
2382
2383 Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2384
2385 class Bar : public Foo {
2386 public:
2387 int b GUARDED_BY(getMu());
2388 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2389 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2390
2391 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2392 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2393 };
2394
2395
2396
2397 // Use getMu() within other attributes.
2398 // This requires at lest levels of substitution, more in the case of
test2(Bar * b1,Bar * b2)2399 void test2(Bar* b1, Bar* b2) {
2400 b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
2401 b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
2402 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
2403 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
2404 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
2405 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
2406
2407 b1->getMu()->Lock();
2408
2409 b1->b = 0;
2410 b1->bar();
2411 b1->bar2(b2); // \
2412 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
2413 // // expected-note {{found near match 'b1->mu_'}}
2414
2415 b2->getMu()->Lock();
2416 b1->bar2(b2);
2417
2418 b2->getMu()->Unlock();
2419
2420 Bar::sbar(b1);
2421 Bar::sbar2(b1);
2422
2423 b1->getMu()->Unlock();
2424 }
2425
2426
2427 // Sanity check -- lock the mutex directly, but use attributes that call getMu()
2428 // Also lock the mutex using getFooMu, which calls a lock_returned function.
test3(Bar * b1,Bar * b2)2429 void test3(Bar* b1, Bar* b2) {
2430 b1->mu_.Lock();
2431 b1->b = 0;
2432 b1->bar();
2433
2434 getFooMu(b2)->Lock();
2435 b1->bar2(b2);
2436 getFooMu(b2)->Unlock();
2437
2438 Bar::sbar(b1);
2439 Bar::sbar2(b1);
2440
2441 b1->mu_.Unlock();
2442 }
2443
2444 } // end namespace LockReturned
2445
2446
2447 namespace ReleasableScopedLock {
2448
2449 class Foo {
2450 Mutex mu_;
2451 bool c;
2452 int a GUARDED_BY(mu_);
2453
2454 void test1();
2455 void test2();
2456 void test3();
2457 void test4();
2458 void test5();
2459 };
2460
2461
test1()2462 void Foo::test1() {
2463 ReleasableMutexLock rlock(&mu_);
2464 rlock.Release();
2465 }
2466
test2()2467 void Foo::test2() {
2468 ReleasableMutexLock rlock(&mu_);
2469 if (c) { // test join point -- held/not held during release
2470 rlock.Release();
2471 }
2472 }
2473
test3()2474 void Foo::test3() {
2475 ReleasableMutexLock rlock(&mu_);
2476 a = 0;
2477 rlock.Release();
2478 a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2479 }
2480
test4()2481 void Foo::test4() {
2482 ReleasableMutexLock rlock(&mu_);
2483 rlock.Release();
2484 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
2485 }
2486
test5()2487 void Foo::test5() {
2488 ReleasableMutexLock rlock(&mu_);
2489 if (c) {
2490 rlock.Release();
2491 }
2492 // no warning on join point for managed lock.
2493 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
2494 }
2495
2496
2497 } // end namespace ReleasableScopedLock
2498
2499
2500 namespace TrylockFunctionTest {
2501
2502 class Foo {
2503 public:
2504 Mutex mu1_;
2505 Mutex mu2_;
2506 bool c;
2507
2508 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
2509 };
2510
lockBoth()2511 bool Foo::lockBoth() {
2512 if (!mu1_.TryLock())
2513 return false;
2514
2515 mu2_.Lock();
2516 if (!c) {
2517 mu1_.Unlock();
2518 mu2_.Unlock();
2519 return false;
2520 }
2521
2522 return true;
2523 }
2524
2525
2526 } // end namespace TrylockFunctionTest
2527
2528
2529
2530 namespace DoubleLockBug {
2531
2532 class Foo {
2533 public:
2534 Mutex mu_;
2535 int a GUARDED_BY(mu_);
2536
2537 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2538 int foo2() SHARED_LOCKS_REQUIRED(mu_);
2539 };
2540
2541
foo1()2542 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2543 a = 0;
2544 }
2545
foo2()2546 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
2547 return a;
2548 }
2549
2550 }
2551
2552
2553
2554 namespace UnlockBug {
2555
2556 class Foo {
2557 public:
2558 Mutex mutex_;
2559
foo1()2560 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2561 mutex_.Unlock();
2562 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2563
2564
foo2()2565 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2566 mutex_.Unlock();
2567 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
2568 };
2569
2570 } // end namespace UnlockBug
2571
2572
2573
2574 namespace FoolishScopedLockableBug {
2575
2576 class SCOPED_LOCKABLE WTF_ScopedLockable {
2577 public:
2578 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2579
2580 // have to call release() manually;
2581 ~WTF_ScopedLockable();
2582
2583 void release() UNLOCK_FUNCTION();
2584 };
2585
2586
2587 class Foo {
2588 Mutex mu_;
2589 int a GUARDED_BY(mu_);
2590 bool c;
2591
2592 void doSomething();
2593
test1()2594 void test1() {
2595 WTF_ScopedLockable wtf(&mu_);
2596 wtf.release();
2597 }
2598
test2()2599 void test2() {
2600 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2601 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
2602
test3()2603 void test3() {
2604 if (c) {
2605 WTF_ScopedLockable wtf(&mu_);
2606 wtf.release();
2607 }
2608 }
2609
test4()2610 void test4() {
2611 if (c) {
2612 doSomething();
2613 }
2614 else {
2615 WTF_ScopedLockable wtf(&mu_);
2616 wtf.release();
2617 }
2618 }
2619
test5()2620 void test5() {
2621 if (c) {
2622 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2623 }
2624 } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2625
test6()2626 void test6() {
2627 if (c) {
2628 doSomething();
2629 }
2630 else {
2631 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2632 }
2633 } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
2634 };
2635
2636
2637 } // end namespace FoolishScopedLockableBug
2638
2639
2640
2641 namespace TemporaryCleanupExpr {
2642
2643 class Foo {
2644 int a GUARDED_BY(getMutexPtr().get());
2645
2646 SmartPtr<Mutex> getMutexPtr();
2647
2648 void test();
2649 };
2650
2651
test()2652 void Foo::test() {
2653 {
2654 ReaderMutexLock lock(getMutexPtr().get());
2655 int b = a;
2656 }
2657 int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
2658 }
2659
2660 } // end namespace TemporaryCleanupExpr
2661
2662
2663
2664 namespace SmartPointerTests {
2665
2666 class Foo {
2667 public:
2668 SmartPtr<Mutex> mu_;
2669 int a GUARDED_BY(mu_);
2670 int b GUARDED_BY(mu_.get());
2671 int c GUARDED_BY(*mu_);
2672
2673 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
2674 void Unlock() UNLOCK_FUNCTION(mu_);
2675
2676 void test0();
2677 void test1();
2678 void test2();
2679 void test3();
2680 void test4();
2681 void test5();
2682 void test6();
2683 void test7();
2684 void test8();
2685 };
2686
test0()2687 void Foo::test0() {
2688 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
2689 b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
2690 c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
2691 }
2692
test1()2693 void Foo::test1() {
2694 mu_->Lock();
2695 a = 0;
2696 b = 0;
2697 c = 0;
2698 mu_->Unlock();
2699 }
2700
test2()2701 void Foo::test2() {
2702 (*mu_).Lock();
2703 a = 0;
2704 b = 0;
2705 c = 0;
2706 (*mu_).Unlock();
2707 }
2708
2709
test3()2710 void Foo::test3() {
2711 mu_.get()->Lock();
2712 a = 0;
2713 b = 0;
2714 c = 0;
2715 mu_.get()->Unlock();
2716 }
2717
2718
test4()2719 void Foo::test4() {
2720 MutexLock lock(mu_.get());
2721 a = 0;
2722 b = 0;
2723 c = 0;
2724 }
2725
2726
test5()2727 void Foo::test5() {
2728 MutexLock lock(&(*mu_));
2729 a = 0;
2730 b = 0;
2731 c = 0;
2732 }
2733
2734
test6()2735 void Foo::test6() {
2736 Lock();
2737 a = 0;
2738 b = 0;
2739 c = 0;
2740 Unlock();
2741 }
2742
2743
test7()2744 void Foo::test7() {
2745 {
2746 Lock();
2747 mu_->Unlock();
2748 }
2749 {
2750 mu_->Lock();
2751 Unlock();
2752 }
2753 {
2754 mu_.get()->Lock();
2755 mu_->Unlock();
2756 }
2757 {
2758 mu_->Lock();
2759 mu_.get()->Unlock();
2760 }
2761 {
2762 mu_.get()->Lock();
2763 (*mu_).Unlock();
2764 }
2765 {
2766 (*mu_).Lock();
2767 mu_->Unlock();
2768 }
2769 }
2770
2771
test8()2772 void Foo::test8() {
2773 mu_->Lock();
2774 mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}}
2775 (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}}
2776 mu_.get()->Unlock();
2777 Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}}
2778 }
2779
2780
2781 class Bar {
2782 SmartPtr<Foo> foo;
2783
2784 void test0();
2785 void test1();
2786 void test2();
2787 void test3();
2788 };
2789
2790
test0()2791 void Bar::test0() {
2792 foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
2793 (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
2794 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
2795 }
2796
2797
test1()2798 void Bar::test1() {
2799 foo->mu_->Lock();
2800 foo->a = 0;
2801 (*foo).b = 0;
2802 foo.get()->c = 0;
2803 foo->mu_->Unlock();
2804 }
2805
2806
test2()2807 void Bar::test2() {
2808 (*foo).mu_->Lock();
2809 foo->a = 0;
2810 (*foo).b = 0;
2811 foo.get()->c = 0;
2812 foo.get()->mu_->Unlock();
2813 }
2814
2815
test3()2816 void Bar::test3() {
2817 MutexLock lock(foo->mu_.get());
2818 foo->a = 0;
2819 (*foo).b = 0;
2820 foo.get()->c = 0;
2821 }
2822
2823 } // end namespace SmartPointerTests
2824
2825
2826
2827 namespace DuplicateAttributeTest {
2828
2829 class LOCKABLE Foo {
2830 public:
2831 Mutex mu1_;
2832 Mutex mu2_;
2833 Mutex mu3_;
2834 int a GUARDED_BY(mu1_);
2835 int b GUARDED_BY(mu2_);
2836 int c GUARDED_BY(mu3_);
2837
2838 void lock() EXCLUSIVE_LOCK_FUNCTION();
2839 void unlock() UNLOCK_FUNCTION();
2840
2841 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
2842 void slock1() SHARED_LOCK_FUNCTION(mu1_);
2843 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2844 void locklots()
2845 EXCLUSIVE_LOCK_FUNCTION(mu1_)
2846 EXCLUSIVE_LOCK_FUNCTION(mu2_)
2847 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
2848
2849 void unlock1() UNLOCK_FUNCTION(mu1_);
2850 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2851 void unlocklots()
2852 UNLOCK_FUNCTION(mu1_)
2853 UNLOCK_FUNCTION(mu2_)
2854 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
2855 };
2856
2857
lock()2858 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
unlock()2859 void Foo::unlock() UNLOCK_FUNCTION() { }
2860
lock1()2861 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
2862 mu1_.Lock();
2863 }
2864
slock1()2865 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
2866 mu1_.ReaderLock();
2867 }
2868
lock3()2869 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
2870 mu1_.Lock();
2871 mu2_.Lock();
2872 mu3_.Lock();
2873 }
2874
locklots()2875 void Foo::locklots()
2876 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
2877 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
2878 mu1_.Lock();
2879 mu2_.Lock();
2880 mu3_.Lock();
2881 }
2882
unlock1()2883 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
2884 mu1_.Unlock();
2885 }
2886
unlock3()2887 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
2888 mu1_.Unlock();
2889 mu2_.Unlock();
2890 mu3_.Unlock();
2891 }
2892
unlocklots()2893 void Foo::unlocklots()
2894 UNLOCK_FUNCTION(mu1_, mu2_)
2895 UNLOCK_FUNCTION(mu2_, mu3_) {
2896 mu1_.Unlock();
2897 mu2_.Unlock();
2898 mu3_.Unlock();
2899 }
2900
2901
test0()2902 void test0() {
2903 Foo foo;
2904 foo.lock();
2905 foo.unlock();
2906
2907 foo.lock();
2908 foo.lock(); // expected-warning {{locking 'foo' that is already locked}}
2909 foo.unlock();
2910 foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}}
2911 }
2912
2913
test1()2914 void test1() {
2915 Foo foo;
2916 foo.lock1();
2917 foo.a = 0;
2918 foo.unlock1();
2919
2920 foo.lock1();
2921 foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
2922 foo.a = 0;
2923 foo.unlock1();
2924 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
2925 }
2926
2927
test2()2928 int test2() {
2929 Foo foo;
2930 foo.slock1();
2931 int d1 = foo.a;
2932 foo.unlock1();
2933
2934 foo.slock1();
2935 foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
2936 int d2 = foo.a;
2937 foo.unlock1();
2938 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
2939 return d1 + d2;
2940 }
2941
2942
test3()2943 void test3() {
2944 Foo foo;
2945 foo.lock3();
2946 foo.a = 0;
2947 foo.b = 0;
2948 foo.c = 0;
2949 foo.unlock3();
2950
2951 foo.lock3();
2952 foo.lock3(); // \
2953 // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2954 // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2955 // expected-warning {{locking 'foo.mu3_' that is already locked}}
2956 foo.a = 0;
2957 foo.b = 0;
2958 foo.c = 0;
2959 foo.unlock3();
2960 foo.unlock3(); // \
2961 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2962 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2963 // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
2964 }
2965
2966
testlots()2967 void testlots() {
2968 Foo foo;
2969 foo.locklots();
2970 foo.a = 0;
2971 foo.b = 0;
2972 foo.c = 0;
2973 foo.unlocklots();
2974
2975 foo.locklots();
2976 foo.locklots(); // \
2977 // expected-warning {{locking 'foo.mu1_' that is already locked}} \
2978 // expected-warning {{locking 'foo.mu2_' that is already locked}} \
2979 // expected-warning {{locking 'foo.mu3_' that is already locked}}
2980 foo.a = 0;
2981 foo.b = 0;
2982 foo.c = 0;
2983 foo.unlocklots();
2984 foo.unlocklots(); // \
2985 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
2986 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
2987 // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
2988 }
2989
2990 } // end namespace DuplicateAttributeTest
2991
2992
2993
2994 namespace TryLockEqTest {
2995
2996 class Foo {
2997 Mutex mu_;
2998 int a GUARDED_BY(mu_);
2999 bool c;
3000
3001 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3002 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3003 void unlock() UNLOCK_FUNCTION(mu_);
3004
3005 void test1();
3006 void test2();
3007 };
3008
3009
test1()3010 void Foo::test1() {
3011 if (tryLockMutexP() == 0) {
3012 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3013 return;
3014 }
3015 a = 0;
3016 unlock();
3017
3018 if (tryLockMutexP() != 0) {
3019 a = 0;
3020 unlock();
3021 }
3022
3023 if (0 != tryLockMutexP()) {
3024 a = 0;
3025 unlock();
3026 }
3027
3028 if (!(tryLockMutexP() == 0)) {
3029 a = 0;
3030 unlock();
3031 }
3032
3033 if (tryLockMutexI() == 0) {
3034 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3035 return;
3036 }
3037 a = 0;
3038 unlock();
3039
3040 if (0 == tryLockMutexI()) {
3041 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3042 return;
3043 }
3044 a = 0;
3045 unlock();
3046
3047 if (tryLockMutexI() == 1) {
3048 a = 0;
3049 unlock();
3050 }
3051
3052 if (mu_.TryLock() == false) {
3053 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3054 return;
3055 }
3056 a = 0;
3057 unlock();
3058
3059 if (mu_.TryLock() == true) {
3060 a = 0;
3061 unlock();
3062 }
3063 else {
3064 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3065 }
3066
3067 #if __has_feature(cxx_nullptr)
3068 if (tryLockMutexP() == nullptr) {
3069 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3070 return;
3071 }
3072 a = 0;
3073 unlock();
3074 #endif
3075 }
3076
3077
test2()3078 void Foo::test2() {
3079 /* FIXME: these tests depend on changes to the CFG.
3080 *
3081 if (mu_.TryLock() && c) {
3082 a = 0;
3083 unlock();
3084 }
3085 else return;
3086
3087 if (c && mu_.TryLock()) {
3088 a = 0;
3089 unlock();
3090 }
3091 else return;
3092
3093 if (!(mu_.TryLock() && c))
3094 return;
3095 a = 0;
3096 unlock();
3097
3098 if (!(c && mu_.TryLock()))
3099 return;
3100 a = 0;
3101 unlock();
3102
3103 if (!(mu_.TryLock() == 0) && c) {
3104 a = 0;
3105 unlock();
3106 }
3107
3108 if (!mu_.TryLock() || c)
3109 return;
3110 a = 0;
3111 unlock();
3112 */
3113 }
3114
3115 } // end namespace TryLockEqTest
3116
3117
3118 namespace ExistentialPatternMatching {
3119
3120 class Graph {
3121 public:
3122 Mutex mu_;
3123 };
3124
3125 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3126 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3127
3128 class Node {
3129 public:
3130 int a GUARDED_BY(&Graph::mu_);
3131
foo()3132 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3133 a = 0;
3134 }
3135 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3136 };
3137
test()3138 void test() {
3139 Graph g1;
3140 Graph g2;
3141 Node n1;
3142
3143 n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3144 n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
3145 n1.foo2();
3146
3147 g1.mu_.Lock();
3148 n1.a = 0;
3149 n1.foo();
3150 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3151 g1.mu_.Unlock();
3152
3153 g2.mu_.Lock();
3154 n1.a = 0;
3155 n1.foo();
3156 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3157 g2.mu_.Unlock();
3158
3159 LockAllGraphs();
3160 n1.a = 0;
3161 n1.foo();
3162 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
3163 UnlockAllGraphs();
3164
3165 LockAllGraphs();
3166 g1.mu_.Unlock();
3167
3168 LockAllGraphs();
3169 g2.mu_.Unlock();
3170
3171 LockAllGraphs();
3172 g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}}
3173 g1.mu_.Unlock();
3174 }
3175
3176 } // end namespace ExistentialPatternMatching
3177
3178
3179 namespace StringIgnoreTest {
3180
3181 class Foo {
3182 public:
3183 Mutex mu_;
3184 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3185 void unlock() UNLOCK_FUNCTION("");
3186 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3187 void roober() SHARED_LOCKS_REQUIRED("");
3188 };
3189
3190
3191 class Bar : public Foo {
3192 public:
bar(Foo * f)3193 void bar(Foo* f) {
3194 f->unlock();
3195 f->goober();
3196 f->roober();
3197 f->lock();
3198 };
3199 };
3200
3201 } // end namespace StringIgnoreTest
3202
3203
3204 namespace LockReturnedScopeFix {
3205
3206 class Base {
3207 protected:
3208 struct Inner;
3209 bool c;
3210
3211 const Mutex& getLock(const Inner* i);
3212
3213 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3214 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3215 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3216
3217 void bar(Inner* i);
3218 };
3219
3220
3221 struct Base::Inner {
3222 Mutex lock_;
3223 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3224 };
3225
3226
getLock(const Inner * i)3227 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3228 return i->lock_;
3229 }
3230
3231
foo(Inner * i)3232 void Base::foo(Inner* i) {
3233 i->doSomething();
3234 }
3235
bar(Inner * i)3236 void Base::bar(Inner* i) {
3237 if (c) {
3238 i->lock_.Lock();
3239 unlockInner(i);
3240 }
3241 else {
3242 lockInner(i);
3243 i->lock_.Unlock();
3244 }
3245 }
3246
3247 } // end namespace LockReturnedScopeFix
3248
3249
3250 namespace TrylockWithCleanups {
3251
3252 struct Foo {
3253 Mutex mu_;
3254 int a GUARDED_BY(mu_);
3255 };
3256
3257 Foo* GetAndLockFoo(const MyString& s)
3258 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3259
test()3260 static void test() {
3261 Foo* lt = GetAndLockFoo("foo");
3262 if (!lt) return;
3263 int a = lt->a;
3264 lt->mu_.Unlock();
3265 }
3266
3267 } // end namespace TrylockWithCleanups
3268
3269
3270 namespace UniversalLock {
3271
3272 class Foo {
3273 Mutex mu_;
3274 bool c;
3275
3276 int a GUARDED_BY(mu_);
3277 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3278 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3279
test1()3280 void test1() {
3281 int b;
3282
3283 beginNoWarnOnReads();
3284 b = a;
3285 r_foo();
3286 endNoWarnOnReads();
3287
3288 beginNoWarnOnWrites();
3289 a = 0;
3290 w_foo();
3291 endNoWarnOnWrites();
3292 }
3293
3294 // don't warn on joins with universal lock
test2()3295 void test2() {
3296 if (c) {
3297 beginNoWarnOnWrites();
3298 }
3299 a = 0; // \
3300 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
3301 endNoWarnOnWrites(); // \
3302 // expected-warning {{unlocking '*' that was not locked}}
3303 }
3304
3305
3306 // make sure the universal lock joins properly
test3()3307 void test3() {
3308 if (c) {
3309 mu_.Lock();
3310 beginNoWarnOnWrites();
3311 }
3312 else {
3313 beginNoWarnOnWrites();
3314 mu_.Lock();
3315 }
3316 a = 0;
3317 endNoWarnOnWrites();
3318 mu_.Unlock();
3319 }
3320
3321
3322 // combine universal lock with other locks
test4()3323 void test4() {
3324 beginNoWarnOnWrites();
3325 mu_.Lock();
3326 mu_.Unlock();
3327 endNoWarnOnWrites();
3328
3329 mu_.Lock();
3330 beginNoWarnOnWrites();
3331 endNoWarnOnWrites();
3332 mu_.Unlock();
3333
3334 mu_.Lock();
3335 beginNoWarnOnWrites();
3336 mu_.Unlock();
3337 endNoWarnOnWrites();
3338 }
3339 };
3340
3341 } // end namespace UniversalLock
3342
3343
3344 namespace TemplateLockReturned {
3345
3346 template<class T>
3347 class BaseT {
3348 public:
3349 virtual void baseMethod() = 0;
get_mutex()3350 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
3351
3352 Mutex mutex_;
3353 int a GUARDED_BY(mutex_);
3354 };
3355
3356
3357 class Derived : public BaseT<int> {
3358 public:
baseMethod()3359 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
3360 a = 0;
3361 }
3362 };
3363
3364 } // end namespace TemplateLockReturned
3365
3366
3367 namespace ExprMatchingBugFix {
3368
3369 class Foo {
3370 public:
3371 Mutex mu_;
3372 };
3373
3374
3375 class Bar {
3376 public:
3377 bool c;
3378 Foo* foo;
Bar(Foo * f)3379 Bar(Foo* f) : foo(f) { }
3380
3381 struct Nested {
3382 Foo* foo;
NestedExprMatchingBugFix::Bar::Nested3383 Nested(Foo* f) : foo(f) { }
3384
3385 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3386 };
3387
3388 void test();
3389 };
3390
3391
test()3392 void Bar::test() {
3393 foo->mu_.Lock();
3394 if (c) {
3395 Nested *n = new Nested(foo);
3396 n->unlockFoo();
3397 }
3398 else {
3399 foo->mu_.Unlock();
3400 }
3401 }
3402
3403 }; // end namespace ExprMatchingBugfix
3404
3405
3406 namespace ComplexNameTest {
3407
3408 class Foo {
3409 public:
3410 static Mutex mu_;
3411
EXCLUSIVE_LOCKS_REQUIRED(mu_)3412 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
EXCLUSIVE_LOCKS_REQUIRED(mu_)3413 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
3414
operator [](int i)3415 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
3416 };
3417
3418 class Bar {
3419 public:
3420 static Mutex mu_;
3421
LOCKS_EXCLUDED(mu_)3422 Bar() LOCKS_EXCLUDED(mu_) { }
LOCKS_EXCLUDED(mu_)3423 ~Bar() LOCKS_EXCLUDED(mu_) { }
3424
operator [](int i)3425 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
3426 };
3427
3428
test1()3429 void test1() {
3430 Foo f; // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
3431 int a = f[0]; // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
3432 } // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
3433
3434
test2()3435 void test2() {
3436 Bar::mu_.Lock();
3437 {
3438 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
3439 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
3440 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
3441 Bar::mu_.Unlock();
3442 }
3443
3444 }; // end namespace ComplexNameTest
3445
3446
3447 namespace UnreachableExitTest {
3448
3449 class FemmeFatale {
3450 public:
3451 FemmeFatale();
3452 ~FemmeFatale() __attribute__((noreturn));
3453 };
3454
3455 void exitNow() __attribute__((noreturn));
3456 void exitDestruct(const MyString& ms) __attribute__((noreturn));
3457
3458 Mutex fatalmu_;
3459
test1()3460 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3461 exitNow();
3462 }
3463
test2()3464 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3465 FemmeFatale femme;
3466 }
3467
3468 bool c;
3469
test3()3470 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3471 if (c) {
3472 exitNow();
3473 }
3474 else {
3475 FemmeFatale femme;
3476 }
3477 }
3478
test4()3479 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3480 exitDestruct("foo");
3481 }
3482
3483 } // end namespace UnreachableExitTest
3484
3485
3486 namespace VirtualMethodCanonicalizationTest {
3487
3488 class Base {
3489 public:
3490 virtual Mutex* getMutex() = 0;
3491 };
3492
3493 class Base2 : public Base {
3494 public:
3495 Mutex* getMutex();
3496 };
3497
3498 class Base3 : public Base2 {
3499 public:
3500 Mutex* getMutex();
3501 };
3502
3503 class Derived : public Base3 {
3504 public:
3505 Mutex* getMutex(); // overrides Base::getMutex()
3506 };
3507
baseFun(Base * b)3508 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3509
derivedFun(Derived * d)3510 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3511 baseFun(d);
3512 }
3513
3514 } // end namespace VirtualMethodCanonicalizationTest
3515
3516
3517 namespace TemplateFunctionParamRemapTest {
3518
3519 template <class T>
3520 struct Cell {
3521 T dummy_;
3522 Mutex* mu_;
3523 };
3524
3525 class Foo {
3526 public:
3527 template <class T>
3528 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3529
3530 void test();
3531 };
3532
3533 template<class T>
elr(Cell<T> * c1)3534 void Foo::elr(Cell<T>* c1) { }
3535
test()3536 void Foo::test() {
3537 Cell<int> cell;
3538 elr(&cell); // \
3539 // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3540 }
3541
3542
3543 template<class T>
3544 void globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3545
3546 template<class T>
globalELR(Cell<T> * c1)3547 void globalELR(Cell<T>* c1) { }
3548
globalTest()3549 void globalTest() {
3550 Cell<int> cell;
3551 globalELR(&cell); // \
3552 // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
3553 }
3554
3555
3556 template<class T>
3557 void globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3558
3559 // second declaration
3560 template<class T>
3561 void globalELR2(Cell<T>* c2);
3562
3563 template<class T>
globalELR2(Cell<T> * c3)3564 void globalELR2(Cell<T>* c3) { }
3565
3566 // re-declaration after definition
3567 template<class T>
3568 void globalELR2(Cell<T>* c4);
3569
globalTest2()3570 void globalTest2() {
3571 Cell<int> cell;
3572 globalELR2(&cell); // \
3573 // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
3574 }
3575
3576
3577 template<class T>
3578 class FooT {
3579 public:
3580 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_)));
3581 };
3582
3583 template<class T>
elr(Cell<T> * c1)3584 void FooT<T>::elr(Cell<T>* c1) { }
3585
testFooT()3586 void testFooT() {
3587 Cell<int> cell;
3588 FooT<int> foo;
3589 foo.elr(&cell); // \
3590 // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
3591 }
3592
3593 } // end namespace TemplateFunctionParamRemapTest
3594
3595
3596 namespace SelfConstructorTest {
3597
3598 class SelfLock {
3599 public:
3600 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3601 ~SelfLock() UNLOCK_FUNCTION(mu_);
3602
3603 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3604
3605 Mutex mu_;
3606 };
3607
3608 class LOCKABLE SelfLock2 {
3609 public:
3610 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
3611 ~SelfLock2() UNLOCK_FUNCTION();
3612
3613 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3614 };
3615
3616
test()3617 void test() {
3618 SelfLock s;
3619 s.foo();
3620 }
3621
test2()3622 void test2() {
3623 SelfLock2 s2;
3624 s2.foo();
3625 }
3626
3627 } // end namespace SelfConstructorTest
3628
3629
3630 namespace MultipleAttributeTest {
3631
3632 class Foo {
3633 Mutex mu1_;
3634 Mutex mu2_;
3635 int a GUARDED_BY(mu1_);
3636 int b GUARDED_BY(mu2_);
3637 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_);
3638 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
3639
3640 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_)
3641 EXCLUSIVE_LOCKS_REQUIRED(mu2_);
3642 void foo2() SHARED_LOCKS_REQUIRED(mu1_)
3643 SHARED_LOCKS_REQUIRED(mu2_);
3644 void foo3() LOCKS_EXCLUDED(mu1_)
3645 LOCKS_EXCLUDED(mu2_);
3646 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
3647 EXCLUSIVE_LOCK_FUNCTION(mu2_);
3648 void readerlock() SHARED_LOCK_FUNCTION(mu1_)
3649 SHARED_LOCK_FUNCTION(mu2_);
3650 void unlock() UNLOCK_FUNCTION(mu1_)
3651 UNLOCK_FUNCTION(mu2_);
3652 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
3653 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
3654 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
3655 SHARED_TRYLOCK_FUNCTION(true, mu2_);
3656
3657 void test();
3658 };
3659
3660
foo1()3661 void Foo::foo1() {
3662 a = 1;
3663 b = 2;
3664 }
3665
foo2()3666 void Foo::foo2() {
3667 int result = a + b;
3668 }
3669
foo3()3670 void Foo::foo3() { }
lock()3671 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
readerlock()3672 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
unlock()3673 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
trylock()3674 bool Foo::trylock() { return true; }
readertrylock()3675 bool Foo::readertrylock() { return true; }
3676
3677
test()3678 void Foo::test() {
3679 mu1_.Lock();
3680 foo1(); // expected-warning {{}}
3681 c = 0; // expected-warning {{}}
3682 *d = 0; // expected-warning {{}}
3683 mu1_.Unlock();
3684
3685 mu1_.ReaderLock();
3686 foo2(); // expected-warning {{}}
3687 int x = c; // expected-warning {{}}
3688 int y = *d; // expected-warning {{}}
3689 mu1_.Unlock();
3690
3691 mu2_.Lock();
3692 foo3(); // expected-warning {{}}
3693 mu2_.Unlock();
3694
3695 lock();
3696 a = 0;
3697 b = 0;
3698 unlock();
3699
3700 readerlock();
3701 int z = a + b;
3702 unlock();
3703
3704 if (trylock()) {
3705 a = 0;
3706 b = 0;
3707 unlock();
3708 }
3709
3710 if (readertrylock()) {
3711 int zz = a + b;
3712 unlock();
3713 }
3714 }
3715
3716
3717 } // end namespace MultipleAttributeTest
3718
3719
3720 namespace GuardedNonPrimitiveTypeTest {
3721
3722
3723 class Data {
3724 public:
Data(int i)3725 Data(int i) : dat(i) { }
3726
getValue() const3727 int getValue() const { return dat; }
setValue(int i)3728 void setValue(int i) { dat = i; }
3729
operator [](int i) const3730 int operator[](int i) const { return dat; }
operator [](int i)3731 int& operator[](int i) { return dat; }
3732
operator ()()3733 void operator()() { }
3734
3735 private:
3736 int dat;
3737 };
3738
3739
3740 class DataCell {
3741 public:
DataCell(const Data & d)3742 DataCell(const Data& d) : dat(d) { }
3743
3744 private:
3745 Data dat;
3746 };
3747
3748
3749 void showDataCell(const DataCell& dc);
3750
3751
3752 class Foo {
3753 public:
3754 // method call tests
test()3755 void test() {
3756 data_.setValue(0); // FIXME -- should be writing \
3757 // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3758 int a = data_.getValue(); // \
3759 // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3760
3761 datap1_->setValue(0); // FIXME -- should be writing \
3762 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
3763 a = datap1_->getValue(); // \
3764 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
3765
3766 datap2_->setValue(0); // FIXME -- should be writing \
3767 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3768 a = datap2_->getValue(); // \
3769 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3770
3771 (*datap2_).setValue(0); // FIXME -- should be writing \
3772 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3773 a = (*datap2_).getValue(); // \
3774 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3775
3776 mu_.Lock();
3777 data_.setValue(1);
3778 datap1_->setValue(1);
3779 datap2_->setValue(1);
3780 mu_.Unlock();
3781
3782 mu_.ReaderLock();
3783 a = data_.getValue();
3784 datap1_->setValue(0); // reads datap1_, writes *datap1_
3785 a = datap1_->getValue();
3786 a = datap2_->getValue();
3787 mu_.Unlock();
3788 }
3789
3790 // operator tests
test2()3791 void test2() {
3792 data_ = Data(1); // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
3793 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
3794 // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3795 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
3796 // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3797 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
3798 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
3799 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
3800 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3801
3802 data_[0] = 0; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3803 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3804
3805 data_(); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3806 }
3807
3808 // const operator tests
test3() const3809 void test3() const {
3810 Data mydat(data_); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3811
3812 //FIXME
3813 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
3814 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
3815
3816 int a = data_[0]; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
3817 }
3818
3819 private:
3820 Mutex mu_;
3821 Data data_ GUARDED_BY(mu_);
3822 Data* datap1_ GUARDED_BY(mu_);
3823 Data* datap2_ PT_GUARDED_BY(mu_);
3824 };
3825
3826 } // end namespace GuardedNonPrimitiveTypeTest
3827
3828
3829 namespace GuardedNonPrimitive_MemberAccess {
3830
3831 class Cell {
3832 public:
3833 Cell(int i);
3834
3835 void cellMethod();
3836
3837 int a;
3838 };
3839
3840
3841 class Foo {
3842 public:
3843 int a;
3844 Cell c GUARDED_BY(cell_mu_);
3845 Cell* cp PT_GUARDED_BY(cell_mu_);
3846
3847 void myMethod();
3848
3849 Mutex cell_mu_;
3850 };
3851
3852
3853 class Bar {
3854 private:
3855 Mutex mu_;
3856 Foo foo GUARDED_BY(mu_);
3857 Foo* foop PT_GUARDED_BY(mu_);
3858
test()3859 void test() {
3860 foo.myMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
3861
3862 int fa = foo.a; // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
3863 foo.a = fa; // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
3864
3865 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
3866 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
3867
3868 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
3869 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
3870
3871 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
3872 // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
3873 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
3874 // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
3875
3876 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
3877 // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
3878 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
3879 // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
3880
3881 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
3882 // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
3883 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
3884 // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
3885 };
3886 };
3887
3888 } // namespace GuardedNonPrimitive_MemberAccess
3889
3890
3891 namespace TestThrowExpr {
3892
3893 class Foo {
3894 Mutex mu_;
3895
3896 bool hasError();
3897
test()3898 void test() {
3899 mu_.Lock();
3900 if (hasError()) {
3901 throw "ugly";
3902 }
3903 mu_.Unlock();
3904 }
3905 };
3906
3907 } // end namespace TestThrowExpr
3908
3909
3910 namespace UnevaluatedContextTest {
3911
3912 // parse attribute expressions in an unevaluated context.
3913
3914 static inline Mutex* getMutex1();
3915 static inline Mutex* getMutex2();
3916
3917 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
3918
3919 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
3920
3921 } // end namespace UnevaluatedContextTest
3922
3923
3924 namespace LockUnlockFunctionTest {
3925
3926 // Check built-in lock functions
3927 class LOCKABLE MyLockable {
3928 public:
lock()3929 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
readerLock()3930 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
unlock()3931 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
3932
3933 private:
3934 Mutex mu_;
3935 };
3936
3937
3938 class Foo {
3939 public:
3940 // Correct lock/unlock functions
lock()3941 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
3942 mu_.Lock();
3943 }
3944
readerLock()3945 void readerLock() SHARED_LOCK_FUNCTION(mu_) {
3946 mu_.ReaderLock();
3947 }
3948
unlock()3949 void unlock() UNLOCK_FUNCTION(mu_) {
3950 mu_.Unlock();
3951 }
3952
3953 // Check failure to lock.
lockBad()3954 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3955 mu2_.Lock();
3956 mu2_.Unlock();
3957 } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
3958
readerLockBad()3959 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3960 mu2_.Lock();
3961 mu2_.Unlock();
3962 } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
3963
unlockBad()3964 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3965 mu2_.Lock();
3966 mu2_.Unlock();
3967 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
3968
3969 // Check locking the wrong thing.
lockBad2()3970 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3971 mu2_.Lock(); // expected-note {{mutex acquired here}}
3972 } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
3973 // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
3974
3975
readerLockBad2()3976 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3977 mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
3978 } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
3979 // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
3980
3981
unlockBad2()3982 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
3983 mu2_.Unlock(); // expected-warning {{unlocking 'mu2_' that was not locked}}
3984 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
3985
3986 private:
3987 Mutex mu_;
3988 Mutex mu2_;
3989 };
3990
3991 } // end namespace LockUnlockFunctionTest
3992
3993
3994 namespace AssertHeldTest {
3995
3996 class Foo {
3997 public:
3998 int c;
3999 int a GUARDED_BY(mu_);
4000 Mutex mu_;
4001
test1()4002 void test1() {
4003 mu_.AssertHeld();
4004 int b = a;
4005 a = 0;
4006 }
4007
test2()4008 void test2() {
4009 mu_.AssertReaderHeld();
4010 int b = a;
4011 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
4012 }
4013
test3()4014 void test3() {
4015 if (c) {
4016 mu_.AssertHeld();
4017 }
4018 else {
4019 mu_.AssertHeld();
4020 }
4021 int b = a;
4022 a = 0;
4023 }
4024
test4()4025 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4026 mu_.AssertHeld();
4027 int b = a;
4028 a = 0;
4029 }
4030
test5()4031 void test5() UNLOCK_FUNCTION(mu_) {
4032 mu_.AssertHeld();
4033 mu_.Unlock();
4034 }
4035
test6()4036 void test6() {
4037 mu_.AssertHeld();
4038 mu_.Unlock();
4039 } // should this be a warning?
4040
test7()4041 void test7() {
4042 if (c) {
4043 mu_.AssertHeld();
4044 }
4045 else {
4046 mu_.Lock();
4047 }
4048 int b = a;
4049 a = 0;
4050 mu_.Unlock();
4051 }
4052
test8()4053 void test8() {
4054 if (c) {
4055 mu_.Lock();
4056 }
4057 else {
4058 mu_.AssertHeld();
4059 }
4060 int b = a;
4061 a = 0;
4062 mu_.Unlock();
4063 }
4064
test9()4065 void test9() {
4066 if (c) {
4067 mu_.AssertHeld();
4068 }
4069 else {
4070 mu_.Lock(); // expected-note {{mutex acquired here}}
4071 }
4072 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
4073
test10()4074 void test10() {
4075 if (c) {
4076 mu_.Lock(); // expected-note {{mutex acquired here}}
4077 }
4078 else {
4079 mu_.AssertHeld();
4080 }
4081 } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
4082
4083 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
4084
test11()4085 void test11() {
4086 assertMu();
4087 int b = a;
4088 a = 0;
4089 }
4090 };
4091
4092 } // end namespace AssertHeldTest
4093
4094
4095