1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
5
6 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
7 // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
8
9 #include "thread-safety-annotations.h"
10
11 class LOCKABLE Mutex {
12 public:
13 void Lock() EXCLUSIVE_LOCK_FUNCTION();
14 void ReaderLock() SHARED_LOCK_FUNCTION();
15 void Unlock() UNLOCK_FUNCTION();
16 void ExclusiveUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
17 void ReaderUnlock() SHARED_UNLOCK_FUNCTION();
18 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
19 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
20 void LockWhen(const int &cond) EXCLUSIVE_LOCK_FUNCTION();
21
22 void PromoteShared() SHARED_UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();
23 void DemoteExclusive() EXCLUSIVE_UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();
24
25 // for negative capabilities
operator !() const26 const Mutex& operator!() const { return *this; }
27
28 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
29 void AssertReaderHeld() ASSERT_SHARED_LOCK();
30 };
31
32 class SCOPED_LOCKABLE MutexLock {
33 public:
34 MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
35 MutexLock(Mutex *mu, bool adopt) EXCLUSIVE_LOCKS_REQUIRED(mu);
36 ~MutexLock() UNLOCK_FUNCTION();
37 };
38
39 class SCOPED_LOCKABLE ReaderMutexLock {
40 public:
41 ReaderMutexLock(Mutex *mu) SHARED_LOCK_FUNCTION(mu);
42 ReaderMutexLock(Mutex *mu, bool adopt) SHARED_LOCKS_REQUIRED(mu);
43 ~ReaderMutexLock() UNLOCK_FUNCTION();
44 };
45
46 class SCOPED_LOCKABLE ReleasableMutexLock {
47 public:
48 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
49 ~ReleasableMutexLock() UNLOCK_FUNCTION();
50
51 void Release() UNLOCK_FUNCTION();
52 };
53
54 class SCOPED_LOCKABLE DoubleMutexLock {
55 public:
56 DoubleMutexLock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);
57 ~DoubleMutexLock() UNLOCK_FUNCTION();
58 };
59
60 // The universal lock, written "*", allows checking to be selectively turned
61 // off for a particular piece of code.
62 void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
63 void endNoWarnOnReads() UNLOCK_FUNCTION("*");
64 void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
65 void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
66
67
68 // For testing handling of smart pointers.
69 template<class T>
70 class SmartPtr {
71 public:
SmartPtr(T * p)72 SmartPtr(T* p) : ptr_(p) { }
SmartPtr(const SmartPtr<T> & p)73 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { }
74 ~SmartPtr();
75
get() const76 T* get() const { return ptr_; }
operator ->() const77 T* operator->() const { return ptr_; }
operator *() const78 T& operator*() const { return *ptr_; }
operator [](int i) const79 T& operator[](int i) const { return ptr_[i]; }
80
81 private:
82 T* ptr_;
83 };
84
85
86 // For testing destructor calls and cleanup.
87 class MyString {
88 public:
89 MyString(const char* s);
90 ~MyString();
91 };
92
93
94 // For testing operator overloading
95 template <class K, class T>
96 class MyMap {
97 public:
98 T& operator[](const K& k);
99 };
100
101
102 // For testing handling of containers.
103 template <class T>
104 class MyContainer {
105 public:
106 MyContainer();
107
108 typedef T* iterator;
109 typedef const T* const_iterator;
110
111 T* begin();
112 T* end();
113
114 const T* cbegin();
115 const T* cend();
116
117 T& operator[](int i);
118 const T& operator[](int i) const;
119
120 private:
121 T* ptr_;
122 };
123
124
125
126 Mutex sls_mu;
127
128 Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
129 int sls_guard_var __attribute__((guarded_var)) = 0;
130 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
131
132 bool getBool();
133
134 class MutexWrapper {
135 public:
136 Mutex mu;
137 int x __attribute__((guarded_by(mu)));
138 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
139 };
140
141 MutexWrapper sls_mw;
142
sls_fun_0()143 void sls_fun_0() {
144 sls_mw.mu.Lock();
145 sls_mw.x = 5;
146 sls_mw.mu.Unlock();
147 }
148
sls_fun_2()149 void sls_fun_2() {
150 sls_mu.Lock();
151 int x = sls_guard_var;
152 sls_mu.Unlock();
153 }
154
sls_fun_3()155 void sls_fun_3() {
156 sls_mu.Lock();
157 sls_guard_var = 2;
158 sls_mu.Unlock();
159 }
160
sls_fun_4()161 void sls_fun_4() {
162 sls_mu2.Lock();
163 sls_guard_var = 2;
164 sls_mu2.Unlock();
165 }
166
sls_fun_5()167 void sls_fun_5() {
168 sls_mu.Lock();
169 int x = sls_guardby_var;
170 sls_mu.Unlock();
171 }
172
sls_fun_6()173 void sls_fun_6() {
174 sls_mu.Lock();
175 sls_guardby_var = 2;
176 sls_mu.Unlock();
177 }
178
sls_fun_7()179 void sls_fun_7() {
180 sls_mu.Lock();
181 sls_mu2.Lock();
182 sls_mu2.Unlock();
183 sls_mu.Unlock();
184 }
185
sls_fun_8()186 void sls_fun_8() {
187 sls_mu.Lock();
188 if (getBool())
189 sls_mu.Unlock();
190 else
191 sls_mu.Unlock();
192 }
193
sls_fun_9()194 void sls_fun_9() {
195 if (getBool())
196 sls_mu.Lock();
197 else
198 sls_mu.Lock();
199 sls_mu.Unlock();
200 }
201
sls_fun_good_6()202 void sls_fun_good_6() {
203 if (getBool()) {
204 sls_mu.Lock();
205 } else {
206 if (getBool()) {
207 getBool(); // EMPTY
208 } else {
209 getBool(); // EMPTY
210 }
211 sls_mu.Lock();
212 }
213 sls_mu.Unlock();
214 }
215
sls_fun_good_7()216 void sls_fun_good_7() {
217 sls_mu.Lock();
218 while (getBool()) {
219 sls_mu.Unlock();
220 if (getBool()) {
221 if (getBool()) {
222 sls_mu.Lock();
223 continue;
224 }
225 }
226 sls_mu.Lock();
227 }
228 sls_mu.Unlock();
229 }
230
sls_fun_good_8()231 void sls_fun_good_8() {
232 sls_mw.MyLock();
233 sls_mw.mu.Unlock();
234 }
235
sls_fun_bad_1()236 void sls_fun_bad_1() {
237 sls_mu.Unlock(); // \
238 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
239 }
240
sls_fun_bad_2()241 void sls_fun_bad_2() {
242 sls_mu.Lock(); // expected-note{{mutex acquired here}}
243 sls_mu.Lock(); // \
244 // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
245 sls_mu.Unlock();
246 }
247
sls_fun_bad_3()248 void sls_fun_bad_3() {
249 sls_mu.Lock(); // expected-note {{mutex acquired here}}
250 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
251
sls_fun_bad_4()252 void sls_fun_bad_4() {
253 if (getBool())
254 sls_mu.Lock(); // expected-note{{mutex acquired here}}
255 else
256 sls_mu2.Lock(); // expected-note{{mutex acquired here}}
257 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
258 // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
259
sls_fun_bad_5()260 void sls_fun_bad_5() {
261 sls_mu.Lock(); // expected-note {{mutex acquired here}}
262 if (getBool())
263 sls_mu.Unlock();
264 } // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
265
sls_fun_bad_6()266 void sls_fun_bad_6() {
267 if (getBool()) {
268 sls_mu.Lock(); // expected-note {{mutex acquired here}}
269 } else {
270 if (getBool()) {
271 getBool(); // EMPTY
272 } else {
273 getBool(); // EMPTY
274 }
275 }
276 sls_mu.Unlock(); // \
277 expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
278 expected-warning{{releasing mutex 'sls_mu' that was not held}}
279 }
280
sls_fun_bad_7()281 void sls_fun_bad_7() {
282 sls_mu.Lock();
283 while (getBool()) {
284 sls_mu.Unlock();
285 if (getBool()) {
286 if (getBool()) {
287 continue; // \
288 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
289 }
290 }
291 sls_mu.Lock(); // expected-note {{mutex acquired here}}
292 }
293 sls_mu.Unlock();
294 }
295
sls_fun_bad_8()296 void sls_fun_bad_8() {
297 sls_mu.Lock(); // expected-note{{mutex acquired here}}
298
299 do {
300 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
301 } while (getBool());
302 }
303
sls_fun_bad_9()304 void sls_fun_bad_9() {
305 do {
306 sls_mu.Lock(); // \
307 // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
308 // expected-note{{mutex acquired here}}
309 } while (getBool());
310 sls_mu.Unlock();
311 }
312
sls_fun_bad_10()313 void sls_fun_bad_10() {
314 sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
315 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
316 sls_mu.Unlock();
317 }
318 } // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
319
sls_fun_bad_11()320 void sls_fun_bad_11() {
321 while (getBool()) { // \
322 expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
323 sls_mu.Lock(); // expected-note {{mutex acquired here}}
324 }
325 sls_mu.Unlock(); // \
326 // expected-warning{{releasing mutex 'sls_mu' that was not held}}
327 }
328
sls_fun_bad_12()329 void sls_fun_bad_12() {
330 sls_mu.Lock(); // expected-note {{mutex acquired here}}
331 while (getBool()) {
332 sls_mu.Unlock();
333 if (getBool()) {
334 if (getBool()) {
335 break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
336 }
337 }
338 sls_mu.Lock();
339 }
340 sls_mu.Unlock();
341 }
342
343 //-----------------------------------------//
344 // Handling lock expressions in attribute args
345 // -------------------------------------------//
346
347 Mutex aa_mu;
348
349 class GlobalLocker {
350 public:
351 void globalLock() EXCLUSIVE_LOCK_FUNCTION(aa_mu);
352 void globalUnlock() UNLOCK_FUNCTION(aa_mu);
353 };
354
355 GlobalLocker glock;
356
aa_fun_1()357 void aa_fun_1() {
358 glock.globalLock();
359 glock.globalUnlock();
360 }
361
aa_fun_bad_1()362 void aa_fun_bad_1() {
363 glock.globalUnlock(); // \
364 // expected-warning{{releasing mutex 'aa_mu' that was not held}}
365 }
366
aa_fun_bad_2()367 void aa_fun_bad_2() {
368 glock.globalLock(); // expected-note{{mutex acquired here}}
369 glock.globalLock(); // \
370 // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
371 glock.globalUnlock();
372 }
373
aa_fun_bad_3()374 void aa_fun_bad_3() {
375 glock.globalLock(); // expected-note{{mutex acquired here}}
376 } // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
377
378 //--------------------------------------------------//
379 // Regression tests for unusual method names
380 //--------------------------------------------------//
381
382 Mutex wmu;
383
384 // Test diagnostics for other method names.
385 class WeirdMethods {
386 // FIXME: can't currently check inside constructors and destructors.
WeirdMethods()387 WeirdMethods() {
388 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
389 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
~WeirdMethods()390 ~WeirdMethods() {
391 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
392 } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
operator ++()393 void operator++() {
394 wmu.Lock(); // expected-note {{mutex acquired here}}
395 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
operator int*()396 operator int*() {
397 wmu.Lock(); // expected-note {{mutex acquired here}}
398 return 0;
399 } // expected-warning {{mutex 'wmu' is still held at the end of function}}
400 };
401
402 //-----------------------------------------------//
403 // Errors for guarded by or guarded var variables
404 // ----------------------------------------------//
405
406 int *pgb_gvar __attribute__((pt_guarded_var));
407 int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
408
409 class PGBFoo {
410 public:
411 int x;
412 int *pgb_field __attribute__((guarded_by(sls_mu2)))
413 __attribute__((pt_guarded_by(sls_mu)));
testFoo()414 void testFoo() {
415 pgb_field = &x; // \
416 // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
417 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
418 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
419 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
420 // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
421 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
422 // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
423 }
424 };
425
426 class GBFoo {
427 public:
428 int gb_field __attribute__((guarded_by(sls_mu)));
429
testFoo()430 void testFoo() {
431 gb_field = 0; // \
432 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
433 }
434
testNoAnal()435 void testNoAnal() NO_THREAD_SAFETY_ANALYSIS {
436 gb_field = 0;
437 }
438 };
439
440 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
441
gb_fun_0()442 void gb_fun_0() {
443 sls_mu.Lock();
444 int x = *pgb_var;
445 sls_mu.Unlock();
446 }
447
gb_fun_1()448 void gb_fun_1() {
449 sls_mu.Lock();
450 *pgb_var = 2;
451 sls_mu.Unlock();
452 }
453
gb_fun_2()454 void gb_fun_2() {
455 int x;
456 pgb_var = &x;
457 }
458
gb_fun_3()459 void gb_fun_3() {
460 int *x = pgb_var;
461 }
462
gb_bad_0()463 void gb_bad_0() {
464 sls_guard_var = 1; // \
465 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
466 }
467
gb_bad_1()468 void gb_bad_1() {
469 int x = sls_guard_var; // \
470 // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
471 }
472
gb_bad_2()473 void gb_bad_2() {
474 sls_guardby_var = 1; // \
475 // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
476 }
477
gb_bad_3()478 void gb_bad_3() {
479 int x = sls_guardby_var; // \
480 // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
481 }
482
gb_bad_4()483 void gb_bad_4() {
484 *pgb_gvar = 1; // \
485 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
486 }
487
gb_bad_5()488 void gb_bad_5() {
489 int x = *pgb_gvar; // \
490 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
491 }
492
gb_bad_6()493 void gb_bad_6() {
494 *pgb_var = 1; // \
495 // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
496 }
497
gb_bad_7()498 void gb_bad_7() {
499 int x = *pgb_var; // \
500 // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
501 }
502
gb_bad_8()503 void gb_bad_8() {
504 GBFoo G;
505 G.gb_field = 0; // \
506 // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
507 }
508
gb_bad_9()509 void gb_bad_9() {
510 sls_guard_var++; // \
511 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
512 sls_guard_var--; // \
513 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
514 ++sls_guard_var; // \
515 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
516 --sls_guard_var;// \
517 // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
518 }
519
520 //-----------------------------------------------//
521 // Warnings on variables with late parsed attributes
522 // ----------------------------------------------//
523
524 class LateFoo {
525 public:
526 int a __attribute__((guarded_by(mu)));
527 int b;
528
foo()529 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu) { }
530
test()531 void test() {
532 a = 0; // \
533 // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
534 b = a; // \
535 // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
536 c = 0; // \
537 // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
538 }
539
540 int c __attribute__((guarded_by(mu)));
541
542 Mutex mu;
543 };
544
545 class LateBar {
546 public:
547 int a_ __attribute__((guarded_by(mu1_)));
548 int b_;
549 int *q __attribute__((pt_guarded_by(mu)));
550 Mutex mu1_;
551 Mutex mu;
552 LateFoo Foo;
553 LateFoo Foo2;
554 LateFoo *FooPointer;
555 };
556
557 LateBar b1, *b3;
558
late_0()559 void late_0() {
560 LateFoo FooA;
561 LateFoo FooB;
562 FooA.mu.Lock();
563 FooA.a = 5;
564 FooA.mu.Unlock();
565 }
566
late_1()567 void late_1() {
568 LateBar BarA;
569 BarA.FooPointer->mu.Lock();
570 BarA.FooPointer->a = 2;
571 BarA.FooPointer->mu.Unlock();
572 }
573
late_bad_0()574 void late_bad_0() {
575 LateFoo fooA;
576 LateFoo fooB;
577 fooA.mu.Lock();
578 fooB.a = 5; // \
579 // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
580 // expected-note{{found near match 'fooA.mu'}}
581 fooA.mu.Unlock();
582 }
583
late_bad_1()584 void late_bad_1() {
585 Mutex mu;
586 mu.Lock();
587 b1.mu1_.Lock();
588 int res = b1.a_ + b3->b_;
589 b3->b_ = *b1.q; // \
590 // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
591 b1.mu1_.Unlock();
592 b1.b_ = res;
593 mu.Unlock();
594 }
595
late_bad_2()596 void late_bad_2() {
597 LateBar BarA;
598 BarA.FooPointer->mu.Lock();
599 BarA.Foo.a = 2; // \
600 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
601 // expected-note{{found near match 'BarA.FooPointer->mu'}}
602 BarA.FooPointer->mu.Unlock();
603 }
604
late_bad_3()605 void late_bad_3() {
606 LateBar BarA;
607 BarA.Foo.mu.Lock();
608 BarA.FooPointer->a = 2; // \
609 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
610 // expected-note{{found near match 'BarA.Foo.mu'}}
611 BarA.Foo.mu.Unlock();
612 }
613
late_bad_4()614 void late_bad_4() {
615 LateBar BarA;
616 BarA.Foo.mu.Lock();
617 BarA.Foo2.a = 2; // \
618 // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
619 // expected-note{{found near match 'BarA.Foo.mu'}}
620 BarA.Foo.mu.Unlock();
621 }
622
623 //-----------------------------------------------//
624 // Extra warnings for shared vs. exclusive locks
625 // ----------------------------------------------//
626
shared_fun_0()627 void shared_fun_0() {
628 sls_mu.Lock();
629 do {
630 sls_mu.Unlock();
631 sls_mu.Lock();
632 } while (getBool());
633 sls_mu.Unlock();
634 }
635
shared_fun_1()636 void shared_fun_1() {
637 sls_mu.ReaderLock(); // \
638 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
639 do {
640 sls_mu.Unlock();
641 sls_mu.Lock(); // \
642 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
643 } while (getBool());
644 sls_mu.Unlock();
645 }
646
shared_fun_3()647 void shared_fun_3() {
648 if (getBool())
649 sls_mu.Lock();
650 else
651 sls_mu.Lock();
652 *pgb_var = 1;
653 sls_mu.Unlock();
654 }
655
shared_fun_4()656 void shared_fun_4() {
657 if (getBool())
658 sls_mu.ReaderLock();
659 else
660 sls_mu.ReaderLock();
661 int x = sls_guardby_var;
662 sls_mu.Unlock();
663 }
664
shared_fun_8()665 void shared_fun_8() {
666 if (getBool())
667 sls_mu.Lock(); // \
668 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
669 else
670 sls_mu.ReaderLock(); // \
671 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
672 sls_mu.Unlock();
673 }
674
shared_fun_9()675 void shared_fun_9() {
676 sls_mu.Lock();
677 sls_mu.ExclusiveUnlock();
678
679 sls_mu.ReaderLock();
680 sls_mu.ReaderUnlock();
681 }
682
shared_fun_10()683 void shared_fun_10() {
684 sls_mu.Lock();
685 sls_mu.DemoteExclusive();
686 sls_mu.ReaderUnlock();
687 }
688
shared_fun_11()689 void shared_fun_11() {
690 sls_mu.ReaderLock();
691 sls_mu.PromoteShared();
692 sls_mu.Unlock();
693 }
694
shared_bad_0()695 void shared_bad_0() {
696 sls_mu.Lock(); // \
697 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
698 do {
699 sls_mu.Unlock();
700 sls_mu.ReaderLock(); // \
701 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
702 } while (getBool());
703 sls_mu.Unlock();
704 }
705
shared_bad_1()706 void shared_bad_1() {
707 if (getBool())
708 sls_mu.Lock(); // \
709 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
710 else
711 sls_mu.ReaderLock(); // \
712 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
713 *pgb_var = 1;
714 sls_mu.Unlock();
715 }
716
shared_bad_2()717 void shared_bad_2() {
718 if (getBool())
719 sls_mu.ReaderLock(); // \
720 // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
721 else
722 sls_mu.Lock(); // \
723 // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
724 *pgb_var = 1;
725 sls_mu.Unlock();
726 }
727
shared_bad_3()728 void shared_bad_3() {
729 sls_mu.Lock(); // expected-note {{mutex acquired here}}
730 sls_mu.ReaderUnlock(); // \
731 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
732 }
733
shared_bad_4()734 void shared_bad_4() {
735 sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
736 sls_mu.ExclusiveUnlock(); // \
737 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
738 }
739
shared_bad_5()740 void shared_bad_5() {
741 sls_mu.Lock(); // expected-note {{mutex acquired here}}
742 sls_mu.PromoteShared(); // \
743 // expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
744 sls_mu.ExclusiveUnlock();
745 }
746
shared_bad_6()747 void shared_bad_6() {
748 sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
749 sls_mu.DemoteExclusive(); // \
750 // expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
751 sls_mu.ReaderUnlock();
752 }
753
754 // FIXME: Add support for functions (not only methods)
755 class LRBar {
756 public:
757 void aa_elr_fun() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);
758 void aa_elr_fun_s() SHARED_LOCKS_REQUIRED(aa_mu);
759 void le_fun() __attribute__((locks_excluded(sls_mu)));
760 };
761
762 class LRFoo {
763 public:
764 void test() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);
765 void testShared() SHARED_LOCKS_REQUIRED(sls_mu2);
766 };
767
768 void elr_fun() EXCLUSIVE_LOCKS_REQUIRED(sls_mu);
elr_fun()769 void elr_fun() {}
770
771 LRFoo MyLRFoo;
772 LRBar Bar;
773
es_fun_0()774 void es_fun_0() {
775 aa_mu.Lock();
776 Bar.aa_elr_fun();
777 aa_mu.Unlock();
778 }
779
es_fun_1()780 void es_fun_1() {
781 aa_mu.Lock();
782 Bar.aa_elr_fun_s();
783 aa_mu.Unlock();
784 }
785
es_fun_2()786 void es_fun_2() {
787 aa_mu.ReaderLock();
788 Bar.aa_elr_fun_s();
789 aa_mu.Unlock();
790 }
791
es_fun_3()792 void es_fun_3() {
793 sls_mu.Lock();
794 MyLRFoo.test();
795 sls_mu.Unlock();
796 }
797
es_fun_4()798 void es_fun_4() {
799 sls_mu2.Lock();
800 MyLRFoo.testShared();
801 sls_mu2.Unlock();
802 }
803
es_fun_5()804 void es_fun_5() {
805 sls_mu2.ReaderLock();
806 MyLRFoo.testShared();
807 sls_mu2.Unlock();
808 }
809
es_fun_6()810 void es_fun_6() {
811 Bar.le_fun();
812 }
813
es_fun_7()814 void es_fun_7() {
815 sls_mu.Lock();
816 elr_fun();
817 sls_mu.Unlock();
818 }
819
820 void es_fun_8() NO_THREAD_SAFETY_ANALYSIS;
821
es_fun_8()822 void es_fun_8() {
823 Bar.aa_elr_fun_s();
824 }
825
826 void es_fun_9() SHARED_LOCKS_REQUIRED(aa_mu);
es_fun_9()827 void es_fun_9() {
828 Bar.aa_elr_fun_s();
829 }
830
831 void es_fun_10() EXCLUSIVE_LOCKS_REQUIRED(aa_mu);
es_fun_10()832 void es_fun_10() {
833 Bar.aa_elr_fun_s();
834 }
835
es_bad_0()836 void es_bad_0() {
837 Bar.aa_elr_fun(); // \
838 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
839 }
840
es_bad_1()841 void es_bad_1() {
842 aa_mu.ReaderLock();
843 Bar.aa_elr_fun(); // \
844 // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
845 aa_mu.Unlock();
846 }
847
es_bad_2()848 void es_bad_2() {
849 Bar.aa_elr_fun_s(); // \
850 // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
851 }
852
es_bad_3()853 void es_bad_3() {
854 MyLRFoo.test(); // \
855 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
856 }
857
es_bad_4()858 void es_bad_4() {
859 MyLRFoo.testShared(); // \
860 // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
861 }
862
es_bad_5()863 void es_bad_5() {
864 sls_mu.ReaderLock();
865 MyLRFoo.test(); // \
866 // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
867 sls_mu.Unlock();
868 }
869
es_bad_6()870 void es_bad_6() {
871 sls_mu.Lock();
872 Bar.le_fun(); // \
873 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
874 sls_mu.Unlock();
875 }
876
es_bad_7()877 void es_bad_7() {
878 sls_mu.ReaderLock();
879 Bar.le_fun(); // \
880 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
881 sls_mu.Unlock();
882 }
883
884
885 //-----------------------------------------------//
886 // Unparseable lock expressions
887 // ----------------------------------------------//
888
889 // FIXME -- derive new tests for unhandled expressions
890
891
892 //----------------------------------------------------------------------------//
893 // The following test cases are ported from the gcc thread safety implementation
894 // They are each wrapped inside a namespace with the test number of the gcc test
895 //
896 // FIXME: add all the gcc tests, once this analysis passes them.
897 //----------------------------------------------------------------------------//
898
899 //-----------------------------------------//
900 // Good testcases (no errors)
901 //-----------------------------------------//
902
903 namespace thread_annot_lock_20 {
904 class Bar {
905 public:
906 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
907 static int b_ GUARDED_BY(mu1_);
908 static Mutex mu1_;
909 static int a_ GUARDED_BY(mu1_);
910 };
911
912 Bar b1;
913
func1()914 int Bar::func1()
915 {
916 int res = 5;
917
918 if (a_ == 4)
919 res = b_;
920 return res;
921 }
922 } // end namespace thread_annot_lock_20
923
924 namespace thread_annot_lock_22 {
925 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
926 // uses in class definitions.
927 Mutex mu;
928
929 class Bar {
930 public:
931 int a_ GUARDED_BY(mu1_);
932 int b_;
933 int *q PT_GUARDED_BY(mu);
934 Mutex mu1_ ACQUIRED_AFTER(mu);
935 };
936
937 Bar b1, *b3;
938 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
939 int res GUARDED_BY(mu) = 5;
940
func(int i)941 int func(int i)
942 {
943 int x;
944 mu.Lock();
945 b1.mu1_.Lock();
946 res = b1.a_ + b3->b_;
947 *p = i;
948 b1.a_ = res + b3->b_;
949 b3->b_ = *b1.q;
950 b1.mu1_.Unlock();
951 b1.b_ = res;
952 x = res;
953 mu.Unlock();
954 return x;
955 }
956 } // end namespace thread_annot_lock_22
957
958 namespace thread_annot_lock_27_modified {
959 // test lock annotations applied to function definitions
960 // Modified: applied annotations only to function declarations
961 Mutex mu1;
962 Mutex mu2 ACQUIRED_AFTER(mu1);
963
964 class Foo {
965 public:
966 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
967 };
968
method1(int i)969 int Foo::method1(int i) {
970 return i;
971 }
972
973
974 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
foo(int i)975 int foo(int i) {
976 return i;
977 }
978
979 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
bar(int i)980 static int bar(int i) {
981 return i;
982 }
983
main()984 void main() {
985 Foo a;
986
987 mu1.Lock();
988 mu2.Lock();
989 a.method1(1);
990 foo(2);
991 mu2.Unlock();
992 bar(3);
993 mu1.Unlock();
994 }
995 } // end namespace thread_annot_lock_27_modified
996
997
998 namespace thread_annot_lock_38 {
999 // Test the case where a template member function is annotated with lock
1000 // attributes in a non-template class.
1001 class Foo {
1002 public:
1003 void func1(int y) LOCKS_EXCLUDED(mu_);
1004 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
1005 private:
1006 Mutex mu_;
1007 };
1008
1009 Foo *foo;
1010
main()1011 void main()
1012 {
1013 foo->func1(5);
1014 foo->func2(5);
1015 }
1016 } // end namespace thread_annot_lock_38
1017
1018 namespace thread_annot_lock_43 {
1019 // Tests lock canonicalization
1020 class Foo {
1021 public:
1022 Mutex *mu_;
1023 };
1024
1025 class FooBar {
1026 public:
1027 Foo *foo_;
GetA()1028 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
1029 int a_ GUARDED_BY(foo_->mu_);
1030 };
1031
1032 FooBar *fb;
1033
main()1034 void main()
1035 {
1036 int x;
1037 fb->foo_->mu_->Lock();
1038 x = fb->GetA();
1039 fb->foo_->mu_->Unlock();
1040 }
1041 } // end namespace thread_annot_lock_43
1042
1043 namespace thread_annot_lock_49 {
1044 // Test the support for use of lock expression in the annotations
1045 class Foo {
1046 public:
1047 Mutex foo_mu_;
1048 };
1049
1050 class Bar {
1051 private:
1052 Foo *foo;
1053 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
1054
1055 public:
Test1()1056 void Test1() {
1057 foo->foo_mu_.Lock();
1058 bar_mu_.Lock();
1059 bar_mu_.Unlock();
1060 foo->foo_mu_.Unlock();
1061 }
1062 };
1063
main()1064 void main() {
1065 Bar bar;
1066 bar.Test1();
1067 }
1068 } // end namespace thread_annot_lock_49
1069
1070 namespace thread_annot_lock_61_modified {
1071 // Modified to fix the compiler errors
1072 // Test the fix for a bug introduced by the support of pass-by-reference
1073 // parameters.
operator <<thread_annot_lock_61_modified::Foo1074 struct Foo { Foo &operator<< (bool) {return *this;} };
1075 Foo &getFoo();
functhread_annot_lock_61_modified::Bar1076 struct Bar { Foo &func () {return getFoo();} };
operator &thread_annot_lock_61_modified::Bas1077 struct Bas { void operator& (Foo &) {} };
mumble()1078 void mumble()
1079 {
1080 Bas() & Bar().func() << "" << "";
1081 Bas() & Bar().func() << "";
1082 }
1083 } // end namespace thread_annot_lock_61_modified
1084
1085
1086 namespace thread_annot_lock_65 {
1087 // Test the fix for a bug in the support of allowing reader locks for
1088 // non-const, non-modifying overload functions. (We didn't handle the builtin
1089 // properly.)
1090 enum MyFlags {
1091 Zero,
1092 One,
1093 Two,
1094 Three,
1095 Four,
1096 Five,
1097 Six,
1098 Seven,
1099 Eight,
1100 Nine
1101 };
1102
1103 inline MyFlags
operator |(MyFlags a,MyFlags b)1104 operator|(MyFlags a, MyFlags b)
1105 {
1106 return MyFlags(static_cast<int>(a) | static_cast<int>(b));
1107 }
1108
1109 inline MyFlags&
operator |=(MyFlags & a,MyFlags b)1110 operator|=(MyFlags& a, MyFlags b)
1111 {
1112 return a = a | b;
1113 }
1114 } // end namespace thread_annot_lock_65
1115
1116 namespace thread_annot_lock_66_modified {
1117 // Modified: Moved annotation to function defn
1118 // Test annotations on out-of-line definitions of member functions where the
1119 // annotations refer to locks that are also data members in the class.
1120 Mutex mu;
1121
1122 class Foo {
1123 public:
1124 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
1125 int data GUARDED_BY(mu1);
1126 Mutex *mu1;
1127 Mutex *mu2;
1128 };
1129
method1(int i)1130 int Foo::method1(int i)
1131 {
1132 return data + i;
1133 }
1134
main()1135 void main()
1136 {
1137 Foo a;
1138
1139 a.mu2->Lock();
1140 a.mu1->Lock();
1141 mu.Lock();
1142 a.method1(1);
1143 mu.Unlock();
1144 a.mu1->Unlock();
1145 a.mu2->Unlock();
1146 }
1147 } // end namespace thread_annot_lock_66_modified
1148
1149 namespace thread_annot_lock_68_modified {
1150 // Test a fix to a bug in the delayed name binding with nested template
1151 // instantiation. We use a stack to make sure a name is not resolved to an
1152 // inner context.
1153 template <typename T>
1154 class Bar {
1155 Mutex mu_;
1156 };
1157
1158 template <typename T>
1159 class Foo {
1160 public:
func(T x)1161 void func(T x) {
1162 mu_.Lock();
1163 count_ = x;
1164 mu_.Unlock();
1165 }
1166
1167 private:
1168 T count_ GUARDED_BY(mu_);
1169 Bar<T> bar_;
1170 Mutex mu_;
1171 };
1172
main()1173 void main()
1174 {
1175 Foo<int> *foo;
1176 foo->func(5);
1177 }
1178 } // end namespace thread_annot_lock_68_modified
1179
1180 namespace thread_annot_lock_30_modified {
1181 // Test delay parsing of lock attribute arguments with nested classes.
1182 // Modified: trylocks replaced with exclusive_lock_fun
1183 int a = 0;
1184
1185 class Bar {
1186 struct Foo;
1187
1188 public:
1189 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
1190
func()1191 int func() {
1192 MyLock();
1193 // if (foo == 0) {
1194 // return 0;
1195 // }
1196 a = 5;
1197 mu.Unlock();
1198 return 1;
1199 }
1200
1201 class FooBar {
1202 int x;
1203 int y;
1204 };
1205
1206 private:
1207 Mutex mu;
1208 };
1209
1210 Bar *bar;
1211
main()1212 void main()
1213 {
1214 bar->func();
1215 }
1216 } // end namespace thread_annot_lock_30_modified
1217
1218 namespace thread_annot_lock_47 {
1219 // Test the support for annotations on virtual functions.
1220 // This is a good test case. (i.e. There should be no warning emitted by the
1221 // compiler.)
1222 class Base {
1223 public:
1224 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1225 virtual void func2() LOCKS_EXCLUDED(mu_);
1226 Mutex mu_;
1227 };
1228
1229 class Child : public Base {
1230 public:
1231 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1232 virtual void func2() LOCKS_EXCLUDED(mu_);
1233 };
1234
main()1235 void main() {
1236 Child *c;
1237 Base *b = c;
1238
1239 b->mu_.Lock();
1240 b->func1();
1241 b->mu_.Unlock();
1242 b->func2();
1243
1244 c->mu_.Lock();
1245 c->func1();
1246 c->mu_.Unlock();
1247 c->func2();
1248 }
1249 } // end namespace thread_annot_lock_47
1250
1251 //-----------------------------------------//
1252 // Tests which produce errors
1253 //-----------------------------------------//
1254
1255 namespace thread_annot_lock_13 {
1256 Mutex mu1;
1257 Mutex mu2;
1258
1259 int g GUARDED_BY(mu1);
1260 int w GUARDED_BY(mu2);
1261
1262 class Foo {
1263 public:
1264 void bar() LOCKS_EXCLUDED(mu_, mu1);
1265 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
1266
1267 private:
1268 int a_ GUARDED_BY(mu_);
1269 public:
1270 Mutex mu_ ACQUIRED_AFTER(mu1);
1271 };
1272
foo()1273 int Foo::foo()
1274 {
1275 int res;
1276 w = 5;
1277 res = a_ + 5;
1278 return res;
1279 }
1280
bar()1281 void Foo::bar()
1282 {
1283 int x;
1284 mu_.Lock();
1285 x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
1286 a_ = x + 1;
1287 mu_.Unlock();
1288 if (x > 5) {
1289 mu1.Lock();
1290 g = 2;
1291 mu1.Unlock();
1292 }
1293 }
1294
main()1295 void main()
1296 {
1297 Foo f1, *f2;
1298 f1.mu_.Lock();
1299 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
1300 mu2.Lock();
1301 f1.foo();
1302 mu2.Unlock();
1303 f1.mu_.Unlock();
1304 f2->mu_.Lock();
1305 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
1306 f2->mu_.Unlock();
1307 mu2.Lock();
1308 w = 2;
1309 mu2.Unlock();
1310 }
1311 } // end namespace thread_annot_lock_13
1312
1313 namespace thread_annot_lock_18_modified {
1314 // Modified: Trylocks removed
1315 // Test the ability to distnguish between the same lock field of
1316 // different objects of a class.
1317 class Bar {
1318 public:
1319 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
1320 void MyUnlock() UNLOCK_FUNCTION(mu1_);
1321 int a_ GUARDED_BY(mu1_);
1322
1323 private:
1324 Mutex mu1_;
1325 };
1326
1327 Bar *b1, *b2;
1328
func()1329 void func()
1330 {
1331 b1->MyLock();
1332 b1->a_ = 5;
1333 b2->a_ = 3; // \
1334 // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
1335 // expected-note {{found near match 'b1->mu1_'}}
1336 b2->MyLock();
1337 b2->MyUnlock();
1338 b1->MyUnlock();
1339 }
1340 } // end namespace thread_annot_lock_18_modified
1341
1342 namespace thread_annot_lock_21 {
1343 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
1344 // uses in class definitions.
1345 Mutex mu;
1346
1347 class Bar {
1348 public:
1349 int a_ GUARDED_BY(mu1_);
1350 int b_;
1351 int *q PT_GUARDED_BY(mu);
1352 Mutex mu1_ ACQUIRED_AFTER(mu);
1353 };
1354
1355 Bar b1, *b3;
1356 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
1357
1358 int res GUARDED_BY(mu) = 5;
1359
func(int i)1360 int func(int i)
1361 {
1362 int x;
1363 b3->mu1_.Lock();
1364 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
1365 // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
1366 // expected-note {{found near match 'b3->mu1_'}}
1367 *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
1368 // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
1369 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
1370 // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
1371 // expected-note {{found near match 'b3->mu1_'}}
1372 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
1373 b3->mu1_.Unlock();
1374 b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1375 x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
1376 return x;
1377 }
1378 } // end namespace thread_annot_lock_21
1379
1380 namespace thread_annot_lock_35_modified {
1381 // Test the analyzer's ability to distinguish the lock field of different
1382 // objects.
1383 class Foo {
1384 private:
1385 Mutex lock_;
1386 int a_ GUARDED_BY(lock_);
1387
1388 public:
Func(Foo * child)1389 void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
1390 Foo *new_foo = new Foo;
1391
1392 lock_.Lock();
1393
1394 child->Func(new_foo); // There shouldn't be any warning here as the
1395 // acquired lock is not in child.
1396 child->bar(7); // \
1397 // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
1398 // expected-note {{found near match 'lock_'}}
1399 child->a_ = 5; // \
1400 // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
1401 // expected-note {{found near match 'lock_'}}
1402 lock_.Unlock();
1403 }
1404
bar(int y)1405 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
1406 a_ = y;
1407 }
1408 };
1409
1410 Foo *x;
1411
main()1412 void main() {
1413 Foo *child = new Foo;
1414 x->Func(child);
1415 }
1416 } // end namespace thread_annot_lock_35_modified
1417
1418 namespace thread_annot_lock_36_modified {
1419 // Modified to move the annotations to function defns.
1420 // Test the analyzer's ability to distinguish the lock field of different
1421 // objects
1422 class Foo {
1423 private:
1424 Mutex lock_;
1425 int a_ GUARDED_BY(lock_);
1426
1427 public:
1428 void Func(Foo* child) LOCKS_EXCLUDED(lock_);
1429 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
1430 };
1431
Func(Foo * child)1432 void Foo::Func(Foo* child) {
1433 Foo *new_foo = new Foo;
1434
1435 lock_.Lock();
1436
1437 child->lock_.Lock();
1438 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
1439 child->bar(7);
1440 child->a_ = 5;
1441 child->lock_.Unlock();
1442
1443 lock_.Unlock();
1444 }
1445
bar(int y)1446 void Foo::bar(int y) {
1447 a_ = y;
1448 }
1449
1450
1451 Foo *x;
1452
main()1453 void main() {
1454 Foo *child = new Foo;
1455 x->Func(child);
1456 }
1457 } // end namespace thread_annot_lock_36_modified
1458
1459
1460 namespace thread_annot_lock_42 {
1461 // Test support of multiple lock attributes of the same kind on a decl.
1462 class Foo {
1463 private:
1464 Mutex mu1, mu2, mu3;
1465 int x GUARDED_BY(mu1) GUARDED_BY(mu2);
1466 int y GUARDED_BY(mu2);
1467
f2()1468 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
1469 mu2.Lock();
1470 y = 2;
1471 mu2.Unlock();
1472 }
1473
1474 public:
f1()1475 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
1476 x = 5;
1477 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
1478 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
1479 }
1480 };
1481
1482 Foo *foo;
1483
func()1484 void func()
1485 {
1486 foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
1487 // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
1488 }
1489 } // end namespace thread_annot_lock_42
1490
1491 namespace thread_annot_lock_46 {
1492 // Test the support for annotations on virtual functions.
1493 class Base {
1494 public:
1495 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1496 virtual void func2() LOCKS_EXCLUDED(mu_);
1497 Mutex mu_;
1498 };
1499
1500 class Child : public Base {
1501 public:
1502 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
1503 virtual void func2() LOCKS_EXCLUDED(mu_);
1504 };
1505
main()1506 void main() {
1507 Child *c;
1508 Base *b = c;
1509
1510 b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
1511 b->mu_.Lock();
1512 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
1513 b->mu_.Unlock();
1514
1515 c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
1516 c->mu_.Lock();
1517 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
1518 c->mu_.Unlock();
1519 }
1520 } // end namespace thread_annot_lock_46
1521
1522 namespace thread_annot_lock_67_modified {
1523 // Modified: attributes on definitions moved to declarations
1524 // Test annotations on out-of-line definitions of member functions where the
1525 // annotations refer to locks that are also data members in the class.
1526 Mutex mu;
1527 Mutex mu3;
1528
1529 class Foo {
1530 public:
1531 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
1532 int data GUARDED_BY(mu1);
1533 Mutex *mu1;
1534 Mutex *mu2;
1535 };
1536
method1(int i)1537 int Foo::method1(int i) {
1538 return data + i;
1539 }
1540
main()1541 void main()
1542 {
1543 Foo a;
1544 a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
1545 // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
1546 // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
1547 // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
1548 }
1549 } // end namespace thread_annot_lock_67_modified
1550
1551
1552 namespace substitution_test {
1553 class MyData {
1554 public:
1555 Mutex mu;
1556
1557 void lockData() EXCLUSIVE_LOCK_FUNCTION(mu);
1558 void unlockData() UNLOCK_FUNCTION(mu);
1559
doSomething()1560 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu) { }
1561 };
1562
1563
1564 class DataLocker {
1565 public:
1566 void lockData (MyData *d) EXCLUSIVE_LOCK_FUNCTION(d->mu);
1567 void unlockData(MyData *d) UNLOCK_FUNCTION(d->mu);
1568 };
1569
1570
1571 class Foo {
1572 public:
foo(MyData * d)1573 void foo(MyData* d) EXCLUSIVE_LOCKS_REQUIRED(d->mu) { }
1574
bar1(MyData * d)1575 void bar1(MyData* d) {
1576 d->lockData();
1577 foo(d);
1578 d->unlockData();
1579 }
1580
bar2(MyData * d)1581 void bar2(MyData* d) {
1582 DataLocker dlr;
1583 dlr.lockData(d);
1584 foo(d);
1585 dlr.unlockData(d);
1586 }
1587
bar3(MyData * d1,MyData * d2)1588 void bar3(MyData* d1, MyData* d2) {
1589 DataLocker dlr;
1590 dlr.lockData(d1); // expected-note {{mutex acquired here}}
1591 dlr.unlockData(d2); // \
1592 // expected-warning {{releasing mutex 'd2->mu' that was not held}}
1593 } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
1594
bar4(MyData * d1,MyData * d2)1595 void bar4(MyData* d1, MyData* d2) {
1596 DataLocker dlr;
1597 dlr.lockData(d1);
1598 foo(d2); // \
1599 // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
1600 // expected-note {{found near match 'd1->mu'}}
1601 dlr.unlockData(d1);
1602 }
1603 };
1604 } // end namespace substituation_test
1605
1606
1607
1608 namespace constructor_destructor_tests {
1609 Mutex fooMu;
1610 int myVar GUARDED_BY(fooMu);
1611
1612 class Foo {
1613 public:
EXCLUSIVE_LOCK_FUNCTION(fooMu)1614 Foo() EXCLUSIVE_LOCK_FUNCTION(fooMu) { }
UNLOCK_FUNCTION(fooMu)1615 ~Foo() UNLOCK_FUNCTION(fooMu) { }
1616 };
1617
fooTest()1618 void fooTest() {
1619 Foo foo;
1620 myVar = 0;
1621 }
1622 }
1623
1624
1625 namespace template_member_test {
1626
1627 struct S { int n; };
1628 struct T {
1629 Mutex m;
1630 S *s GUARDED_BY(this->m);
1631 };
1632 Mutex m;
1633 struct U {
1634 union {
1635 int n;
1636 };
1637 } *u GUARDED_BY(m);
1638
1639 template<typename U>
1640 struct IndirectLock {
DoNaughtyThingstemplate_member_test::IndirectLock1641 int DoNaughtyThings(T *t) {
1642 u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
1643 return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
1644 }
1645 };
1646
1647 template struct IndirectLock<int>; // expected-note {{here}}
1648
1649 struct V {
1650 void f(int);
1651 void f(double);
1652
1653 Mutex m;
1654 V *p GUARDED_BY(this->m);
1655 };
1656 template<typename U> struct W {
1657 V v;
ftemplate_member_test::W1658 void f(U u) {
1659 v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
1660 }
1661 };
1662 template struct W<int>; // expected-note {{here}}
1663
1664 }
1665
1666 namespace test_scoped_lockable {
1667
1668 struct TestScopedLockable {
1669 Mutex mu1;
1670 Mutex mu2;
1671 int a __attribute__((guarded_by(mu1)));
1672 int b __attribute__((guarded_by(mu2)));
1673
1674 bool getBool();
1675
foo1test_scoped_lockable::TestScopedLockable1676 void foo1() {
1677 MutexLock mulock(&mu1);
1678 a = 5;
1679 }
1680
foo2test_scoped_lockable::TestScopedLockable1681 void foo2() {
1682 ReaderMutexLock mulock1(&mu1);
1683 if (getBool()) {
1684 MutexLock mulock2a(&mu2);
1685 b = a + 1;
1686 }
1687 else {
1688 MutexLock mulock2b(&mu2);
1689 b = a + 2;
1690 }
1691 }
1692
foo3test_scoped_lockable::TestScopedLockable1693 void foo3() {
1694 MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}
1695 MutexLock mulock_b(&mu1); // \
1696 // expected-warning {{acquiring mutex 'mu1' that is already held}}
1697 }
1698
foo4test_scoped_lockable::TestScopedLockable1699 void foo4() {
1700 MutexLock mulock1(&mu1), mulock2(&mu2);
1701 a = b+1;
1702 b = a+1;
1703 }
1704
foo5test_scoped_lockable::TestScopedLockable1705 void foo5() {
1706 DoubleMutexLock mulock(&mu1, &mu2);
1707 a = b + 1;
1708 b = a + 1;
1709 }
1710 };
1711
1712 } // end namespace test_scoped_lockable
1713
1714
1715 namespace FunctionAttrTest {
1716
1717 class Foo {
1718 public:
1719 Mutex mu_;
1720 int a GUARDED_BY(mu_);
1721 };
1722
1723 Foo fooObj;
1724
1725 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
1726
bar()1727 void bar() {
1728 foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
1729 fooObj.mu_.Lock();
1730 foo();
1731 fooObj.mu_.Unlock();
1732 }
1733
1734 }; // end namespace FunctionAttrTest
1735
1736
1737 namespace TryLockTest {
1738
1739 struct TestTryLock {
1740 Mutex mu;
1741 int a GUARDED_BY(mu);
1742 bool cond;
1743
foo1TryLockTest::TestTryLock1744 void foo1() {
1745 if (mu.TryLock()) {
1746 a = 1;
1747 mu.Unlock();
1748 }
1749 }
1750
foo2TryLockTest::TestTryLock1751 void foo2() {
1752 if (!mu.TryLock()) return;
1753 a = 2;
1754 mu.Unlock();
1755 }
1756
foo2_builtin_expectTryLockTest::TestTryLock1757 void foo2_builtin_expect() {
1758 if (__builtin_expect(!mu.TryLock(), false))
1759 return;
1760 a = 2;
1761 mu.Unlock();
1762 }
1763
foo3TryLockTest::TestTryLock1764 void foo3() {
1765 bool b = mu.TryLock();
1766 if (b) {
1767 a = 3;
1768 mu.Unlock();
1769 }
1770 }
1771
foo3_builtin_expectTryLockTest::TestTryLock1772 void foo3_builtin_expect() {
1773 bool b = mu.TryLock();
1774 if (__builtin_expect(b, true)) {
1775 a = 3;
1776 mu.Unlock();
1777 }
1778 }
1779
foo4TryLockTest::TestTryLock1780 void foo4() {
1781 bool b = mu.TryLock();
1782 if (!b) return;
1783 a = 4;
1784 mu.Unlock();
1785 }
1786
foo5TryLockTest::TestTryLock1787 void foo5() {
1788 while (mu.TryLock()) {
1789 a = a + 1;
1790 mu.Unlock();
1791 }
1792 }
1793
foo6TryLockTest::TestTryLock1794 void foo6() {
1795 bool b = mu.TryLock();
1796 b = !b;
1797 if (b) return;
1798 a = 6;
1799 mu.Unlock();
1800 }
1801
foo7TryLockTest::TestTryLock1802 void foo7() {
1803 bool b1 = mu.TryLock();
1804 bool b2 = !b1;
1805 bool b3 = !b2;
1806 if (b3) {
1807 a = 7;
1808 mu.Unlock();
1809 }
1810 }
1811
1812 // Test use-def chains: join points
foo8TryLockTest::TestTryLock1813 void foo8() {
1814 bool b = mu.TryLock();
1815 bool b2 = b;
1816 if (cond)
1817 b = true;
1818 if (b) { // b should be unknown at this point, because of the join point
1819 a = 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1820 }
1821 if (b2) { // b2 should be known at this point.
1822 a = 8;
1823 mu.Unlock();
1824 }
1825 }
1826
1827 // Test use-def-chains: back edges
foo9TryLockTest::TestTryLock1828 void foo9() {
1829 bool b = mu.TryLock();
1830
1831 for (int i = 0; i < 10; ++i);
1832
1833 if (b) { // b is still known, because the loop doesn't alter it
1834 a = 9;
1835 mu.Unlock();
1836 }
1837 }
1838
1839 // Test use-def chains: back edges
foo10TryLockTest::TestTryLock1840 void foo10() {
1841 bool b = mu.TryLock();
1842
1843 while (cond) {
1844 if (b) { // b should be unknown at this point b/c of the loop
1845 a = 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
1846 }
1847 b = !b;
1848 }
1849 }
1850
1851 // Test merge of exclusive trylock
foo11TryLockTest::TestTryLock1852 void foo11() {
1853 if (cond) {
1854 if (!mu.TryLock())
1855 return;
1856 }
1857 else {
1858 mu.Lock();
1859 }
1860 a = 10;
1861 mu.Unlock();
1862 }
1863
1864 // Test merge of shared trylock
foo12TryLockTest::TestTryLock1865 void foo12() {
1866 if (cond) {
1867 if (!mu.ReaderTryLock())
1868 return;
1869 }
1870 else {
1871 mu.ReaderLock();
1872 }
1873 int i = a;
1874 mu.Unlock();
1875 }
1876
1877 // Test with conditional operator
foo13TryLockTest::TestTryLock1878 void foo13() {
1879 if (mu.TryLock() ? 1 : 0)
1880 mu.Unlock();
1881 }
1882
foo14TryLockTest::TestTryLock1883 void foo14() {
1884 if (mu.TryLock() ? 0 : 1)
1885 return;
1886 mu.Unlock();
1887 }
1888
foo15TryLockTest::TestTryLock1889 void foo15() {
1890 if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}}
1891 mu.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}}
1892 } // expected-warning{{mutex 'mu' is not held on every path through here}}
1893 }; // end TestTrylock
1894
1895 } // end namespace TrylockTest
1896
1897
1898 namespace TestTemplateAttributeInstantiation {
1899
1900 class Foo1 {
1901 public:
1902 Mutex mu_;
1903 int a GUARDED_BY(mu_);
1904 };
1905
1906 class Foo2 {
1907 public:
1908 int a GUARDED_BY(mu_);
1909 Mutex mu_;
1910 };
1911
1912
1913 class Bar {
1914 public:
1915 // Test non-dependent expressions in attributes on template functions
1916 template <class T>
barND(Foo1 * foo,T * fooT)1917 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) {
1918 foo->a = 0;
1919 }
1920
1921 // Test dependent expressions in attributes on template functions
1922 template <class T>
barD(Foo1 * foo,T * fooT)1923 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) {
1924 fooT->a = 0;
1925 }
1926 };
1927
1928
1929 template <class T>
1930 class BarT {
1931 public:
1932 Foo1 fooBase;
1933 T fooBaseT;
1934
1935 // Test non-dependent expression in ordinary method on template class
barND()1936 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) {
1937 fooBase.a = 0;
1938 }
1939
1940 // Test dependent expressions in ordinary methods on template class
barD()1941 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) {
1942 fooBaseT.a = 0;
1943 }
1944
1945 // Test dependent expressions in template method in template class
1946 template <class T2>
barTD(T2 * fooT)1947 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) {
1948 fooBaseT.a = 0;
1949 fooT->a = 0;
1950 }
1951 };
1952
1953 template <class T>
1954 class Cell {
1955 public:
1956 Mutex mu_;
1957 // Test dependent guarded_by
1958 T data GUARDED_BY(mu_);
1959
fooEx()1960 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
1961 data = 0;
1962 }
1963
foo()1964 void foo() {
1965 mu_.Lock();
1966 data = 0;
1967 mu_.Unlock();
1968 }
1969 };
1970
test()1971 void test() {
1972 Bar b;
1973 BarT<Foo2> bt;
1974 Foo1 f1;
1975 Foo2 f2;
1976
1977 f1.mu_.Lock();
1978 f2.mu_.Lock();
1979 bt.fooBase.mu_.Lock();
1980 bt.fooBaseT.mu_.Lock();
1981
1982 b.barND(&f1, &f2);
1983 b.barD(&f1, &f2);
1984 bt.barND();
1985 bt.barD();
1986 bt.barTD(&f2);
1987
1988 f1.mu_.Unlock();
1989 bt.barTD(&f1); // \
1990 // expected-warning {{calling function 'barTD<TestTemplateAttributeInstantiation::Foo1>' requires holding mutex 'f1.mu_' exclusively}} \
1991 // expected-note {{found near match 'bt.fooBase.mu_'}}
1992
1993 bt.fooBase.mu_.Unlock();
1994 bt.fooBaseT.mu_.Unlock();
1995 f2.mu_.Unlock();
1996
1997 Cell<int> cell;
1998 cell.data = 0; // \
1999 // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
2000 cell.foo();
2001 cell.mu_.Lock();
2002 cell.fooEx();
2003 cell.mu_.Unlock();
2004 }
2005
2006
2007 template <class T>
2008 class CellDelayed {
2009 public:
2010 // Test dependent guarded_by
2011 T data GUARDED_BY(mu_);
2012 static T static_data GUARDED_BY(static_mu_);
2013
fooEx(CellDelayed<T> * other)2014 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) {
2015 this->data = other->data;
2016 }
2017
2018 template <class T2>
fooExT(CellDelayed<T2> * otherT)2019 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) {
2020 this->data = otherT->data;
2021 }
2022
foo()2023 void foo() {
2024 mu_.Lock();
2025 data = 0;
2026 mu_.Unlock();
2027 }
2028
2029 Mutex mu_;
2030 static Mutex static_mu_;
2031 };
2032
testDelayed()2033 void testDelayed() {
2034 CellDelayed<int> celld;
2035 CellDelayed<int> celld2;
2036 celld.foo();
2037 celld.mu_.Lock();
2038 celld2.mu_.Lock();
2039
2040 celld.fooEx(&celld2);
2041 celld.fooExT(&celld2);
2042
2043 celld2.mu_.Unlock();
2044 celld.mu_.Unlock();
2045 }
2046
2047 }; // end namespace TestTemplateAttributeInstantiation
2048
2049
2050 namespace FunctionDeclDefTest {
2051
2052 class Foo {
2053 public:
2054 Mutex mu_;
2055 int a GUARDED_BY(mu_);
2056
2057 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_);
2058 };
2059
2060 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_
foo1(Foo * f_defined)2061 void Foo::foo1(Foo *f_defined) {
2062 f_defined->a = 0;
2063 };
2064
test()2065 void test() {
2066 Foo myfoo;
2067 myfoo.foo1(&myfoo); // \
2068 // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
2069 myfoo.mu_.Lock();
2070 myfoo.foo1(&myfoo);
2071 myfoo.mu_.Unlock();
2072 }
2073
2074 };
2075
2076 namespace GoingNative {
2077
2078 struct LOCKABLE mutex {
2079 void lock() EXCLUSIVE_LOCK_FUNCTION();
2080 void unlock() UNLOCK_FUNCTION();
2081 // ...
2082 };
2083 bool foo();
2084 bool bar();
2085 mutex m;
test()2086 void test() {
2087 m.lock();
2088 while (foo()) {
2089 m.unlock();
2090 // ...
2091 if (bar()) {
2092 // ...
2093 if (foo())
2094 continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
2095 //...
2096 }
2097 // ...
2098 m.lock(); // expected-note {{mutex acquired here}}
2099 }
2100 m.unlock();
2101 }
2102
2103 }
2104
2105
2106
2107 namespace FunctionDefinitionTest {
2108
2109 class Foo {
2110 public:
2111 void foo1();
2112 void foo2();
2113 void foo3(Foo *other);
2114
2115 template<class T>
2116 void fooT1(const T& dummy1);
2117
2118 template<class T>
2119 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_);
2120
2121 Mutex mu_;
2122 int a GUARDED_BY(mu_);
2123 };
2124
2125 template<class T>
2126 class FooT {
2127 public:
2128 void foo();
2129
2130 Mutex mu_;
2131 T a GUARDED_BY(mu_);
2132 };
2133
2134
foo1()2135 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS {
2136 a = 1;
2137 }
2138
foo2()2139 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2140 a = 2;
2141 }
2142
foo3(Foo * other)2143 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) {
2144 other->a = 3;
2145 }
2146
2147 template<class T>
fooT1(const T & dummy1)2148 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2149 a = dummy1;
2150 }
2151
2152 /* TODO -- uncomment with template instantiation of attributes.
2153 template<class T>
2154 void Foo::fooT2(const T& dummy2) {
2155 a = dummy2;
2156 }
2157 */
2158
fooF1(Foo * f)2159 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2160 f->a = 1;
2161 }
2162
2163 void fooF2(Foo *f);
fooF2(Foo * f)2164 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) {
2165 f->a = 2;
2166 }
2167
2168 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
fooF3(Foo * f)2169 void fooF3(Foo *f) {
2170 f->a = 3;
2171 }
2172
2173 template<class T>
foo()2174 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2175 a = 0;
2176 }
2177
test()2178 void test() {
2179 int dummy = 0;
2180 Foo myFoo;
2181
2182 myFoo.foo2(); // \
2183 // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
2184 myFoo.foo3(&myFoo); // \
2185 // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
2186 myFoo.fooT1(dummy); // \
2187 // expected-warning {{calling function 'fooT1<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2188
2189 myFoo.fooT2(dummy); // \
2190 // expected-warning {{calling function 'fooT2<int>' requires holding mutex 'myFoo.mu_' exclusively}}
2191
2192 fooF1(&myFoo); // \
2193 // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
2194 fooF2(&myFoo); // \
2195 // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
2196 fooF3(&myFoo); // \
2197 // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
2198
2199 myFoo.mu_.Lock();
2200 myFoo.foo2();
2201 myFoo.foo3(&myFoo);
2202 myFoo.fooT1(dummy);
2203
2204 myFoo.fooT2(dummy);
2205
2206 fooF1(&myFoo);
2207 fooF2(&myFoo);
2208 fooF3(&myFoo);
2209 myFoo.mu_.Unlock();
2210
2211 FooT<int> myFooT;
2212 myFooT.foo(); // \
2213 // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
2214 }
2215
2216 } // end namespace FunctionDefinitionTest
2217
2218
2219 namespace SelfLockingTest {
2220
2221 class LOCKABLE MyLock {
2222 public:
2223 int foo GUARDED_BY(this);
2224
2225 void lock() EXCLUSIVE_LOCK_FUNCTION();
2226 void unlock() UNLOCK_FUNCTION();
2227
doSomething()2228 void doSomething() {
2229 this->lock(); // allow 'this' as a lock expression
2230 foo = 0;
2231 doSomethingElse();
2232 this->unlock();
2233 }
2234
doSomethingElse()2235 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) {
2236 foo = 1;
2237 };
2238
test()2239 void test() {
2240 foo = 2; // \
2241 // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
2242 }
2243 };
2244
2245
2246 class LOCKABLE MyLock2 {
2247 public:
2248 Mutex mu_;
2249 int foo GUARDED_BY(this);
2250
2251 // don't check inside lock and unlock functions
lock()2252 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
unlock()2253 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
2254
2255 // don't check inside constructors and destructors
MyLock2()2256 MyLock2() { foo = 1; }
~MyLock2()2257 ~MyLock2() { foo = 0; }
2258 };
2259
2260
2261 } // end namespace SelfLockingTest
2262
2263
2264 namespace InvalidNonstatic {
2265
2266 // Forward decl here causes bogus "invalid use of non-static data member"
2267 // on reference to mutex_ in guarded_by attribute.
2268 class Foo;
2269
2270 class Foo {
2271 Mutex* mutex_;
2272
2273 int foo __attribute__((guarded_by(mutex_)));
2274 };
2275
2276 } // end namespace InvalidNonStatic
2277
2278
2279 namespace NoReturnTest {
2280
2281 bool condition();
2282 void fatal() __attribute__((noreturn));
2283
2284 Mutex mu_;
2285
test1()2286 void test1() {
2287 MutexLock lock(&mu_);
2288 if (condition()) {
2289 fatal();
2290 return;
2291 }
2292 }
2293
2294 } // end namespace NoReturnTest
2295
2296
2297 namespace TestMultiDecl {
2298
2299 class Foo {
2300 public:
2301 int GUARDED_BY(mu_) a;
2302 int GUARDED_BY(mu_) b, c;
2303
foo()2304 void foo() {
2305 a = 0; // \
2306 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2307 b = 0; // \
2308 // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
2309 c = 0; // \
2310 // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
2311 }
2312
2313 private:
2314 Mutex mu_;
2315 };
2316
2317 } // end namespace TestMultiDecl
2318
2319
2320 namespace WarnNoDecl {
2321
2322 class Foo {
2323 void foo(int a); __attribute__(( // \
2324 // expected-warning {{declaration does not declare anything}}
2325 exclusive_locks_required(a))); // \
2326 // expected-warning {{attribute exclusive_locks_required ignored}}
2327 };
2328
2329 } // end namespace WarnNoDecl
2330
2331
2332
2333 namespace MoreLockExpressions {
2334
2335 class Foo {
2336 public:
2337 Mutex mu_;
2338 int a GUARDED_BY(mu_);
2339 };
2340
2341 class Bar {
2342 public:
2343 int b;
2344 Foo* f;
2345
getFoo()2346 Foo& getFoo() { return *f; }
getFoo2(int c)2347 Foo& getFoo2(int c) { return *f; }
getFoo3(int c,int d)2348 Foo& getFoo3(int c, int d) { return *f; }
2349
getFooey()2350 Foo& getFooey() { return *f; }
2351 };
2352
getBarFoo(Bar & bar,int c)2353 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
2354
test()2355 void test() {
2356 Foo foo;
2357 Foo *fooArray;
2358 Foo &(*fooFuncPtr)();
2359 Bar bar;
2360 int a;
2361 int b;
2362 int c;
2363
2364 bar.getFoo().mu_.Lock();
2365 bar.getFoo().a = 0;
2366 bar.getFoo().mu_.Unlock();
2367
2368 (bar.getFoo().mu_).Lock(); // test parenthesis
2369 bar.getFoo().a = 0;
2370 (bar.getFoo().mu_).Unlock();
2371
2372 bar.getFoo2(a).mu_.Lock();
2373 bar.getFoo2(a).a = 0;
2374 bar.getFoo2(a).mu_.Unlock();
2375
2376 bar.getFoo3(a, b).mu_.Lock();
2377 bar.getFoo3(a, b).a = 0;
2378 bar.getFoo3(a, b).mu_.Unlock();
2379
2380 getBarFoo(bar, a).mu_.Lock();
2381 getBarFoo(bar, a).a = 0;
2382 getBarFoo(bar, a).mu_.Unlock();
2383
2384 bar.getFoo2(10).mu_.Lock();
2385 bar.getFoo2(10).a = 0;
2386 bar.getFoo2(10).mu_.Unlock();
2387
2388 bar.getFoo2(a + 1).mu_.Lock();
2389 bar.getFoo2(a + 1).a = 0;
2390 bar.getFoo2(a + 1).mu_.Unlock();
2391
2392 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2393 (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
2394 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2395
2396 fooFuncPtr().mu_.Lock();
2397 fooFuncPtr().a = 0;
2398 fooFuncPtr().mu_.Unlock();
2399 }
2400
2401
test2()2402 void test2() {
2403 Foo *fooArray;
2404 Bar bar;
2405 int a;
2406 int b;
2407 int c;
2408
2409 bar.getFoo().mu_.Lock();
2410 bar.getFooey().a = 0; // \
2411 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
2412 // expected-note {{found near match 'bar.getFoo().mu_'}}
2413 bar.getFoo().mu_.Unlock();
2414
2415 bar.getFoo2(a).mu_.Lock();
2416 bar.getFoo2(b).a = 0; // \
2417 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
2418 // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
2419 bar.getFoo2(a).mu_.Unlock();
2420
2421 bar.getFoo3(a, b).mu_.Lock();
2422 bar.getFoo3(a, c).a = 0; // \
2423 // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a, c).mu_' exclusively}} \
2424 // expected-note {{found near match 'bar.getFoo3(a, b).mu_'}}
2425 bar.getFoo3(a, b).mu_.Unlock();
2426
2427 getBarFoo(bar, a).mu_.Lock();
2428 getBarFoo(bar, b).a = 0; // \
2429 // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar, b).mu_' exclusively}} \
2430 // expected-note {{found near match 'getBarFoo(bar, a).mu_'}}
2431 getBarFoo(bar, a).mu_.Unlock();
2432
2433 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
2434 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
2435 // expected-warning {{writing variable 'a' requires holding mutex '((0 < a) ? fooArray[b] : fooArray[c]).mu_' exclusively}} \
2436 // expected-note {{found near match '((0 < a) ? fooArray[1] : fooArray[b]).mu_'}}
2437 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
2438 }
2439
2440
2441 } // end namespace MoreLockExpressions
2442
2443
2444 namespace TrylockJoinPoint {
2445
2446 class Foo {
2447 Mutex mu;
2448 bool c;
2449
foo()2450 void foo() {
2451 if (c) {
2452 if (!mu.TryLock())
2453 return;
2454 } else {
2455 mu.Lock();
2456 }
2457 mu.Unlock();
2458 }
2459 };
2460
2461 } // end namespace TrylockJoinPoint
2462
2463
2464 namespace LockReturned {
2465
2466 class Foo {
2467 public:
2468 int a GUARDED_BY(mu_);
2469 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2470 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
2471
2472 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
2473
2474 Mutex* getMu() LOCK_RETURNED(mu_);
2475
2476 Mutex mu_;
2477
2478 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
2479 };
2480
2481
2482 // Calls getMu() directly to lock and unlock
test1(Foo * f1,Foo * f2)2483 void test1(Foo* f1, Foo* f2) {
2484 f1->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
2485 f1->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
2486
2487 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
2488 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
2489 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
2490
2491 f1->getMu()->Lock();
2492
2493 f1->a = 0;
2494 f1->foo();
2495 f1->foo2(f2); // \
2496 // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
2497 // expected-note {{found near match 'f1->mu_'}}
2498
2499 Foo::getMu(f2)->Lock();
2500 f1->foo2(f2);
2501 Foo::getMu(f2)->Unlock();
2502
2503 Foo::sfoo(f1);
2504
2505 f1->getMu()->Unlock();
2506 }
2507
2508
2509 Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
2510
2511 class Bar : public Foo {
2512 public:
2513 int b GUARDED_BY(getMu());
2514 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
2515 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
2516
2517 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
2518 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
2519 };
2520
2521
2522
2523 // Use getMu() within other attributes.
2524 // This requires at lest levels of substitution, more in the case of
test2(Bar * b1,Bar * b2)2525 void test2(Bar* b1, Bar* b2) {
2526 b1->b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
2527 b1->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
2528 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
2529 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
2530 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
2531 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
2532
2533 b1->getMu()->Lock();
2534
2535 b1->b = 0;
2536 b1->bar();
2537 b1->bar2(b2); // \
2538 // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
2539 // // expected-note {{found near match 'b1->mu_'}}
2540
2541 b2->getMu()->Lock();
2542 b1->bar2(b2);
2543
2544 b2->getMu()->Unlock();
2545
2546 Bar::sbar(b1);
2547 Bar::sbar2(b1);
2548
2549 b1->getMu()->Unlock();
2550 }
2551
2552
2553 // Sanity check -- lock the mutex directly, but use attributes that call getMu()
2554 // Also lock the mutex using getFooMu, which calls a lock_returned function.
test3(Bar * b1,Bar * b2)2555 void test3(Bar* b1, Bar* b2) {
2556 b1->mu_.Lock();
2557 b1->b = 0;
2558 b1->bar();
2559
2560 getFooMu(b2)->Lock();
2561 b1->bar2(b2);
2562 getFooMu(b2)->Unlock();
2563
2564 Bar::sbar(b1);
2565 Bar::sbar2(b1);
2566
2567 b1->mu_.Unlock();
2568 }
2569
2570 } // end namespace LockReturned
2571
2572
2573 namespace ReleasableScopedLock {
2574
2575 class Foo {
2576 Mutex mu_;
2577 bool c;
2578 int a GUARDED_BY(mu_);
2579
2580 void test1();
2581 void test2();
2582 void test3();
2583 void test4();
2584 void test5();
2585 };
2586
2587
test1()2588 void Foo::test1() {
2589 ReleasableMutexLock rlock(&mu_);
2590 rlock.Release();
2591 }
2592
test2()2593 void Foo::test2() {
2594 ReleasableMutexLock rlock(&mu_);
2595 if (c) { // test join point -- held/not held during release
2596 rlock.Release();
2597 }
2598 }
2599
test3()2600 void Foo::test3() {
2601 ReleasableMutexLock rlock(&mu_);
2602 a = 0;
2603 rlock.Release();
2604 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
2605 }
2606
test4()2607 void Foo::test4() {
2608 ReleasableMutexLock rlock(&mu_);
2609 rlock.Release();
2610 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2611 }
2612
test5()2613 void Foo::test5() {
2614 ReleasableMutexLock rlock(&mu_);
2615 if (c) {
2616 rlock.Release();
2617 }
2618 // no warning on join point for managed lock.
2619 rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
2620 }
2621
2622
2623 } // end namespace ReleasableScopedLock
2624
2625
2626 namespace RelockableScopedLock {
2627
2628 class SCOPED_LOCKABLE RelockableExclusiveMutexLock {
2629 public:
2630 RelockableExclusiveMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2631 ~RelockableExclusiveMutexLock() EXCLUSIVE_UNLOCK_FUNCTION();
2632
2633 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2634 void Unlock() UNLOCK_FUNCTION();
2635 };
2636
2637 struct SharedTraits {};
2638 struct ExclusiveTraits {};
2639
2640 class SCOPED_LOCKABLE RelockableMutexLock {
2641 public:
2642 RelockableMutexLock(Mutex *mu, SharedTraits) SHARED_LOCK_FUNCTION(mu);
2643 RelockableMutexLock(Mutex *mu, ExclusiveTraits) EXCLUSIVE_LOCK_FUNCTION(mu);
2644 ~RelockableMutexLock() UNLOCK_FUNCTION();
2645
2646 void Lock() EXCLUSIVE_LOCK_FUNCTION();
2647 void Unlock() UNLOCK_FUNCTION();
2648
2649 void ReaderLock() SHARED_LOCK_FUNCTION();
2650 void ReaderUnlock() UNLOCK_FUNCTION();
2651
2652 void PromoteShared() UNLOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION();
2653 void DemoteExclusive() UNLOCK_FUNCTION() SHARED_LOCK_FUNCTION();
2654 };
2655
2656 Mutex mu;
2657 int x GUARDED_BY(mu);
2658
2659 void print(int);
2660
relock()2661 void relock() {
2662 RelockableExclusiveMutexLock scope(&mu);
2663 x = 2;
2664 scope.Unlock();
2665
2666 x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2667
2668 scope.Lock();
2669 x = 4;
2670 }
2671
relockExclusive()2672 void relockExclusive() {
2673 RelockableMutexLock scope(&mu, SharedTraits{});
2674 print(x);
2675 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2676 scope.ReaderUnlock();
2677
2678 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2679
2680 scope.Lock();
2681 print(x);
2682 x = 4;
2683
2684 scope.DemoteExclusive();
2685 print(x);
2686 x = 5; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2687 }
2688
relockShared()2689 void relockShared() {
2690 RelockableMutexLock scope(&mu, ExclusiveTraits{});
2691 print(x);
2692 x = 2;
2693 scope.Unlock();
2694
2695 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2696
2697 scope.ReaderLock();
2698 print(x);
2699 x = 4; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2700
2701 scope.PromoteShared();
2702 print(x);
2703 x = 5;
2704 }
2705
doubleUnlock()2706 void doubleUnlock() {
2707 RelockableExclusiveMutexLock scope(&mu);
2708 scope.Unlock();
2709 scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
2710 }
2711
doubleLock1()2712 void doubleLock1() {
2713 RelockableExclusiveMutexLock scope(&mu); // expected-note{{mutex acquired here}}
2714 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2715 }
2716
doubleLock2()2717 void doubleLock2() {
2718 RelockableExclusiveMutexLock scope(&mu);
2719 scope.Unlock();
2720 scope.Lock(); // expected-note{{mutex acquired here}}
2721 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2722 }
2723
directUnlock()2724 void directUnlock() {
2725 RelockableExclusiveMutexLock scope(&mu);
2726 mu.Unlock();
2727 // Debatable that there is no warning. Currently we don't track in the scoped
2728 // object whether it is active, but just check if the contained locks can be
2729 // reacquired. Here they can, because mu has been unlocked manually.
2730 scope.Lock();
2731 }
2732
directRelock()2733 void directRelock() {
2734 RelockableExclusiveMutexLock scope(&mu);
2735 scope.Unlock();
2736 mu.Lock();
2737 // Similarly debatable that there is no warning.
2738 scope.Unlock();
2739 }
2740
2741 // Doesn't make a lot of sense, just making sure there is no crash.
destructLock()2742 void destructLock() {
2743 RelockableExclusiveMutexLock scope(&mu);
2744 scope.~RelockableExclusiveMutexLock();
2745 scope.Lock(); // Should be UB, so we don't really care.
2746 }
2747
2748 class SCOPED_LOCKABLE MemberLock {
2749 public:
2750 MemberLock() EXCLUSIVE_LOCK_FUNCTION(mutex);
2751 ~MemberLock() UNLOCK_FUNCTION(mutex);
2752 void Lock() EXCLUSIVE_LOCK_FUNCTION(mutex);
2753 Mutex mutex;
2754 };
2755
relockShared2()2756 void relockShared2() {
2757 MemberLock lock; // expected-note{{mutex acquired here}}
2758 lock.Lock(); // expected-warning {{acquiring mutex 'lock.mutex' that is already held}}
2759 }
2760
2761 class SCOPED_LOCKABLE WeirdScope {
2762 private:
2763 Mutex *other;
2764
2765 public:
2766 WeirdScope(Mutex *mutex) EXCLUSIVE_LOCK_FUNCTION(mutex);
2767 void unlock() EXCLUSIVE_UNLOCK_FUNCTION() EXCLUSIVE_UNLOCK_FUNCTION(other);
2768 void lock() EXCLUSIVE_LOCK_FUNCTION() EXCLUSIVE_LOCK_FUNCTION(other);
2769 ~WeirdScope() EXCLUSIVE_UNLOCK_FUNCTION();
2770
2771 void requireOther() EXCLUSIVE_LOCKS_REQUIRED(other);
2772 };
2773
relockWeird()2774 void relockWeird() {
2775 WeirdScope scope(&mu);
2776 x = 1;
2777 scope.unlock(); // expected-warning {{releasing mutex 'scope.other' that was not held}}
2778 x = 2; // \
2779 // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2780 scope.requireOther(); // \
2781 // expected-warning {{calling function 'requireOther' requires holding mutex 'scope.other' exclusively}}
2782 scope.lock(); // expected-note {{mutex acquired here}}
2783 x = 3;
2784 scope.requireOther();
2785 } // expected-warning {{mutex 'scope.other' is still held at the end of function}}
2786
2787 } // end namespace RelockableScopedLock
2788
2789
2790 namespace ScopedUnlock {
2791
2792 class SCOPED_LOCKABLE MutexUnlock {
2793 public:
2794 MutexUnlock(Mutex *mu) EXCLUSIVE_UNLOCK_FUNCTION(mu);
2795 ~MutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
2796
2797 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
2798 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
2799 };
2800
2801 class SCOPED_LOCKABLE ReaderMutexUnlock {
2802 public:
2803 ReaderMutexUnlock(Mutex *mu) SHARED_UNLOCK_FUNCTION(mu);
2804 ~ReaderMutexUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
2805
2806 void Lock() EXCLUSIVE_UNLOCK_FUNCTION();
2807 void Unlock() EXCLUSIVE_LOCK_FUNCTION();
2808 };
2809
2810 Mutex mu;
2811 int x GUARDED_BY(mu);
2812 bool c;
2813 void print(int);
2814
simple()2815 void simple() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2816 x = 1;
2817 MutexUnlock scope(&mu);
2818 x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2819 }
2820
simpleShared()2821 void simpleShared() SHARED_LOCKS_REQUIRED(mu) {
2822 print(x);
2823 ReaderMutexUnlock scope(&mu);
2824 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2825 }
2826
innerUnlock()2827 void innerUnlock() {
2828 MutexLock outer(&mu);
2829 if (x == 0) {
2830 MutexUnlock inner(&mu);
2831 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2832 }
2833 x = 2;
2834 }
2835
innerUnlockShared()2836 void innerUnlockShared() {
2837 ReaderMutexLock outer(&mu);
2838 if (x == 0) {
2839 ReaderMutexUnlock inner(&mu);
2840 print(x); // expected-warning {{reading variable 'x' requires holding mutex 'mu'}}
2841 }
2842 print(x);
2843 }
2844
manual()2845 void manual() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2846 MutexUnlock scope(&mu);
2847 scope.Lock();
2848 x = 2;
2849 scope.Unlock();
2850 x = 3; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2851 }
2852
join()2853 void join() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2854 MutexUnlock scope(&mu);
2855 if (c) {
2856 scope.Lock(); // expected-note{{mutex acquired here}}
2857 }
2858 // expected-warning@+1{{mutex 'mu' is not held on every path through here}}
2859 scope.Lock();
2860 }
2861
doubleLock()2862 void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2863 MutexUnlock scope(&mu);
2864 scope.Lock(); // expected-note{{mutex acquired here}}
2865 scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
2866 }
2867
doubleUnlock()2868 void doubleUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2869 MutexUnlock scope(&mu);
2870 scope.Unlock(); // expected-warning {{releasing mutex 'mu' that was not held}}
2871 }
2872
2873 class SCOPED_LOCKABLE MutexLockUnlock {
2874 public:
2875 MutexLockUnlock(Mutex *mu1, Mutex *mu2) EXCLUSIVE_UNLOCK_FUNCTION(mu1) EXCLUSIVE_LOCK_FUNCTION(mu2);
2876 ~MutexLockUnlock() EXCLUSIVE_UNLOCK_FUNCTION();
2877
2878 void Release() EXCLUSIVE_UNLOCK_FUNCTION();
2879 void Acquire() EXCLUSIVE_LOCK_FUNCTION();
2880 };
2881
2882 Mutex other;
2883 void fn() EXCLUSIVE_LOCKS_REQUIRED(other);
2884
lockUnlock()2885 void lockUnlock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
2886 MutexLockUnlock scope(&mu, &other);
2887 fn();
2888 x = 1; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}}
2889 }
2890
2891 } // end namespace ScopedUnlock
2892
2893
2894 namespace TrylockFunctionTest {
2895
2896 class Foo {
2897 public:
2898 Mutex mu1_;
2899 Mutex mu2_;
2900 bool c;
2901
2902 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
2903 };
2904
lockBoth()2905 bool Foo::lockBoth() {
2906 if (!mu1_.TryLock())
2907 return false;
2908
2909 mu2_.Lock();
2910 if (!c) {
2911 mu1_.Unlock();
2912 mu2_.Unlock();
2913 return false;
2914 }
2915
2916 return true;
2917 }
2918
2919
2920 } // end namespace TrylockFunctionTest
2921
2922
2923
2924 namespace DoubleLockBug {
2925
2926 class Foo {
2927 public:
2928 Mutex mu_;
2929 int a GUARDED_BY(mu_);
2930
2931 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
2932 int foo2() SHARED_LOCKS_REQUIRED(mu_);
2933 };
2934
2935
foo1()2936 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2937 a = 0;
2938 }
2939
foo2()2940 int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
2941 return a;
2942 }
2943
2944 }
2945
2946
2947
2948 namespace UnlockBug {
2949
2950 class Foo {
2951 public:
2952 Mutex mutex_;
2953
foo1()2954 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2955 mutex_.Unlock();
2956 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2957
2958
foo2()2959 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
2960 mutex_.Unlock();
2961 } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
2962 };
2963
2964 } // end namespace UnlockBug
2965
2966
2967
2968 namespace FoolishScopedLockableBug {
2969
2970 class SCOPED_LOCKABLE WTF_ScopedLockable {
2971 public:
2972 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
2973
2974 // have to call release() manually;
2975 ~WTF_ScopedLockable();
2976
2977 void release() UNLOCK_FUNCTION();
2978 };
2979
2980
2981 class Foo {
2982 Mutex mu_;
2983 int a GUARDED_BY(mu_);
2984 bool c;
2985
2986 void doSomething();
2987
test1()2988 void test1() {
2989 WTF_ScopedLockable wtf(&mu_);
2990 wtf.release();
2991 }
2992
test2()2993 void test2() {
2994 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
2995 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
2996
test3()2997 void test3() {
2998 if (c) {
2999 WTF_ScopedLockable wtf(&mu_);
3000 wtf.release();
3001 }
3002 }
3003
test4()3004 void test4() {
3005 if (c) {
3006 doSomething();
3007 }
3008 else {
3009 WTF_ScopedLockable wtf(&mu_);
3010 wtf.release();
3011 }
3012 }
3013
test5()3014 void test5() {
3015 if (c) {
3016 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
3017 }
3018 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3019
test6()3020 void test6() {
3021 if (c) {
3022 doSomething();
3023 }
3024 else {
3025 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
3026 }
3027 } // expected-warning {{mutex 'mu_' is not held on every path through here}}
3028 };
3029
3030
3031 } // end namespace FoolishScopedLockableBug
3032
3033
3034
3035 namespace TemporaryCleanupExpr {
3036
3037 class Foo {
3038 int a GUARDED_BY(getMutexPtr().get());
3039
3040 SmartPtr<Mutex> getMutexPtr();
3041
3042 void test();
3043 };
3044
3045
test()3046 void Foo::test() {
3047 {
3048 ReaderMutexLock lock(getMutexPtr().get());
3049 int b = a;
3050 }
3051 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
3052 }
3053
3054 } // end namespace TemporaryCleanupExpr
3055
3056
3057
3058 namespace SmartPointerTests {
3059
3060 class Foo {
3061 public:
3062 SmartPtr<Mutex> mu_;
3063 int a GUARDED_BY(mu_);
3064 int b GUARDED_BY(mu_.get());
3065 int c GUARDED_BY(*mu_);
3066
3067 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3068 void Unlock() UNLOCK_FUNCTION(mu_);
3069
3070 void test0();
3071 void test1();
3072 void test2();
3073 void test3();
3074 void test4();
3075 void test5();
3076 void test6();
3077 void test7();
3078 void test8();
3079 };
3080
test0()3081 void Foo::test0() {
3082 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3083 b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
3084 c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
3085 }
3086
test1()3087 void Foo::test1() {
3088 mu_->Lock();
3089 a = 0;
3090 b = 0;
3091 c = 0;
3092 mu_->Unlock();
3093 }
3094
test2()3095 void Foo::test2() {
3096 (*mu_).Lock();
3097 a = 0;
3098 b = 0;
3099 c = 0;
3100 (*mu_).Unlock();
3101 }
3102
3103
test3()3104 void Foo::test3() {
3105 mu_.get()->Lock();
3106 a = 0;
3107 b = 0;
3108 c = 0;
3109 mu_.get()->Unlock();
3110 }
3111
3112
test4()3113 void Foo::test4() {
3114 MutexLock lock(mu_.get());
3115 a = 0;
3116 b = 0;
3117 c = 0;
3118 }
3119
3120
test5()3121 void Foo::test5() {
3122 MutexLock lock(&(*mu_));
3123 a = 0;
3124 b = 0;
3125 c = 0;
3126 }
3127
3128
test6()3129 void Foo::test6() {
3130 Lock();
3131 a = 0;
3132 b = 0;
3133 c = 0;
3134 Unlock();
3135 }
3136
3137
test7()3138 void Foo::test7() {
3139 {
3140 Lock();
3141 mu_->Unlock();
3142 }
3143 {
3144 mu_->Lock();
3145 Unlock();
3146 }
3147 {
3148 mu_.get()->Lock();
3149 mu_->Unlock();
3150 }
3151 {
3152 mu_->Lock();
3153 mu_.get()->Unlock();
3154 }
3155 {
3156 mu_.get()->Lock();
3157 (*mu_).Unlock();
3158 }
3159 {
3160 (*mu_).Lock();
3161 mu_->Unlock();
3162 }
3163 }
3164
3165
test8()3166 void Foo::test8() {
3167 mu_->Lock(); // expected-note 2 {{mutex acquired here}}
3168 mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3169 (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3170 mu_.get()->Unlock();
3171 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
3172 }
3173
3174
3175 class Bar {
3176 SmartPtr<Foo> foo;
3177
3178 void test0();
3179 void test1();
3180 void test2();
3181 void test3();
3182 };
3183
3184
test0()3185 void Bar::test0() {
3186 foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
3187 (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
3188 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
3189 }
3190
3191
test1()3192 void Bar::test1() {
3193 foo->mu_->Lock();
3194 foo->a = 0;
3195 (*foo).b = 0;
3196 foo.get()->c = 0;
3197 foo->mu_->Unlock();
3198 }
3199
3200
test2()3201 void Bar::test2() {
3202 (*foo).mu_->Lock();
3203 foo->a = 0;
3204 (*foo).b = 0;
3205 foo.get()->c = 0;
3206 foo.get()->mu_->Unlock();
3207 }
3208
3209
test3()3210 void Bar::test3() {
3211 MutexLock lock(foo->mu_.get());
3212 foo->a = 0;
3213 (*foo).b = 0;
3214 foo.get()->c = 0;
3215 }
3216
3217 } // end namespace SmartPointerTests
3218
3219
3220
3221 namespace DuplicateAttributeTest {
3222
3223 class LOCKABLE Foo {
3224 public:
3225 Mutex mu1_;
3226 Mutex mu2_;
3227 Mutex mu3_;
3228 int a GUARDED_BY(mu1_);
3229 int b GUARDED_BY(mu2_);
3230 int c GUARDED_BY(mu3_);
3231
3232 void lock() EXCLUSIVE_LOCK_FUNCTION();
3233 void unlock() UNLOCK_FUNCTION();
3234
3235 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
3236 void slock1() SHARED_LOCK_FUNCTION(mu1_);
3237 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3238 void locklots()
3239 EXCLUSIVE_LOCK_FUNCTION(mu1_)
3240 EXCLUSIVE_LOCK_FUNCTION(mu2_)
3241 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3242
3243 void unlock1() UNLOCK_FUNCTION(mu1_);
3244 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3245 void unlocklots()
3246 UNLOCK_FUNCTION(mu1_)
3247 UNLOCK_FUNCTION(mu2_)
3248 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3249 };
3250
3251
lock()3252 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
unlock()3253 void Foo::unlock() UNLOCK_FUNCTION() { }
3254
lock1()3255 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
3256 mu1_.Lock();
3257 }
3258
slock1()3259 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
3260 mu1_.ReaderLock();
3261 }
3262
lock3()3263 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
3264 mu1_.Lock();
3265 mu2_.Lock();
3266 mu3_.Lock();
3267 }
3268
locklots()3269 void Foo::locklots()
3270 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
3271 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
3272 mu1_.Lock();
3273 mu2_.Lock();
3274 mu3_.Lock();
3275 }
3276
unlock1()3277 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
3278 mu1_.Unlock();
3279 }
3280
unlock3()3281 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
3282 mu1_.Unlock();
3283 mu2_.Unlock();
3284 mu3_.Unlock();
3285 }
3286
unlocklots()3287 void Foo::unlocklots()
3288 UNLOCK_FUNCTION(mu1_, mu2_)
3289 UNLOCK_FUNCTION(mu2_, mu3_) {
3290 mu1_.Unlock();
3291 mu2_.Unlock();
3292 mu3_.Unlock();
3293 }
3294
3295
test0()3296 void test0() {
3297 Foo foo;
3298 foo.lock();
3299 foo.unlock();
3300
3301 foo.lock(); // expected-note{{mutex acquired here}}
3302 foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
3303 foo.unlock();
3304 foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
3305 }
3306
3307
test1()3308 void test1() {
3309 Foo foo;
3310 foo.lock1();
3311 foo.a = 0;
3312 foo.unlock1();
3313
3314 foo.lock1(); // expected-note{{mutex acquired here}}
3315 foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3316 foo.a = 0;
3317 foo.unlock1();
3318 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3319 }
3320
3321
test2()3322 int test2() {
3323 Foo foo;
3324 foo.slock1();
3325 int d1 = foo.a;
3326 foo.unlock1();
3327
3328 foo.slock1(); // expected-note{{mutex acquired here}}
3329 foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3330 int d2 = foo.a;
3331 foo.unlock1();
3332 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3333 return d1 + d2;
3334 }
3335
3336
test3()3337 void test3() {
3338 Foo foo;
3339 foo.lock3();
3340 foo.a = 0;
3341 foo.b = 0;
3342 foo.c = 0;
3343 foo.unlock3();
3344
3345 foo.lock3(); // expected-note 3 {{mutex acquired here}}
3346 foo.lock3(); // \
3347 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3348 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3349 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3350 foo.a = 0;
3351 foo.b = 0;
3352 foo.c = 0;
3353 foo.unlock3();
3354 foo.unlock3(); // \
3355 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3356 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3357 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3358 }
3359
3360
testlots()3361 void testlots() {
3362 Foo foo;
3363 foo.locklots();
3364 foo.a = 0;
3365 foo.b = 0;
3366 foo.c = 0;
3367 foo.unlocklots();
3368
3369 foo.locklots(); // expected-note 3 {{mutex acquired here}}
3370 foo.locklots(); // \
3371 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3372 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3373 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3374 foo.a = 0;
3375 foo.b = 0;
3376 foo.c = 0;
3377 foo.unlocklots();
3378 foo.unlocklots(); // \
3379 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3380 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3381 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3382 }
3383
3384 } // end namespace DuplicateAttributeTest
3385
3386
3387
3388 namespace TryLockEqTest {
3389
3390 class Foo {
3391 Mutex mu_;
3392 int a GUARDED_BY(mu_);
3393 bool c;
3394
3395 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3396 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3397 void unlock() UNLOCK_FUNCTION(mu_);
3398
3399 void test1();
3400 void test2();
3401 };
3402
3403
test1()3404 void Foo::test1() {
3405 if (tryLockMutexP() == 0) {
3406 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3407 return;
3408 }
3409 a = 0;
3410 unlock();
3411
3412 if (tryLockMutexP() != 0) {
3413 a = 0;
3414 unlock();
3415 }
3416
3417 if (0 != tryLockMutexP()) {
3418 a = 0;
3419 unlock();
3420 }
3421
3422 if (!(tryLockMutexP() == 0)) {
3423 a = 0;
3424 unlock();
3425 }
3426
3427 if (tryLockMutexI() == 0) {
3428 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3429 return;
3430 }
3431 a = 0;
3432 unlock();
3433
3434 if (0 == tryLockMutexI()) {
3435 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3436 return;
3437 }
3438 a = 0;
3439 unlock();
3440
3441 if (tryLockMutexI() == 1) {
3442 a = 0;
3443 unlock();
3444 }
3445
3446 if (mu_.TryLock() == false) {
3447 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3448 return;
3449 }
3450 a = 0;
3451 unlock();
3452
3453 if (mu_.TryLock() == true) {
3454 a = 0;
3455 unlock();
3456 }
3457 else {
3458 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3459 }
3460
3461 #if __has_feature(cxx_nullptr)
3462 if (tryLockMutexP() == nullptr) {
3463 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3464 return;
3465 }
3466 a = 0;
3467 unlock();
3468 #endif
3469 }
3470
3471 } // end namespace TryLockEqTest
3472
3473
3474 namespace ExistentialPatternMatching {
3475
3476 class Graph {
3477 public:
3478 Mutex mu_;
3479 };
3480
3481 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3482 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3483
3484 class Node {
3485 public:
3486 int a GUARDED_BY(&Graph::mu_);
3487
foo()3488 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3489 a = 0;
3490 }
3491 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3492 };
3493
test()3494 void test() {
3495 Graph g1;
3496 Graph g2;
3497 Node n1;
3498
3499 n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3500 n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3501 n1.foo2();
3502
3503 g1.mu_.Lock();
3504 n1.a = 0;
3505 n1.foo();
3506 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3507 g1.mu_.Unlock();
3508
3509 g2.mu_.Lock();
3510 n1.a = 0;
3511 n1.foo();
3512 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3513 g2.mu_.Unlock();
3514
3515 LockAllGraphs();
3516 n1.a = 0;
3517 n1.foo();
3518 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3519 UnlockAllGraphs();
3520
3521 LockAllGraphs();
3522 g1.mu_.Unlock();
3523
3524 LockAllGraphs();
3525 g2.mu_.Unlock();
3526
3527 LockAllGraphs(); // expected-note{{mutex acquired here}}
3528 g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3529 g1.mu_.Unlock();
3530 }
3531
3532 } // end namespace ExistentialPatternMatching
3533
3534
3535 namespace StringIgnoreTest {
3536
3537 class Foo {
3538 public:
3539 Mutex mu_;
3540 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3541 void unlock() UNLOCK_FUNCTION("");
3542 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3543 void roober() SHARED_LOCKS_REQUIRED("");
3544 };
3545
3546
3547 class Bar : public Foo {
3548 public:
bar(Foo * f)3549 void bar(Foo* f) {
3550 f->unlock();
3551 f->goober();
3552 f->roober();
3553 f->lock();
3554 };
3555 };
3556
3557 } // end namespace StringIgnoreTest
3558
3559
3560 namespace LockReturnedScopeFix {
3561
3562 class Base {
3563 protected:
3564 struct Inner;
3565 bool c;
3566
3567 const Mutex& getLock(const Inner* i);
3568
3569 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3570 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3571 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3572
3573 void bar(Inner* i);
3574 };
3575
3576
3577 struct Base::Inner {
3578 Mutex lock_;
3579 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3580 };
3581
3582
getLock(const Inner * i)3583 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3584 return i->lock_;
3585 }
3586
3587
foo(Inner * i)3588 void Base::foo(Inner* i) {
3589 i->doSomething();
3590 }
3591
bar(Inner * i)3592 void Base::bar(Inner* i) {
3593 if (c) {
3594 i->lock_.Lock();
3595 unlockInner(i);
3596 }
3597 else {
3598 lockInner(i);
3599 i->lock_.Unlock();
3600 }
3601 }
3602
3603 } // end namespace LockReturnedScopeFix
3604
3605
3606 namespace TrylockWithCleanups {
3607
3608 struct Foo {
3609 Mutex mu_;
3610 int a GUARDED_BY(mu_);
3611 };
3612
3613 Foo* GetAndLockFoo(const MyString& s)
3614 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3615
test()3616 static void test() {
3617 Foo* lt = GetAndLockFoo("foo");
3618 if (!lt) return;
3619 int a = lt->a;
3620 lt->mu_.Unlock();
3621 }
3622
3623 } // end namespace TrylockWithCleanups
3624
3625
3626 namespace UniversalLock {
3627
3628 class Foo {
3629 Mutex mu_;
3630 bool c;
3631
3632 int a GUARDED_BY(mu_);
3633 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3634 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3635
test1()3636 void test1() {
3637 int b;
3638
3639 beginNoWarnOnReads();
3640 b = a;
3641 r_foo();
3642 endNoWarnOnReads();
3643
3644 beginNoWarnOnWrites();
3645 a = 0;
3646 w_foo();
3647 endNoWarnOnWrites();
3648 }
3649
3650 // don't warn on joins with universal lock
test2()3651 void test2() {
3652 if (c) {
3653 beginNoWarnOnWrites();
3654 }
3655 a = 0; // \
3656 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3657 endNoWarnOnWrites(); // \
3658 // expected-warning {{releasing mutex '*' that was not held}}
3659 }
3660
3661
3662 // make sure the universal lock joins properly
test3()3663 void test3() {
3664 if (c) {
3665 mu_.Lock();
3666 beginNoWarnOnWrites();
3667 }
3668 else {
3669 beginNoWarnOnWrites();
3670 mu_.Lock();
3671 }
3672 a = 0;
3673 endNoWarnOnWrites();
3674 mu_.Unlock();
3675 }
3676
3677
3678 // combine universal lock with other locks
test4()3679 void test4() {
3680 beginNoWarnOnWrites();
3681 mu_.Lock();
3682 mu_.Unlock();
3683 endNoWarnOnWrites();
3684
3685 mu_.Lock();
3686 beginNoWarnOnWrites();
3687 endNoWarnOnWrites();
3688 mu_.Unlock();
3689
3690 mu_.Lock();
3691 beginNoWarnOnWrites();
3692 mu_.Unlock();
3693 endNoWarnOnWrites();
3694 }
3695 };
3696
3697 } // end namespace UniversalLock
3698
3699
3700 namespace TemplateLockReturned {
3701
3702 template<class T>
3703 class BaseT {
3704 public:
3705 virtual void baseMethod() = 0;
get_mutex()3706 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
3707
3708 Mutex mutex_;
3709 int a GUARDED_BY(mutex_);
3710 };
3711
3712
3713 class Derived : public BaseT<int> {
3714 public:
baseMethod()3715 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
3716 a = 0;
3717 }
3718 };
3719
3720 } // end namespace TemplateLockReturned
3721
3722
3723 namespace ExprMatchingBugFix {
3724
3725 class Foo {
3726 public:
3727 Mutex mu_;
3728 };
3729
3730
3731 class Bar {
3732 public:
3733 bool c;
3734 Foo* foo;
Bar(Foo * f)3735 Bar(Foo* f) : foo(f) { }
3736
3737 struct Nested {
3738 Foo* foo;
NestedExprMatchingBugFix::Bar::Nested3739 Nested(Foo* f) : foo(f) { }
3740
3741 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3742 };
3743
3744 void test();
3745 };
3746
3747
test()3748 void Bar::test() {
3749 foo->mu_.Lock();
3750 if (c) {
3751 Nested *n = new Nested(foo);
3752 n->unlockFoo();
3753 }
3754 else {
3755 foo->mu_.Unlock();
3756 }
3757 }
3758
3759 }; // end namespace ExprMatchingBugfix
3760
3761
3762 namespace ComplexNameTest {
3763
3764 class Foo {
3765 public:
3766 static Mutex mu_;
3767
EXCLUSIVE_LOCKS_REQUIRED(mu_)3768 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
EXCLUSIVE_LOCKS_REQUIRED(mu_)3769 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
3770
operator [](int i)3771 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
3772 };
3773
3774 class Bar {
3775 public:
3776 static Mutex mu_;
3777
LOCKS_EXCLUDED(mu_)3778 Bar() LOCKS_EXCLUDED(mu_) { }
LOCKS_EXCLUDED(mu_)3779 ~Bar() LOCKS_EXCLUDED(mu_) { }
3780
operator [](int i)3781 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
3782 };
3783
3784
test1()3785 void test1() {
3786 Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
3787 int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
3788 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
3789
3790
test2()3791 void test2() {
3792 Bar::mu_.Lock();
3793 {
3794 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
3795 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
3796 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
3797 Bar::mu_.Unlock();
3798 }
3799
3800 }; // end namespace ComplexNameTest
3801
3802
3803 namespace UnreachableExitTest {
3804
3805 class FemmeFatale {
3806 public:
3807 FemmeFatale();
3808 ~FemmeFatale() __attribute__((noreturn));
3809 };
3810
3811 void exitNow() __attribute__((noreturn));
3812 void exitDestruct(const MyString& ms) __attribute__((noreturn));
3813
3814 Mutex fatalmu_;
3815
test1()3816 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3817 exitNow();
3818 }
3819
test2()3820 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3821 FemmeFatale femme;
3822 }
3823
3824 bool c;
3825
test3()3826 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3827 if (c) {
3828 exitNow();
3829 }
3830 else {
3831 FemmeFatale femme;
3832 }
3833 }
3834
test4()3835 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3836 exitDestruct("foo");
3837 }
3838
3839 } // end namespace UnreachableExitTest
3840
3841
3842 namespace VirtualMethodCanonicalizationTest {
3843
3844 class Base {
3845 public:
3846 virtual Mutex* getMutex() = 0;
3847 };
3848
3849 class Base2 : public Base {
3850 public:
3851 Mutex* getMutex();
3852 };
3853
3854 class Base3 : public Base2 {
3855 public:
3856 Mutex* getMutex();
3857 };
3858
3859 class Derived : public Base3 {
3860 public:
3861 Mutex* getMutex(); // overrides Base::getMutex()
3862 };
3863
baseFun(Base * b)3864 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3865
derivedFun(Derived * d)3866 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3867 baseFun(d);
3868 }
3869
3870 } // end namespace VirtualMethodCanonicalizationTest
3871
3872
3873 namespace TemplateFunctionParamRemapTest {
3874
3875 template <class T>
3876 struct Cell {
3877 T dummy_;
3878 Mutex* mu_;
3879 };
3880
3881 class Foo {
3882 public:
3883 template <class T>
3884 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3885
3886 void test();
3887 };
3888
3889 template<class T>
elr(Cell<T> * c1)3890 void Foo::elr(Cell<T>* c1) { }
3891
test()3892 void Foo::test() {
3893 Cell<int> cell;
3894 elr(&cell); // \
3895 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}
3896 }
3897
3898
3899 template<class T>
3900 void globalELR(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3901
3902 template<class T>
globalELR(Cell<T> * c1)3903 void globalELR(Cell<T>* c1) { }
3904
globalTest()3905 void globalTest() {
3906 Cell<int> cell;
3907 globalELR(&cell); // \
3908 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}
3909 }
3910
3911
3912 template<class T>
3913 void globalELR2(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3914
3915 // second declaration
3916 template<class T>
3917 void globalELR2(Cell<T>* c2);
3918
3919 template<class T>
globalELR2(Cell<T> * c3)3920 void globalELR2(Cell<T>* c3) { }
3921
3922 // re-declaration after definition
3923 template<class T>
3924 void globalELR2(Cell<T>* c4);
3925
globalTest2()3926 void globalTest2() {
3927 Cell<int> cell;
3928 globalELR2(&cell); // \
3929 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}
3930 }
3931
3932
3933 template<class T>
3934 class FooT {
3935 public:
3936 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3937 };
3938
3939 template<class T>
elr(Cell<T> * c1)3940 void FooT<T>::elr(Cell<T>* c1) { }
3941
testFooT()3942 void testFooT() {
3943 Cell<int> cell;
3944 FooT<int> foo;
3945 foo.elr(&cell); // \
3946 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3947 }
3948
3949 } // end namespace TemplateFunctionParamRemapTest
3950
3951
3952 namespace SelfConstructorTest {
3953
3954 class SelfLock {
3955 public:
3956 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3957 ~SelfLock() UNLOCK_FUNCTION(mu_);
3958
3959 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3960
3961 Mutex mu_;
3962 };
3963
3964 class LOCKABLE SelfLock2 {
3965 public:
3966 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
3967 ~SelfLock2() UNLOCK_FUNCTION();
3968
3969 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3970 };
3971
3972
test()3973 void test() {
3974 SelfLock s;
3975 s.foo();
3976 }
3977
test2()3978 void test2() {
3979 SelfLock2 s2;
3980 s2.foo();
3981 }
3982
3983 } // end namespace SelfConstructorTest
3984
3985
3986 namespace MultipleAttributeTest {
3987
3988 class Foo {
3989 Mutex mu1_;
3990 Mutex mu2_;
3991 int a GUARDED_BY(mu1_);
3992 int b GUARDED_BY(mu2_);
3993 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_);
3994 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
3995
3996 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_)
3997 EXCLUSIVE_LOCKS_REQUIRED(mu2_);
3998 void foo2() SHARED_LOCKS_REQUIRED(mu1_)
3999 SHARED_LOCKS_REQUIRED(mu2_);
4000 void foo3() LOCKS_EXCLUDED(mu1_)
4001 LOCKS_EXCLUDED(mu2_);
4002 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
4003 EXCLUSIVE_LOCK_FUNCTION(mu2_);
4004 void readerlock() SHARED_LOCK_FUNCTION(mu1_)
4005 SHARED_LOCK_FUNCTION(mu2_);
4006 void unlock() UNLOCK_FUNCTION(mu1_)
4007 UNLOCK_FUNCTION(mu2_);
4008 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
4009 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
4010 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
4011 SHARED_TRYLOCK_FUNCTION(true, mu2_);
4012 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
4013 ASSERT_EXCLUSIVE_LOCK(mu2_);
4014
4015 void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);
4016
4017 void assertShared() ASSERT_SHARED_LOCK(mu1_)
4018 ASSERT_SHARED_LOCK(mu2_);
4019
4020 void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);
4021
4022 void test();
4023 void testAssert();
4024 void testAssertShared();
4025 };
4026
4027
foo1()4028 void Foo::foo1() {
4029 a = 1;
4030 b = 2;
4031 }
4032
foo2()4033 void Foo::foo2() {
4034 int result = a + b;
4035 }
4036
foo3()4037 void Foo::foo3() { }
lock()4038 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
readerlock()4039 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
unlock()4040 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
trylock()4041 bool Foo::trylock() { return true; }
readertrylock()4042 bool Foo::readertrylock() { return true; }
4043
4044
test()4045 void Foo::test() {
4046 mu1_.Lock();
4047 foo1(); // expected-warning {{}}
4048 c = 0; // expected-warning {{}}
4049 *d = 0; // expected-warning {{}}
4050 mu1_.Unlock();
4051
4052 mu1_.ReaderLock();
4053 foo2(); // expected-warning {{}}
4054 int x = c; // expected-warning {{}}
4055 int y = *d; // expected-warning {{}}
4056 mu1_.Unlock();
4057
4058 mu2_.Lock();
4059 foo3(); // expected-warning {{}}
4060 mu2_.Unlock();
4061
4062 lock();
4063 a = 0;
4064 b = 0;
4065 unlock();
4066
4067 readerlock();
4068 int z = a + b;
4069 unlock();
4070
4071 if (trylock()) {
4072 a = 0;
4073 b = 0;
4074 unlock();
4075 }
4076
4077 if (readertrylock()) {
4078 int zz = a + b;
4079 unlock();
4080 }
4081 }
4082
4083 // Force duplication of attributes
assertBoth()4084 void Foo::assertBoth() { }
alsoAssertBoth()4085 void Foo::alsoAssertBoth() { }
assertShared()4086 void Foo::assertShared() { }
alsoAssertShared()4087 void Foo::alsoAssertShared() { }
4088
testAssert()4089 void Foo::testAssert() {
4090 {
4091 assertBoth();
4092 a = 0;
4093 b = 0;
4094 }
4095 {
4096 alsoAssertBoth();
4097 a = 0;
4098 b = 0;
4099 }
4100 }
4101
testAssertShared()4102 void Foo::testAssertShared() {
4103 {
4104 assertShared();
4105 int zz = a + b;
4106 }
4107
4108 {
4109 alsoAssertShared();
4110 int zz = a + b;
4111 }
4112 }
4113
4114
4115 } // end namespace MultipleAttributeTest
4116
4117
4118 namespace GuardedNonPrimitiveTypeTest {
4119
4120
4121 class Data {
4122 public:
Data(int i)4123 Data(int i) : dat(i) { }
4124
getValue() const4125 int getValue() const { return dat; }
setValue(int i)4126 void setValue(int i) { dat = i; }
4127
operator [](int i) const4128 int operator[](int i) const { return dat; }
operator [](int i)4129 int& operator[](int i) { return dat; }
4130
operator ()()4131 void operator()() { }
4132
4133 private:
4134 int dat;
4135 };
4136
4137
4138 class DataCell {
4139 public:
DataCell(const Data & d)4140 DataCell(const Data& d) : dat(d) { }
4141
4142 private:
4143 Data dat;
4144 };
4145
4146
4147 void showDataCell(const DataCell& dc);
4148
4149
4150 class Foo {
4151 public:
4152 // method call tests
test()4153 void test() {
4154 data_.setValue(0); // FIXME -- should be writing \
4155 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4156 int a = data_.getValue(); // \
4157 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4158
4159 datap1_->setValue(0); // FIXME -- should be writing \
4160 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4161 a = datap1_->getValue(); // \
4162 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4163
4164 datap2_->setValue(0); // FIXME -- should be writing \
4165 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4166 a = datap2_->getValue(); // \
4167 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4168
4169 (*datap2_).setValue(0); // FIXME -- should be writing \
4170 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4171 a = (*datap2_).getValue(); // \
4172 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4173
4174 mu_.Lock();
4175 data_.setValue(1);
4176 datap1_->setValue(1);
4177 datap2_->setValue(1);
4178 mu_.Unlock();
4179
4180 mu_.ReaderLock();
4181 a = data_.getValue();
4182 datap1_->setValue(0); // reads datap1_, writes *datap1_
4183 a = datap1_->getValue();
4184 a = datap2_->getValue();
4185 mu_.Unlock();
4186 }
4187
4188 // operator tests
test2()4189 void test2() {
4190 data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4191 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
4192 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4193 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
4194 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4195 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4196 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4197 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4198 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4199
4200 data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4201 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4202
4203 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4204 }
4205
4206 // const operator tests
test3() const4207 void test3() const {
4208 Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4209
4210 //FIXME
4211 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4212 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4213
4214 int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4215 }
4216
4217 private:
4218 Mutex mu_;
4219 Data data_ GUARDED_BY(mu_);
4220 Data* datap1_ GUARDED_BY(mu_);
4221 Data* datap2_ PT_GUARDED_BY(mu_);
4222 };
4223
4224 } // end namespace GuardedNonPrimitiveTypeTest
4225
4226
4227 namespace GuardedNonPrimitive_MemberAccess {
4228
4229 class Cell {
4230 public:
4231 Cell(int i);
4232
4233 void cellMethod();
4234
4235 int a;
4236 };
4237
4238
4239 class Foo {
4240 public:
4241 int a;
4242 Cell c GUARDED_BY(cell_mu_);
4243 Cell* cp PT_GUARDED_BY(cell_mu_);
4244
4245 void myMethod();
4246
4247 Mutex cell_mu_;
4248 };
4249
4250
4251 class Bar {
4252 private:
4253 Mutex mu_;
4254 Foo foo GUARDED_BY(mu_);
4255 Foo* foop PT_GUARDED_BY(mu_);
4256
test()4257 void test() {
4258 foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4259
4260 int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4261 foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
4262
4263 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4264 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4265
4266 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4267 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4268
4269 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
4270 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
4271 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
4272 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
4273
4274 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4275 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4276 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4277 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4278
4279 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4280 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4281 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4282 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4283 };
4284 };
4285
4286 } // namespace GuardedNonPrimitive_MemberAccess
4287
4288
4289 namespace TestThrowExpr {
4290
4291 class Foo {
4292 Mutex mu_;
4293
4294 bool hasError();
4295
test()4296 void test() {
4297 mu_.Lock();
4298 if (hasError()) {
4299 throw "ugly";
4300 }
4301 mu_.Unlock();
4302 }
4303 };
4304
4305 } // end namespace TestThrowExpr
4306
4307
4308 namespace UnevaluatedContextTest {
4309
4310 // parse attribute expressions in an unevaluated context.
4311
4312 static inline Mutex* getMutex1();
4313 static inline Mutex* getMutex2();
4314
4315 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
4316
4317 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
4318
4319 } // end namespace UnevaluatedContextTest
4320
4321
4322 namespace LockUnlockFunctionTest {
4323
4324 // Check built-in lock functions
4325 class LOCKABLE MyLockable {
4326 public:
lock()4327 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
readerLock()4328 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
unlock()4329 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
4330
4331 private:
4332 Mutex mu_;
4333 };
4334
4335
4336 class Foo {
4337 public:
4338 // Correct lock/unlock functions
lock()4339 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4340 mu_.Lock();
4341 }
4342
readerLock()4343 void readerLock() SHARED_LOCK_FUNCTION(mu_) {
4344 mu_.ReaderLock();
4345 }
4346
unlock()4347 void unlock() UNLOCK_FUNCTION(mu_) {
4348 mu_.Unlock();
4349 }
4350
unlockExclusive()4351 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_) {
4352 mu_.Unlock();
4353 }
4354
unlockShared()4355 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_) {
4356 mu_.ReaderUnlock();
4357 }
4358
4359 // Check failure to lock.
lockBad()4360 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4361 mu2_.Lock();
4362 mu2_.Unlock();
4363 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4364
readerLockBad()4365 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4366 mu2_.Lock();
4367 mu2_.Unlock();
4368 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4369
unlockBad()4370 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4371 mu2_.Lock();
4372 mu2_.Unlock();
4373 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4374
4375 // Check locking the wrong thing.
lockBad2()4376 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4377 mu2_.Lock(); // expected-note {{mutex acquired here}}
4378 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4379 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4380
4381
readerLockBad2()4382 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4383 mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
4384 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4385 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4386
4387
unlockBad2()4388 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4389 mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
4390 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4391
4392 private:
4393 Mutex mu_;
4394 Mutex mu2_;
4395 };
4396
4397 } // end namespace LockUnlockFunctionTest
4398
4399
4400 namespace AssertHeldTest {
4401
4402 class Foo {
4403 public:
4404 int c;
4405 int a GUARDED_BY(mu_);
4406 Mutex mu_;
4407
test1()4408 void test1() {
4409 mu_.AssertHeld();
4410 int b = a;
4411 a = 0;
4412 }
4413
test2()4414 void test2() {
4415 mu_.AssertReaderHeld();
4416 int b = a;
4417 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4418 }
4419
test3()4420 void test3() {
4421 if (c) {
4422 mu_.AssertHeld();
4423 }
4424 else {
4425 mu_.AssertHeld();
4426 }
4427 int b = a;
4428 a = 0;
4429 }
4430
test4()4431 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4432 mu_.AssertHeld();
4433 int b = a;
4434 a = 0;
4435 }
4436
test5()4437 void test5() UNLOCK_FUNCTION(mu_) {
4438 mu_.AssertHeld();
4439 mu_.Unlock();
4440 }
4441
test6()4442 void test6() {
4443 mu_.AssertHeld();
4444 mu_.Unlock();
4445 } // should this be a warning?
4446
test7()4447 void test7() {
4448 if (c) {
4449 mu_.AssertHeld();
4450 }
4451 else {
4452 mu_.Lock();
4453 }
4454 int b = a;
4455 a = 0;
4456 mu_.Unlock();
4457 }
4458
test8()4459 void test8() {
4460 if (c) {
4461 mu_.Lock();
4462 }
4463 else {
4464 mu_.AssertHeld();
4465 }
4466 int b = a;
4467 a = 0;
4468 mu_.Unlock();
4469 }
4470
test9()4471 void test9() {
4472 if (c) {
4473 mu_.AssertHeld();
4474 }
4475 else {
4476 mu_.Lock(); // expected-note {{mutex acquired here}}
4477 }
4478 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4479
test10()4480 void test10() {
4481 if (c) {
4482 mu_.Lock(); // expected-note {{mutex acquired here}}
4483 }
4484 else {
4485 mu_.AssertHeld();
4486 }
4487 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4488
4489 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
4490
test11()4491 void test11() {
4492 assertMu();
4493 int b = a;
4494 a = 0;
4495 }
4496 };
4497
4498 } // end namespace AssertHeldTest
4499
4500
4501 namespace LogicalConditionalTryLock {
4502
4503 class Foo {
4504 public:
4505 Mutex mu;
4506 int a GUARDED_BY(mu);
4507 bool c;
4508
4509 bool newc();
4510
test1()4511 void test1() {
4512 if (c && mu.TryLock()) {
4513 a = 0;
4514 mu.Unlock();
4515 }
4516 }
4517
test2()4518 void test2() {
4519 bool b = mu.TryLock();
4520 if (c && b) {
4521 a = 0;
4522 mu.Unlock();
4523 }
4524 }
4525
test3()4526 void test3() {
4527 if (c || !mu.TryLock())
4528 return;
4529 a = 0;
4530 mu.Unlock();
4531 }
4532
test4()4533 void test4() {
4534 while (c && mu.TryLock()) {
4535 a = 0;
4536 c = newc();
4537 mu.Unlock();
4538 }
4539 }
4540
test5()4541 void test5() {
4542 while (c) {
4543 if (newc() || !mu.TryLock())
4544 break;
4545 a = 0;
4546 mu.Unlock();
4547 }
4548 }
4549
test6()4550 void test6() {
4551 mu.Lock();
4552 do {
4553 a = 0;
4554 mu.Unlock();
4555 } while (newc() && mu.TryLock());
4556 }
4557
test7()4558 void test7() {
4559 for (bool b = mu.TryLock(); c && b;) {
4560 a = 0;
4561 mu.Unlock();
4562 }
4563 }
4564
test8()4565 void test8() {
4566 if (c && newc() && mu.TryLock()) {
4567 a = 0;
4568 mu.Unlock();
4569 }
4570 }
4571
test9()4572 void test9() {
4573 if (!(c && newc() && mu.TryLock()))
4574 return;
4575 a = 0;
4576 mu.Unlock();
4577 }
4578
test10()4579 void test10() {
4580 if (!(c || !mu.TryLock())) {
4581 a = 0;
4582 mu.Unlock();
4583 }
4584 }
4585 };
4586
4587 } // end namespace LogicalConditionalTryLock
4588
4589
4590
4591 namespace PtGuardedByTest {
4592
4593 void doSomething();
4594
4595 class Cell {
4596 public:
4597 int a;
4598 };
4599
4600
4601 // This mainly duplicates earlier tests, but just to make sure...
4602 class PtGuardedBySanityTest {
4603 Mutex mu1;
4604 Mutex mu2;
4605 int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4606 Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4607 int sa[10] GUARDED_BY(mu1);
4608 Cell sc[10] GUARDED_BY(mu1);
4609
test1()4610 void test1() {
4611 mu1.Lock();
4612 if (a == 0) doSomething(); // OK, we don't dereference.
4613 a = 0;
4614 c = 0;
4615 if (sa[0] == 42) doSomething();
4616 sa[0] = 57;
4617 if (sc[0].a == 42) doSomething();
4618 sc[0].a = 57;
4619 mu1.Unlock();
4620 }
4621
test2()4622 void test2() {
4623 mu1.ReaderLock();
4624 if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4625 *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4626
4627 if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4628 c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4629
4630 if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4631 (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4632
4633 if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4634 a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4635 if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4636 c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4637 mu1.Unlock();
4638 }
4639
test3()4640 void test3() {
4641 mu2.Lock();
4642 if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4643 *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4644
4645 if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4646 c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4647
4648 if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4649 (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4650
4651 if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4652 a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4653 if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4654 c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4655 mu2.Unlock();
4656 }
4657
test4()4658 void test4() { // Literal arrays
4659 if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4660 sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4661 if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4662 sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4663
4664 if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4665 *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4666 if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4667 (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4668 if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4669 sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4670 }
4671
test5()4672 void test5() {
4673 mu1.ReaderLock(); // OK -- correct use.
4674 mu2.Lock();
4675 if (*a == 0) doSomething();
4676 *a = 0;
4677
4678 if (c->a == 0) doSomething();
4679 c->a = 0;
4680
4681 if ((*c).a == 0) doSomething();
4682 (*c).a = 0;
4683 mu2.Unlock();
4684 mu1.Unlock();
4685 }
4686 };
4687
4688
4689 class SmartPtr_PtGuardedBy_Test {
4690 Mutex mu1;
4691 Mutex mu2;
4692 SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4693 SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4694
test1()4695 void test1() {
4696 mu1.ReaderLock();
4697 mu2.Lock();
4698
4699 sp.get();
4700 if (*sp == 0) doSomething();
4701 *sp = 0;
4702 sq->a = 0;
4703
4704 if (sp[0] == 0) doSomething();
4705 sp[0] = 0;
4706
4707 mu2.Unlock();
4708 mu1.Unlock();
4709 }
4710
test2()4711 void test2() {
4712 mu2.Lock();
4713
4714 sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4715 if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4716 *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4717 sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4718
4719 if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4720 sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4721 if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4722 sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4723
4724 mu2.Unlock();
4725 }
4726
test3()4727 void test3() {
4728 mu1.Lock();
4729
4730 sp.get();
4731 if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4732 *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4733 sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4734
4735 if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4736 sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4737 if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4738 sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4739
4740 mu1.Unlock();
4741 }
4742 };
4743
4744 } // end namespace PtGuardedByTest
4745
4746
4747 namespace NonMemberCalleeICETest {
4748
4749 class A {
Run()4750 void Run() {
4751 (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
4752 }
4753
4754 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M);
4755 Mutex M;
4756 };
4757
4758 } // end namespace NonMemberCalleeICETest
4759
4760
4761 namespace pt_guard_attribute_type {
4762 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
4763 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
4764
test()4765 void test() {
4766 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
4767 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
4768
4769 typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}}
4770 typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}}
4771 }
4772 } // end namespace pt_guard_attribute_type
4773
4774
4775 namespace ThreadAttributesOnLambdas {
4776
4777 class Foo {
4778 Mutex mu_;
4779
4780 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4781
test()4782 void test() {
4783 auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4784 LockedFunction();
4785 };
4786
4787 auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
4788 LockedFunction();
4789 };
4790
4791 auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4792 mu_.Lock();
4793 };
4794
4795 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
4796 func2();
4797 func3();
4798 mu_.Unlock();
4799 }
4800 };
4801
4802 } // end namespace ThreadAttributesOnLambdas
4803
4804
4805
4806 namespace AttributeExpressionCornerCases {
4807
4808 class Foo {
4809 int a GUARDED_BY(getMu());
4810
4811 Mutex* getMu() LOCK_RETURNED("");
4812 Mutex* getUniv() LOCK_RETURNED("*");
4813
test1()4814 void test1() {
4815 a = 0;
4816 }
4817
test2()4818 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
4819 a = 0;
4820 }
4821
4822 void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);
4823
test3()4824 void test3() {
4825 foo(nullptr);
4826 }
4827 };
4828
4829
4830 class MapTest {
4831 struct MuCell { Mutex* mu; };
4832
4833 MyMap<MyString, Mutex*> map;
4834 MyMap<MyString, MuCell> mapCell;
4835
4836 int a GUARDED_BY(map["foo"]);
4837 int b GUARDED_BY(mapCell["foo"].mu);
4838
test()4839 void test() {
4840 map["foo"]->Lock();
4841 a = 0;
4842 map["foo"]->Unlock();
4843 }
4844
test2()4845 void test2() {
4846 mapCell["foo"].mu->Lock();
4847 b = 0;
4848 mapCell["foo"].mu->Unlock();
4849 }
4850 };
4851
4852
4853 class PreciseSmartPtr {
4854 SmartPtr<Mutex> mu;
4855 int val GUARDED_BY(mu);
4856
compare(PreciseSmartPtr & a,PreciseSmartPtr & b)4857 static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {
4858 a.mu->Lock();
4859 bool result = (a.val == b.val); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
4860 // expected-note {{found near match 'a.mu'}}
4861 a.mu->Unlock();
4862 return result;
4863 }
4864 };
4865
4866
4867 class SmartRedeclare {
4868 SmartPtr<Mutex> mu;
4869 int val GUARDED_BY(mu);
4870
4871 void test() EXCLUSIVE_LOCKS_REQUIRED(mu);
4872 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4873 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4874 };
4875
4876
test()4877 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {
4878 val = 0;
4879 }
4880
test2()4881 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {
4882 val = 0;
4883 }
4884
test3()4885 void SmartRedeclare::test3() {
4886 val = 0;
4887 }
4888
4889
4890 namespace CustomMutex {
4891
4892
4893 class LOCKABLE BaseMutex { };
4894 class DerivedMutex : public BaseMutex { };
4895
4896 void customLock(const BaseMutex *m) EXCLUSIVE_LOCK_FUNCTION(m);
4897 void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);
4898
4899 static struct DerivedMutex custMu;
4900
doSomethingRequiringLock()4901 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }
4902
customTest()4903 void customTest() {
4904 customLock(reinterpret_cast<BaseMutex*>(&custMu)); // ignore casts
4905 doSomethingRequiringLock();
4906 customUnlock(reinterpret_cast<BaseMutex*>(&custMu));
4907 }
4908
4909 } // end namespace CustomMutex
4910
4911 } // end AttributeExpressionCornerCases
4912
4913
4914 namespace ScopedLockReturnedInvalid {
4915
4916 class Opaque;
4917
4918 Mutex* getMutex(Opaque* o) LOCK_RETURNED("");
4919
test(Opaque * o)4920 void test(Opaque* o) {
4921 MutexLock lock(getMutex(o));
4922 }
4923
4924 } // end namespace ScopedLockReturnedInvalid
4925
4926
4927 namespace NegativeRequirements {
4928
4929 class Bar {
4930 Mutex mu;
4931 int a GUARDED_BY(mu);
4932
4933 public:
baz()4934 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4935 mu.Lock();
4936 a = 0;
4937 mu.Unlock();
4938 }
4939 };
4940
4941
4942 class Foo {
4943 Mutex mu;
4944 int a GUARDED_BY(mu);
4945
4946 public:
foo()4947 void foo() {
4948 mu.Lock(); // warning? needs !mu?
4949 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
4950 bar();
4951 mu.Unlock();
4952 }
4953
bar()4954 void bar() {
4955 bar2(); // expected-warning {{calling function 'bar2' requires holding '!mu'}}
4956 }
4957
bar2()4958 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4959 baz();
4960 }
4961
baz()4962 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4963 mu.Lock();
4964 a = 0;
4965 mu.Unlock();
4966 }
4967
test()4968 void test() {
4969 Bar b;
4970 b.baz(); // no warning -- in different class.
4971 }
4972 };
4973
4974 } // end namespace NegativeRequirements
4975
4976
4977 namespace NegativeThreadRoles {
4978
4979 typedef int __attribute__((capability("role"))) ThreadRole;
4980
acquire(ThreadRole R)4981 void acquire(ThreadRole R) EXCLUSIVE_LOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
release(ThreadRole R)4982 void release(ThreadRole R) UNLOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
4983
4984 ThreadRole FlightControl, Logger;
4985
4986 extern void enque_log_msg(const char *msg);
log_msg(const char * msg)4987 void log_msg(const char *msg) {
4988 enque_log_msg(msg);
4989 }
4990
dispatch_log(const char * msg)4991 void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}
dispatch_log2(const char * msg)4992 void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}
4993
flight_control_entry(void)4994 void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {
4995 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */
4996 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
4997 }
4998
spawn_fake_flight_control_thread(void)4999 void spawn_fake_flight_control_thread(void) {
5000 acquire(FlightControl);
5001 flight_control_entry();
5002 release(FlightControl);
5003 }
5004
5005 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
logger_entry(void)5006 void logger_entry(void) __attribute__((requires_capability(Logger))) {
5007 const char *msg;
5008
5009 while ((msg = deque_log_msg())) {
5010 dispatch_log(msg);
5011 }
5012 }
5013
spawn_fake_logger_thread(void)5014 void spawn_fake_logger_thread(void) {
5015 acquire(Logger);
5016 logger_entry();
5017 release(Logger);
5018 }
5019
main(void)5020 int main(void) {
5021 spawn_fake_flight_control_thread();
5022 spawn_fake_logger_thread();
5023
5024 for (;;)
5025 ; /* Pretend to dispatch things. */
5026
5027 return 0;
5028 }
5029
5030 } // end namespace NegativeThreadRoles
5031
5032
5033 namespace AssertSharedExclusive {
5034
5035 void doSomething();
5036
5037 class Foo {
5038 Mutex mu;
5039 int a GUARDED_BY(mu);
5040
test()5041 void test() SHARED_LOCKS_REQUIRED(mu) {
5042 mu.AssertHeld();
5043 if (a > 0)
5044 doSomething();
5045 }
5046 };
5047
5048 } // end namespace AssertSharedExclusive
5049
5050
5051 namespace RangeBasedForAndReferences {
5052
5053 class Foo {
5054 struct MyStruct {
5055 int a;
5056 };
5057
5058 Mutex mu;
5059 int a GUARDED_BY(mu);
5060 MyContainer<int> cntr GUARDED_BY(mu);
5061 MyStruct s GUARDED_BY(mu);
5062 int arr[10] GUARDED_BY(mu);
5063
nonref_test()5064 void nonref_test() {
5065 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5066 b = 0; // no warning
5067 }
5068
auto_test()5069 void auto_test() {
5070 auto b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5071 b = 0; // no warning
5072 auto &c = a; // no warning
5073 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5074 }
5075
ref_test()5076 void ref_test() {
5077 int &b = a;
5078 int &c = b;
5079 int &d = c;
5080 b = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5081 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5082 d = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5083
5084 MyStruct &rs = s;
5085 rs.a = 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
5086
5087 int (&rarr)[10] = arr;
5088 rarr[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
5089 }
5090
ptr_test()5091 void ptr_test() {
5092 int *b = &a;
5093 *b = 0; // no expected warning yet
5094 }
5095
for_test()5096 void for_test() {
5097 int total = 0;
5098 for (int i : cntr) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
5099 total += i;
5100 }
5101 }
5102 };
5103
5104
5105 } // end namespace RangeBasedForAndReferences
5106
5107
5108
5109 namespace PassByRefTest {
5110
5111 class Foo {
5112 public:
Foo()5113 Foo() : a(0), b(0) { }
5114
5115 int a;
5116 int b;
5117
5118 void operator+(const Foo& f);
5119
5120 void operator[](const Foo& g);
5121
5122 void operator()();
5123 };
5124
5125 template<class T>
5126 T&& mymove(T& f);
5127
5128
5129 // test top-level functions
5130 void copy(Foo f);
5131 void write1(Foo& f);
5132 void write2(int a, Foo& f);
5133 void read1(const Foo& f);
5134 void read2(int a, const Foo& f);
5135 void destroy(Foo&& f);
5136
5137 void operator/(const Foo& f, const Foo& g);
5138 void operator*(const Foo& f, const Foo& g);
5139
5140 // Test constructors.
5141 struct FooRead {
5142 FooRead(const Foo &);
5143 };
5144 struct FooWrite {
5145 FooWrite(Foo &);
5146 };
5147
5148 // Test variadic functions
5149 template<typename... T>
copyVariadic(T...)5150 void copyVariadic(T...) {}
5151 template<typename... T>
writeVariadic(T &...)5152 void writeVariadic(T&...) {}
5153 template<typename... T>
readVariadic(const T &...)5154 void readVariadic(const T&...) {}
5155
5156 void copyVariadicC(int, ...);
5157
5158 class Bar {
5159 public:
5160 Mutex mu;
5161 Foo foo GUARDED_BY(mu);
5162 Foo foo2 GUARDED_BY(mu);
5163 Foo* foop PT_GUARDED_BY(mu);
5164 SmartPtr<Foo> foosp PT_GUARDED_BY(mu);
5165
5166 // test methods.
5167 void mwrite1(Foo& f);
5168 void mwrite2(int a, Foo& f);
5169 void mread1(const Foo& f);
5170 void mread2(int a, const Foo& f);
5171
5172 // static methods
5173 static void smwrite1(Foo& f);
5174 static void smwrite2(int a, Foo& f);
5175 static void smread1(const Foo& f);
5176 static void smread2(int a, const Foo& f);
5177
5178 void operator<<(const Foo& f);
5179
test1()5180 void test1() {
5181 copy(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5182 write1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5183 write2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5184 read1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5185 read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5186 destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5187
5188 copyVariadic(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5189 readVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5190 writeVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5191 copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5192
5193 FooRead reader(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5194 FooWrite writer(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5195
5196 mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5197 mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5198 mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5199 mread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5200
5201 smwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5202 smwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5203 smread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5204 smread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5205
5206 foo + foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5207 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5208 foo / foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5209 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5210 foo * foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5211 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5212 foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5213 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5214 foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5215 (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5216
5217 copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
5218 write1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5219 write2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5220 read1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5221 read2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5222 destroy(mymove(*foop)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5223
5224 copy(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5225 write1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5226 write2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5227 read1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5228 read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5229 destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5230
5231 // TODO -- these require better smart pointer handling.
5232 copy(*foosp.get());
5233 write1(*foosp.get());
5234 write2(10, *foosp.get());
5235 read1(*foosp.get());
5236 read2(10, *foosp.get());
5237 destroy(mymove(*foosp.get()));
5238 }
5239 };
5240
5241
5242 } // end namespace PassByRefTest
5243
5244
5245 namespace AcquiredBeforeAfterText {
5246
5247 class Foo {
5248 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5249 Mutex mu2;
5250 Mutex mu3;
5251
test1()5252 void test1() {
5253 mu1.Lock();
5254 mu2.Lock();
5255 mu3.Lock();
5256
5257 mu3.Unlock();
5258 mu2.Unlock();
5259 mu1.Unlock();
5260 }
5261
test2()5262 void test2() {
5263 mu2.Lock();
5264 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5265 mu1.Unlock();
5266 mu2.Unlock();
5267 }
5268
test3()5269 void test3() {
5270 mu3.Lock();
5271 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5272 mu1.Unlock();
5273 mu3.Unlock();
5274 }
5275
test4()5276 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {
5277 mu2.Lock();
5278 mu2.Unlock();
5279 }
5280
test5()5281 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5282 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5283 mu1.Unlock();
5284 }
5285
test6()5286 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5287 mu1.AssertHeld();
5288 }
5289
test7()5290 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }
5291
test8()5292 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }
5293 };
5294
5295
5296 class Foo2 {
5297 Mutex mu1;
5298 Mutex mu2 ACQUIRED_AFTER(mu1);
5299 Mutex mu3 ACQUIRED_AFTER(mu1);
5300
test1()5301 void test1() {
5302 mu1.Lock();
5303 mu2.Lock();
5304 mu3.Lock();
5305
5306 mu3.Unlock();
5307 mu2.Unlock();
5308 mu1.Unlock();
5309 }
5310
test2()5311 void test2() {
5312 mu2.Lock();
5313 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5314 mu1.Unlock();
5315 mu2.Unlock();
5316 }
5317
test3()5318 void test3() {
5319 mu3.Lock();
5320 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5321 mu1.Unlock();
5322 mu3.Unlock();
5323 }
5324 };
5325
5326
5327 class Foo3 {
5328 Mutex mu1 ACQUIRED_BEFORE(mu2);
5329 Mutex mu2;
5330 Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);
5331 Mutex mu4;
5332
test1()5333 void test1() {
5334 mu1.Lock();
5335 mu2.Lock();
5336 mu3.Lock();
5337 mu4.Lock();
5338
5339 mu4.Unlock();
5340 mu3.Unlock();
5341 mu2.Unlock();
5342 mu1.Unlock();
5343 }
5344
test2()5345 void test2() {
5346 mu4.Lock();
5347 mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
5348
5349 mu2.Unlock();
5350 mu4.Unlock();
5351 }
5352
test3()5353 void test3() {
5354 mu4.Lock();
5355 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
5356
5357 mu1.Unlock();
5358 mu4.Unlock();
5359 }
5360
test4()5361 void test4() {
5362 mu3.Lock();
5363 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5364
5365 mu1.Unlock();
5366 mu3.Unlock();
5367 }
5368 };
5369
5370
5371 // Test transitive DAG traversal with AFTER
5372 class Foo4 {
5373 Mutex mu1;
5374 Mutex mu2 ACQUIRED_AFTER(mu1);
5375 Mutex mu3 ACQUIRED_AFTER(mu1);
5376 Mutex mu4 ACQUIRED_AFTER(mu2, mu3);
5377 Mutex mu5 ACQUIRED_AFTER(mu4);
5378 Mutex mu6 ACQUIRED_AFTER(mu4);
5379 Mutex mu7 ACQUIRED_AFTER(mu5, mu6);
5380 Mutex mu8 ACQUIRED_AFTER(mu7);
5381
test()5382 void test() {
5383 mu8.Lock();
5384 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5385 mu1.Unlock();
5386 mu8.Unlock();
5387 }
5388 };
5389
5390
5391 // Test transitive DAG traversal with BEFORE
5392 class Foo5 {
5393 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5394 Mutex mu2 ACQUIRED_BEFORE(mu4);
5395 Mutex mu3 ACQUIRED_BEFORE(mu4);
5396 Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);
5397 Mutex mu5 ACQUIRED_BEFORE(mu7);
5398 Mutex mu6 ACQUIRED_BEFORE(mu7);
5399 Mutex mu7 ACQUIRED_BEFORE(mu8);
5400 Mutex mu8;
5401
test()5402 void test() {
5403 mu8.Lock();
5404 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5405 mu1.Unlock();
5406 mu8.Unlock();
5407 }
5408 };
5409
5410
5411 class Foo6 {
5412 Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}}
5413 Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}}
5414 Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}}
5415
5416 Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}}
5417 Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}}
5418
test0()5419 void test0() {
5420 mu_a.Lock();
5421 mu_b.Lock();
5422 mu_b.Unlock();
5423 mu_a.Unlock();
5424 }
5425
test1a()5426 void test1a() {
5427 mu1.Lock();
5428 mu1.Unlock();
5429 }
5430
test1b()5431 void test1b() {
5432 mu1.Lock();
5433 mu_a.Lock();
5434 mu_b.Lock();
5435 mu_b.Unlock();
5436 mu_a.Unlock();
5437 mu1.Unlock();
5438 }
5439
test()5440 void test() {
5441 mu2.Lock();
5442 mu2.Unlock();
5443 }
5444
test3()5445 void test3() {
5446 mu3.Lock();
5447 mu3.Unlock();
5448 }
5449 };
5450
5451 } // end namespace AcquiredBeforeAfterTest
5452
5453
5454 namespace ScopedAdoptTest {
5455
5456 class Foo {
5457 Mutex mu;
5458 int a GUARDED_BY(mu);
5459 int b;
5460
test1()5461 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {
5462 MutexLock slock(&mu, true);
5463 a = 0;
5464 }
5465
test2()5466 void test2() SHARED_UNLOCK_FUNCTION(mu) {
5467 ReaderMutexLock slock(&mu, true);
5468 b = a;
5469 }
5470
test3()5471 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5472 MutexLock slock(&mu, true);
5473 a = 0;
5474 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5475
test4()5476 void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5477 ReaderMutexLock slock(&mu, true);
5478 b = a;
5479 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5480
5481 };
5482
5483 } // end namespace ScopedAdoptTest
5484
5485
5486 namespace TestReferenceNoThreadSafetyAnalysis {
5487
5488 #define TS_UNCHECKED_READ(x) ts_unchecked_read(x)
5489
5490 // Takes a reference to a guarded data member, and returns an unguarded
5491 // reference.
5492 template <class T>
ts_unchecked_read(const T & v)5493 inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
5494 return v;
5495 }
5496
5497 template <class T>
ts_unchecked_read(T & v)5498 inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
5499 return v;
5500 }
5501
5502
5503 class Foo {
5504 public:
Foo()5505 Foo(): a(0) { }
5506
5507 int a;
5508 };
5509
5510
5511 class Bar {
5512 public:
Bar()5513 Bar() : a(0) { }
5514
5515 Mutex mu;
5516 int a GUARDED_BY(mu);
5517 Foo foo GUARDED_BY(mu);
5518 };
5519
5520
test()5521 void test() {
5522 Bar bar;
5523 const Bar cbar;
5524
5525 int a = TS_UNCHECKED_READ(bar.a); // nowarn
5526 TS_UNCHECKED_READ(bar.a) = 1; // nowarn
5527
5528 int b = TS_UNCHECKED_READ(bar.foo).a; // nowarn
5529 TS_UNCHECKED_READ(bar.foo).a = 1; // nowarn
5530
5531 int c = TS_UNCHECKED_READ(cbar.a); // nowarn
5532 }
5533
5534 #undef TS_UNCHECKED_READ
5535
5536 } // end namespace TestReferenceNoThreadSafetyAnalysis
5537
5538
5539 namespace GlobalAcquiredBeforeAfterTest {
5540
5541 Mutex mu1;
5542 Mutex mu2 ACQUIRED_AFTER(mu1);
5543
test3()5544 void test3() {
5545 mu2.Lock();
5546 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5547 mu1.Unlock();
5548 mu2.Unlock();
5549 }
5550
5551 } // end namespace GlobalAcquiredBeforeAfterTest
5552
5553
5554 namespace LifetimeExtensionText {
5555
5556 struct Holder {
~HolderLifetimeExtensionText::Holder5557 virtual ~Holder() throw() {}
5558 int i = 0;
5559 };
5560
test()5561 void test() {
5562 // Should not crash.
5563 const auto &value = Holder().i;
5564 }
5565
5566 } // end namespace LifetimeExtensionTest
5567
5568
5569 namespace LockableUnions {
5570
5571 union LOCKABLE MutexUnion {
5572 int a;
5573 char* b;
5574
5575 void Lock() EXCLUSIVE_LOCK_FUNCTION();
5576 void Unlock() UNLOCK_FUNCTION();
5577 };
5578
5579 MutexUnion muun2;
5580 MutexUnion muun1 ACQUIRED_BEFORE(muun2);
5581
test()5582 void test() {
5583 muun2.Lock();
5584 muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
5585 muun1.Unlock();
5586 muun2.Unlock();
5587 }
5588
5589 } // end namespace LockableUnions
5590
5591 // This used to crash.
5592 class acquired_before_empty_str {
WaitUntilSpaceAvailable()5593 void WaitUntilSpaceAvailable() {
5594 lock_.ReaderLock(); // expected-note {{acquired here}}
5595 } // expected-warning {{mutex 'lock_' is still held at the end of function}}
5596 Mutex lock_ ACQUIRED_BEFORE("");
5597 };
5598
5599 namespace PR34800 {
5600 struct A {
5601 operator int() const;
5602 };
5603 struct B {
5604 bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
5605 int h;
5606 };
5607 struct C {
5608 B *operator[](int);
5609 };
5610 C c;
f()5611 void f() { c[A()]->g(); }
5612 } // namespace PR34800
5613
5614 namespace ReturnScopedLockable {
5615 template<typename Object> class SCOPED_LOCKABLE ReadLockedPtr {
5616 public:
5617 ReadLockedPtr(Object *ptr) SHARED_LOCK_FUNCTION((*this)->mutex);
5618 ReadLockedPtr(ReadLockedPtr &&) SHARED_LOCK_FUNCTION((*this)->mutex);
5619 ~ReadLockedPtr() UNLOCK_FUNCTION();
5620
operator ->() const5621 Object *operator->() const { return object; }
5622
5623 private:
5624 Object *object;
5625 };
5626
5627 struct Object {
5628 int f() SHARED_LOCKS_REQUIRED(mutex);
5629 Mutex mutex;
5630 };
5631
5632 ReadLockedPtr<Object> get();
use()5633 int use() {
5634 auto ptr = get();
5635 return ptr->f();
5636 }
5637 }
5638
5639 namespace PR38640 {
f()5640 void f() {
5641 // Self-referencing assignment previously caused an infinite loop when thread
5642 // safety analysis was enabled.
5643 int &i = i; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}}
5644 }
5645 }
5646
5647 namespace Derived_Smart_Pointer {
5648 template <class T>
5649 class SmartPtr_Derived : public SmartPtr<T> {};
5650
5651 class Foo {
5652 public:
5653 SmartPtr_Derived<Mutex> mu_;
5654 int a GUARDED_BY(mu_);
5655 int b GUARDED_BY(mu_.get());
5656 int c GUARDED_BY(*mu_);
5657
5658 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
5659 void Unlock() UNLOCK_FUNCTION(mu_);
5660
test0()5661 void test0() {
5662 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
5663 b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
5664 c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
5665 }
5666
test1()5667 void test1() {
5668 Lock();
5669 a = 1;
5670 b = 1;
5671 c = 1;
5672 Unlock();
5673 }
5674 };
5675
5676 class Bar {
5677 SmartPtr_Derived<Foo> foo;
5678
test0()5679 void test0() {
5680 foo->a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
5681 (*foo).b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
5682 foo.get()->c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
5683 }
5684
test1()5685 void test1() {
5686 foo->Lock();
5687 foo->a = 1;
5688 foo->Unlock();
5689
5690 foo->mu_->Lock();
5691 foo->b = 1;
5692 foo->mu_->Unlock();
5693
5694 MutexLock lock(foo->mu_.get());
5695 foo->c = 1;
5696 }
5697 };
5698
5699 class PointerGuard {
5700 Mutex mu1;
5701 Mutex mu2;
5702 SmartPtr_Derived<int> i GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
5703
test0()5704 void test0() {
5705 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5706 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \
5707 // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
5708
5709 }
5710
test1()5711 void test1() {
5712 mu1.Lock();
5713
5714 i.get();
5715 *i = 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
5716
5717 mu1.Unlock();
5718 }
5719
test2()5720 void test2() {
5721 mu2.Lock();
5722
5723 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5724 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5725
5726 mu2.Unlock();
5727 }
5728
test3()5729 void test3() {
5730 mu1.Lock();
5731 mu2.Lock();
5732
5733 i.get();
5734 *i = 2;
5735
5736 mu2.Unlock();
5737 mu1.Unlock();
5738 }
5739 };
5740 }
5741