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 #ifdef __cpp_guaranteed_copy_elision
3055
guaranteed_copy_elision()3056 void guaranteed_copy_elision() {
3057 MutexLock lock = MutexLock{&sls_mu};
3058 sls_guard_var = 0;
3059 }
3060
guaranteed_copy_elision_const()3061 void guaranteed_copy_elision_const() {
3062 const MutexLock lock = MutexLock{&sls_mu};
3063 sls_guard_var = 0;
3064 }
3065
3066 #endif
3067
3068 } // end namespace TemporaryCleanupExpr
3069
3070
3071
3072 namespace SmartPointerTests {
3073
3074 class Foo {
3075 public:
3076 SmartPtr<Mutex> mu_;
3077 int a GUARDED_BY(mu_);
3078 int b GUARDED_BY(mu_.get());
3079 int c GUARDED_BY(*mu_);
3080
3081 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3082 void Unlock() UNLOCK_FUNCTION(mu_);
3083
3084 void test0();
3085 void test1();
3086 void test2();
3087 void test3();
3088 void test4();
3089 void test5();
3090 void test6();
3091 void test7();
3092 void test8();
3093 };
3094
test0()3095 void Foo::test0() {
3096 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3097 b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
3098 c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
3099 }
3100
test1()3101 void Foo::test1() {
3102 mu_->Lock();
3103 a = 0;
3104 b = 0;
3105 c = 0;
3106 mu_->Unlock();
3107 }
3108
test2()3109 void Foo::test2() {
3110 (*mu_).Lock();
3111 a = 0;
3112 b = 0;
3113 c = 0;
3114 (*mu_).Unlock();
3115 }
3116
3117
test3()3118 void Foo::test3() {
3119 mu_.get()->Lock();
3120 a = 0;
3121 b = 0;
3122 c = 0;
3123 mu_.get()->Unlock();
3124 }
3125
3126
test4()3127 void Foo::test4() {
3128 MutexLock lock(mu_.get());
3129 a = 0;
3130 b = 0;
3131 c = 0;
3132 }
3133
3134
test5()3135 void Foo::test5() {
3136 MutexLock lock(&(*mu_));
3137 a = 0;
3138 b = 0;
3139 c = 0;
3140 }
3141
3142
test6()3143 void Foo::test6() {
3144 Lock();
3145 a = 0;
3146 b = 0;
3147 c = 0;
3148 Unlock();
3149 }
3150
3151
test7()3152 void Foo::test7() {
3153 {
3154 Lock();
3155 mu_->Unlock();
3156 }
3157 {
3158 mu_->Lock();
3159 Unlock();
3160 }
3161 {
3162 mu_.get()->Lock();
3163 mu_->Unlock();
3164 }
3165 {
3166 mu_->Lock();
3167 mu_.get()->Unlock();
3168 }
3169 {
3170 mu_.get()->Lock();
3171 (*mu_).Unlock();
3172 }
3173 {
3174 (*mu_).Lock();
3175 mu_->Unlock();
3176 }
3177 }
3178
3179
test8()3180 void Foo::test8() {
3181 mu_->Lock(); // expected-note 2 {{mutex acquired here}}
3182 mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3183 (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
3184 mu_.get()->Unlock();
3185 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
3186 }
3187
3188
3189 class Bar {
3190 SmartPtr<Foo> foo;
3191
3192 void test0();
3193 void test1();
3194 void test2();
3195 void test3();
3196 };
3197
3198
test0()3199 void Bar::test0() {
3200 foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
3201 (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
3202 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
3203 }
3204
3205
test1()3206 void Bar::test1() {
3207 foo->mu_->Lock();
3208 foo->a = 0;
3209 (*foo).b = 0;
3210 foo.get()->c = 0;
3211 foo->mu_->Unlock();
3212 }
3213
3214
test2()3215 void Bar::test2() {
3216 (*foo).mu_->Lock();
3217 foo->a = 0;
3218 (*foo).b = 0;
3219 foo.get()->c = 0;
3220 foo.get()->mu_->Unlock();
3221 }
3222
3223
test3()3224 void Bar::test3() {
3225 MutexLock lock(foo->mu_.get());
3226 foo->a = 0;
3227 (*foo).b = 0;
3228 foo.get()->c = 0;
3229 }
3230
3231 } // end namespace SmartPointerTests
3232
3233
3234
3235 namespace DuplicateAttributeTest {
3236
3237 class LOCKABLE Foo {
3238 public:
3239 Mutex mu1_;
3240 Mutex mu2_;
3241 Mutex mu3_;
3242 int a GUARDED_BY(mu1_);
3243 int b GUARDED_BY(mu2_);
3244 int c GUARDED_BY(mu3_);
3245
3246 void lock() EXCLUSIVE_LOCK_FUNCTION();
3247 void unlock() UNLOCK_FUNCTION();
3248
3249 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
3250 void slock1() SHARED_LOCK_FUNCTION(mu1_);
3251 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3252 void locklots()
3253 EXCLUSIVE_LOCK_FUNCTION(mu1_)
3254 EXCLUSIVE_LOCK_FUNCTION(mu2_)
3255 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
3256
3257 void unlock1() UNLOCK_FUNCTION(mu1_);
3258 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3259 void unlocklots()
3260 UNLOCK_FUNCTION(mu1_)
3261 UNLOCK_FUNCTION(mu2_)
3262 UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
3263 };
3264
3265
lock()3266 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
unlock()3267 void Foo::unlock() UNLOCK_FUNCTION() { }
3268
lock1()3269 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
3270 mu1_.Lock();
3271 }
3272
slock1()3273 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
3274 mu1_.ReaderLock();
3275 }
3276
lock3()3277 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
3278 mu1_.Lock();
3279 mu2_.Lock();
3280 mu3_.Lock();
3281 }
3282
locklots()3283 void Foo::locklots()
3284 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
3285 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
3286 mu1_.Lock();
3287 mu2_.Lock();
3288 mu3_.Lock();
3289 }
3290
unlock1()3291 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
3292 mu1_.Unlock();
3293 }
3294
unlock3()3295 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
3296 mu1_.Unlock();
3297 mu2_.Unlock();
3298 mu3_.Unlock();
3299 }
3300
unlocklots()3301 void Foo::unlocklots()
3302 UNLOCK_FUNCTION(mu1_, mu2_)
3303 UNLOCK_FUNCTION(mu2_, mu3_) {
3304 mu1_.Unlock();
3305 mu2_.Unlock();
3306 mu3_.Unlock();
3307 }
3308
3309
test0()3310 void test0() {
3311 Foo foo;
3312 foo.lock();
3313 foo.unlock();
3314
3315 foo.lock(); // expected-note{{mutex acquired here}}
3316 foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
3317 foo.unlock();
3318 foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
3319 }
3320
3321
test1()3322 void test1() {
3323 Foo foo;
3324 foo.lock1();
3325 foo.a = 0;
3326 foo.unlock1();
3327
3328 foo.lock1(); // expected-note{{mutex acquired here}}
3329 foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3330 foo.a = 0;
3331 foo.unlock1();
3332 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3333 }
3334
3335
test2()3336 int test2() {
3337 Foo foo;
3338 foo.slock1();
3339 int d1 = foo.a;
3340 foo.unlock1();
3341
3342 foo.slock1(); // expected-note{{mutex acquired here}}
3343 foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
3344 int d2 = foo.a;
3345 foo.unlock1();
3346 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
3347 return d1 + d2;
3348 }
3349
3350
test3()3351 void test3() {
3352 Foo foo;
3353 foo.lock3();
3354 foo.a = 0;
3355 foo.b = 0;
3356 foo.c = 0;
3357 foo.unlock3();
3358
3359 foo.lock3(); // expected-note 3 {{mutex acquired here}}
3360 foo.lock3(); // \
3361 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3362 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3363 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3364 foo.a = 0;
3365 foo.b = 0;
3366 foo.c = 0;
3367 foo.unlock3();
3368 foo.unlock3(); // \
3369 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3370 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3371 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3372 }
3373
3374
testlots()3375 void testlots() {
3376 Foo foo;
3377 foo.locklots();
3378 foo.a = 0;
3379 foo.b = 0;
3380 foo.c = 0;
3381 foo.unlocklots();
3382
3383 foo.locklots(); // expected-note 3 {{mutex acquired here}}
3384 foo.locklots(); // \
3385 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
3386 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
3387 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
3388 foo.a = 0;
3389 foo.b = 0;
3390 foo.c = 0;
3391 foo.unlocklots();
3392 foo.unlocklots(); // \
3393 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
3394 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
3395 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
3396 }
3397
3398 } // end namespace DuplicateAttributeTest
3399
3400
3401
3402 namespace TryLockEqTest {
3403
3404 class Foo {
3405 Mutex mu_;
3406 int a GUARDED_BY(mu_);
3407 bool c;
3408
3409 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3410 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
3411 void unlock() UNLOCK_FUNCTION(mu_);
3412
3413 void test1();
3414 void test2();
3415 };
3416
3417
test1()3418 void Foo::test1() {
3419 if (tryLockMutexP() == 0) {
3420 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3421 return;
3422 }
3423 a = 0;
3424 unlock();
3425
3426 if (tryLockMutexP() != 0) {
3427 a = 0;
3428 unlock();
3429 }
3430
3431 if (0 != tryLockMutexP()) {
3432 a = 0;
3433 unlock();
3434 }
3435
3436 if (!(tryLockMutexP() == 0)) {
3437 a = 0;
3438 unlock();
3439 }
3440
3441 if (tryLockMutexI() == 0) {
3442 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3443 return;
3444 }
3445 a = 0;
3446 unlock();
3447
3448 if (0 == tryLockMutexI()) {
3449 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3450 return;
3451 }
3452 a = 0;
3453 unlock();
3454
3455 if (tryLockMutexI() == 1) {
3456 a = 0;
3457 unlock();
3458 }
3459
3460 if (mu_.TryLock() == false) {
3461 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3462 return;
3463 }
3464 a = 0;
3465 unlock();
3466
3467 if (mu_.TryLock() == true) {
3468 a = 0;
3469 unlock();
3470 }
3471 else {
3472 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3473 }
3474
3475 #if __has_feature(cxx_nullptr)
3476 if (tryLockMutexP() == nullptr) {
3477 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3478 return;
3479 }
3480 a = 0;
3481 unlock();
3482 #endif
3483 }
3484
3485 } // end namespace TryLockEqTest
3486
3487
3488 namespace ExistentialPatternMatching {
3489
3490 class Graph {
3491 public:
3492 Mutex mu_;
3493 };
3494
3495 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
3496 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
3497
3498 class Node {
3499 public:
3500 int a GUARDED_BY(&Graph::mu_);
3501
foo()3502 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
3503 a = 0;
3504 }
3505 void foo2() LOCKS_EXCLUDED(&Graph::mu_);
3506 };
3507
test()3508 void test() {
3509 Graph g1;
3510 Graph g2;
3511 Node n1;
3512
3513 n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3514 n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
3515 n1.foo2();
3516
3517 g1.mu_.Lock();
3518 n1.a = 0;
3519 n1.foo();
3520 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3521 g1.mu_.Unlock();
3522
3523 g2.mu_.Lock();
3524 n1.a = 0;
3525 n1.foo();
3526 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3527 g2.mu_.Unlock();
3528
3529 LockAllGraphs();
3530 n1.a = 0;
3531 n1.foo();
3532 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
3533 UnlockAllGraphs();
3534
3535 LockAllGraphs();
3536 g1.mu_.Unlock();
3537
3538 LockAllGraphs();
3539 g2.mu_.Unlock();
3540
3541 LockAllGraphs(); // expected-note{{mutex acquired here}}
3542 g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
3543 g1.mu_.Unlock();
3544 }
3545
3546 } // end namespace ExistentialPatternMatching
3547
3548
3549 namespace StringIgnoreTest {
3550
3551 class Foo {
3552 public:
3553 Mutex mu_;
3554 void lock() EXCLUSIVE_LOCK_FUNCTION("");
3555 void unlock() UNLOCK_FUNCTION("");
3556 void goober() EXCLUSIVE_LOCKS_REQUIRED("");
3557 void roober() SHARED_LOCKS_REQUIRED("");
3558 };
3559
3560
3561 class Bar : public Foo {
3562 public:
bar(Foo * f)3563 void bar(Foo* f) {
3564 f->unlock();
3565 f->goober();
3566 f->roober();
3567 f->lock();
3568 };
3569 };
3570
3571 } // end namespace StringIgnoreTest
3572
3573
3574 namespace LockReturnedScopeFix {
3575
3576 class Base {
3577 protected:
3578 struct Inner;
3579 bool c;
3580
3581 const Mutex& getLock(const Inner* i);
3582
3583 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i));
3584 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i));
3585 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i));
3586
3587 void bar(Inner* i);
3588 };
3589
3590
3591 struct Base::Inner {
3592 Mutex lock_;
3593 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_);
3594 };
3595
3596
getLock(const Inner * i)3597 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) {
3598 return i->lock_;
3599 }
3600
3601
foo(Inner * i)3602 void Base::foo(Inner* i) {
3603 i->doSomething();
3604 }
3605
bar(Inner * i)3606 void Base::bar(Inner* i) {
3607 if (c) {
3608 i->lock_.Lock();
3609 unlockInner(i);
3610 }
3611 else {
3612 lockInner(i);
3613 i->lock_.Unlock();
3614 }
3615 }
3616
3617 } // end namespace LockReturnedScopeFix
3618
3619
3620 namespace TrylockWithCleanups {
3621
3622 struct Foo {
3623 Mutex mu_;
3624 int a GUARDED_BY(mu_);
3625 };
3626
3627 Foo* GetAndLockFoo(const MyString& s)
3628 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_);
3629
test()3630 static void test() {
3631 Foo* lt = GetAndLockFoo("foo");
3632 if (!lt) return;
3633 int a = lt->a;
3634 lt->mu_.Unlock();
3635 }
3636
3637 } // end namespace TrylockWithCleanups
3638
3639
3640 namespace UniversalLock {
3641
3642 class Foo {
3643 Mutex mu_;
3644 bool c;
3645
3646 int a GUARDED_BY(mu_);
3647 void r_foo() SHARED_LOCKS_REQUIRED(mu_);
3648 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3649
test1()3650 void test1() {
3651 int b;
3652
3653 beginNoWarnOnReads();
3654 b = a;
3655 r_foo();
3656 endNoWarnOnReads();
3657
3658 beginNoWarnOnWrites();
3659 a = 0;
3660 w_foo();
3661 endNoWarnOnWrites();
3662 }
3663
3664 // don't warn on joins with universal lock
test2()3665 void test2() {
3666 if (c) {
3667 beginNoWarnOnWrites();
3668 }
3669 a = 0; // \
3670 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
3671 endNoWarnOnWrites(); // \
3672 // expected-warning {{releasing mutex '*' that was not held}}
3673 }
3674
3675
3676 // make sure the universal lock joins properly
test3()3677 void test3() {
3678 if (c) {
3679 mu_.Lock();
3680 beginNoWarnOnWrites();
3681 }
3682 else {
3683 beginNoWarnOnWrites();
3684 mu_.Lock();
3685 }
3686 a = 0;
3687 endNoWarnOnWrites();
3688 mu_.Unlock();
3689 }
3690
3691
3692 // combine universal lock with other locks
test4()3693 void test4() {
3694 beginNoWarnOnWrites();
3695 mu_.Lock();
3696 mu_.Unlock();
3697 endNoWarnOnWrites();
3698
3699 mu_.Lock();
3700 beginNoWarnOnWrites();
3701 endNoWarnOnWrites();
3702 mu_.Unlock();
3703
3704 mu_.Lock();
3705 beginNoWarnOnWrites();
3706 mu_.Unlock();
3707 endNoWarnOnWrites();
3708 }
3709 };
3710
3711 } // end namespace UniversalLock
3712
3713
3714 namespace TemplateLockReturned {
3715
3716 template<class T>
3717 class BaseT {
3718 public:
3719 virtual void baseMethod() = 0;
get_mutex()3720 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; }
3721
3722 Mutex mutex_;
3723 int a GUARDED_BY(mutex_);
3724 };
3725
3726
3727 class Derived : public BaseT<int> {
3728 public:
baseMethod()3729 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) {
3730 a = 0;
3731 }
3732 };
3733
3734 } // end namespace TemplateLockReturned
3735
3736
3737 namespace ExprMatchingBugFix {
3738
3739 class Foo {
3740 public:
3741 Mutex mu_;
3742 };
3743
3744
3745 class Bar {
3746 public:
3747 bool c;
3748 Foo* foo;
Bar(Foo * f)3749 Bar(Foo* f) : foo(f) { }
3750
3751 struct Nested {
3752 Foo* foo;
NestedExprMatchingBugFix::Bar::Nested3753 Nested(Foo* f) : foo(f) { }
3754
3755 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_);
3756 };
3757
3758 void test();
3759 };
3760
3761
test()3762 void Bar::test() {
3763 foo->mu_.Lock();
3764 if (c) {
3765 Nested *n = new Nested(foo);
3766 n->unlockFoo();
3767 }
3768 else {
3769 foo->mu_.Unlock();
3770 }
3771 }
3772
3773 }; // end namespace ExprMatchingBugfix
3774
3775
3776 namespace ComplexNameTest {
3777
3778 class Foo {
3779 public:
3780 static Mutex mu_;
3781
EXCLUSIVE_LOCKS_REQUIRED(mu_)3782 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
EXCLUSIVE_LOCKS_REQUIRED(mu_)3783 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
3784
operator [](int i)3785 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; }
3786 };
3787
3788 class Bar {
3789 public:
3790 static Mutex mu_;
3791
LOCKS_EXCLUDED(mu_)3792 Bar() LOCKS_EXCLUDED(mu_) { }
LOCKS_EXCLUDED(mu_)3793 ~Bar() LOCKS_EXCLUDED(mu_) { }
3794
operator [](int i)3795 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; }
3796 };
3797
3798
test1()3799 void test1() {
3800 Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
3801 int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
3802 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
3803
3804
test2()3805 void test2() {
3806 Bar::mu_.Lock();
3807 {
3808 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
3809 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
3810 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
3811 Bar::mu_.Unlock();
3812 }
3813
3814 }; // end namespace ComplexNameTest
3815
3816
3817 namespace UnreachableExitTest {
3818
3819 class FemmeFatale {
3820 public:
3821 FemmeFatale();
3822 ~FemmeFatale() __attribute__((noreturn));
3823 };
3824
3825 void exitNow() __attribute__((noreturn));
3826 void exitDestruct(const MyString& ms) __attribute__((noreturn));
3827
3828 Mutex fatalmu_;
3829
test1()3830 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3831 exitNow();
3832 }
3833
test2()3834 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3835 FemmeFatale femme;
3836 }
3837
3838 bool c;
3839
test3()3840 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3841 if (c) {
3842 exitNow();
3843 }
3844 else {
3845 FemmeFatale femme;
3846 }
3847 }
3848
test4()3849 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) {
3850 exitDestruct("foo");
3851 }
3852
3853 } // end namespace UnreachableExitTest
3854
3855
3856 namespace VirtualMethodCanonicalizationTest {
3857
3858 class Base {
3859 public:
3860 virtual Mutex* getMutex() = 0;
3861 };
3862
3863 class Base2 : public Base {
3864 public:
3865 Mutex* getMutex();
3866 };
3867
3868 class Base3 : public Base2 {
3869 public:
3870 Mutex* getMutex();
3871 };
3872
3873 class Derived : public Base3 {
3874 public:
3875 Mutex* getMutex(); // overrides Base::getMutex()
3876 };
3877
baseFun(Base * b)3878 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { }
3879
derivedFun(Derived * d)3880 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) {
3881 baseFun(d);
3882 }
3883
3884 } // end namespace VirtualMethodCanonicalizationTest
3885
3886
3887 namespace TemplateFunctionParamRemapTest {
3888
3889 template <class T>
3890 struct Cell {
3891 T dummy_;
3892 Mutex* mu_;
3893 };
3894
3895 class Foo {
3896 public:
3897 template <class T>
3898 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3899
3900 void test();
3901 };
3902
3903 template<class T>
elr(Cell<T> * c1)3904 void Foo::elr(Cell<T>* c1) { }
3905
test()3906 void Foo::test() {
3907 Cell<int> cell;
3908 elr(&cell); // \
3909 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}}
3910 }
3911
3912
3913 template<class T>
3914 void globalELR(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3915
3916 template<class T>
globalELR(Cell<T> * c1)3917 void globalELR(Cell<T>* c1) { }
3918
globalTest()3919 void globalTest() {
3920 Cell<int> cell;
3921 globalELR(&cell); // \
3922 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}}
3923 }
3924
3925
3926 template<class T>
3927 void globalELR2(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3928
3929 // second declaration
3930 template<class T>
3931 void globalELR2(Cell<T>* c2);
3932
3933 template<class T>
globalELR2(Cell<T> * c3)3934 void globalELR2(Cell<T>* c3) { }
3935
3936 // re-declaration after definition
3937 template<class T>
3938 void globalELR2(Cell<T>* c4);
3939
globalTest2()3940 void globalTest2() {
3941 Cell<int> cell;
3942 globalELR2(&cell); // \
3943 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}}
3944 }
3945
3946
3947 template<class T>
3948 class FooT {
3949 public:
3950 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_);
3951 };
3952
3953 template<class T>
elr(Cell<T> * c1)3954 void FooT<T>::elr(Cell<T>* c1) { }
3955
testFooT()3956 void testFooT() {
3957 Cell<int> cell;
3958 FooT<int> foo;
3959 foo.elr(&cell); // \
3960 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
3961 }
3962
3963 } // end namespace TemplateFunctionParamRemapTest
3964
3965
3966 namespace SelfConstructorTest {
3967
3968 class SelfLock {
3969 public:
3970 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_);
3971 ~SelfLock() UNLOCK_FUNCTION(mu_);
3972
3973 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
3974
3975 Mutex mu_;
3976 };
3977
3978 class LOCKABLE SelfLock2 {
3979 public:
3980 SelfLock2() EXCLUSIVE_LOCK_FUNCTION();
3981 ~SelfLock2() UNLOCK_FUNCTION();
3982
3983 void foo() EXCLUSIVE_LOCKS_REQUIRED(this);
3984 };
3985
3986
test()3987 void test() {
3988 SelfLock s;
3989 s.foo();
3990 }
3991
test2()3992 void test2() {
3993 SelfLock2 s2;
3994 s2.foo();
3995 }
3996
3997 } // end namespace SelfConstructorTest
3998
3999
4000 namespace MultipleAttributeTest {
4001
4002 class Foo {
4003 Mutex mu1_;
4004 Mutex mu2_;
4005 int a GUARDED_BY(mu1_);
4006 int b GUARDED_BY(mu2_);
4007 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_);
4008 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_);
4009
4010 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_)
4011 EXCLUSIVE_LOCKS_REQUIRED(mu2_);
4012 void foo2() SHARED_LOCKS_REQUIRED(mu1_)
4013 SHARED_LOCKS_REQUIRED(mu2_);
4014 void foo3() LOCKS_EXCLUDED(mu1_)
4015 LOCKS_EXCLUDED(mu2_);
4016 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_)
4017 EXCLUSIVE_LOCK_FUNCTION(mu2_);
4018 void readerlock() SHARED_LOCK_FUNCTION(mu1_)
4019 SHARED_LOCK_FUNCTION(mu2_);
4020 void unlock() UNLOCK_FUNCTION(mu1_)
4021 UNLOCK_FUNCTION(mu2_);
4022 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_)
4023 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
4024 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
4025 SHARED_TRYLOCK_FUNCTION(true, mu2_);
4026 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
4027 ASSERT_EXCLUSIVE_LOCK(mu2_);
4028
4029 void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);
4030
4031 void assertShared() ASSERT_SHARED_LOCK(mu1_)
4032 ASSERT_SHARED_LOCK(mu2_);
4033
4034 void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);
4035
4036 void test();
4037 void testAssert();
4038 void testAssertShared();
4039 };
4040
4041
foo1()4042 void Foo::foo1() {
4043 a = 1;
4044 b = 2;
4045 }
4046
foo2()4047 void Foo::foo2() {
4048 int result = a + b;
4049 }
4050
foo3()4051 void Foo::foo3() { }
lock()4052 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); }
readerlock()4053 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); }
unlock()4054 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); }
trylock()4055 bool Foo::trylock() { return true; }
readertrylock()4056 bool Foo::readertrylock() { return true; }
4057
4058
test()4059 void Foo::test() {
4060 mu1_.Lock();
4061 foo1(); // expected-warning {{}}
4062 c = 0; // expected-warning {{}}
4063 *d = 0; // expected-warning {{}}
4064 mu1_.Unlock();
4065
4066 mu1_.ReaderLock();
4067 foo2(); // expected-warning {{}}
4068 int x = c; // expected-warning {{}}
4069 int y = *d; // expected-warning {{}}
4070 mu1_.Unlock();
4071
4072 mu2_.Lock();
4073 foo3(); // expected-warning {{}}
4074 mu2_.Unlock();
4075
4076 lock();
4077 a = 0;
4078 b = 0;
4079 unlock();
4080
4081 readerlock();
4082 int z = a + b;
4083 unlock();
4084
4085 if (trylock()) {
4086 a = 0;
4087 b = 0;
4088 unlock();
4089 }
4090
4091 if (readertrylock()) {
4092 int zz = a + b;
4093 unlock();
4094 }
4095 }
4096
4097 // Force duplication of attributes
assertBoth()4098 void Foo::assertBoth() { }
alsoAssertBoth()4099 void Foo::alsoAssertBoth() { }
assertShared()4100 void Foo::assertShared() { }
alsoAssertShared()4101 void Foo::alsoAssertShared() { }
4102
testAssert()4103 void Foo::testAssert() {
4104 {
4105 assertBoth();
4106 a = 0;
4107 b = 0;
4108 }
4109 {
4110 alsoAssertBoth();
4111 a = 0;
4112 b = 0;
4113 }
4114 }
4115
testAssertShared()4116 void Foo::testAssertShared() {
4117 {
4118 assertShared();
4119 int zz = a + b;
4120 }
4121
4122 {
4123 alsoAssertShared();
4124 int zz = a + b;
4125 }
4126 }
4127
4128
4129 } // end namespace MultipleAttributeTest
4130
4131
4132 namespace GuardedNonPrimitiveTypeTest {
4133
4134
4135 class Data {
4136 public:
Data(int i)4137 Data(int i) : dat(i) { }
4138
getValue() const4139 int getValue() const { return dat; }
setValue(int i)4140 void setValue(int i) { dat = i; }
4141
operator [](int i) const4142 int operator[](int i) const { return dat; }
operator [](int i)4143 int& operator[](int i) { return dat; }
4144
operator ()()4145 void operator()() { }
4146
4147 private:
4148 int dat;
4149 };
4150
4151
4152 class DataCell {
4153 public:
DataCell(const Data & d)4154 DataCell(const Data& d) : dat(d) { }
4155
4156 private:
4157 Data dat;
4158 };
4159
4160
4161 void showDataCell(const DataCell& dc);
4162
4163
4164 class Foo {
4165 public:
4166 // method call tests
test()4167 void test() {
4168 data_.setValue(0); // FIXME -- should be writing \
4169 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4170 int a = data_.getValue(); // \
4171 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4172
4173 datap1_->setValue(0); // FIXME -- should be writing \
4174 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4175 a = datap1_->getValue(); // \
4176 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4177
4178 datap2_->setValue(0); // FIXME -- should be writing \
4179 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4180 a = datap2_->getValue(); // \
4181 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4182
4183 (*datap2_).setValue(0); // FIXME -- should be writing \
4184 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4185 a = (*datap2_).getValue(); // \
4186 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4187
4188 mu_.Lock();
4189 data_.setValue(1);
4190 datap1_->setValue(1);
4191 datap2_->setValue(1);
4192 mu_.Unlock();
4193
4194 mu_.ReaderLock();
4195 a = data_.getValue();
4196 datap1_->setValue(0); // reads datap1_, writes *datap1_
4197 a = datap1_->getValue();
4198 a = datap2_->getValue();
4199 mu_.Unlock();
4200 }
4201
4202 // operator tests
test2()4203 void test2() {
4204 data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
4205 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
4206 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4207 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
4208 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4209 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4210 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
4211 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
4212 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4213
4214 data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4215 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4216
4217 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4218 }
4219
4220 // const operator tests
test3() const4221 void test3() const {
4222 Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4223
4224 //FIXME
4225 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4226 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
4227
4228 int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
4229 }
4230
4231 private:
4232 Mutex mu_;
4233 Data data_ GUARDED_BY(mu_);
4234 Data* datap1_ GUARDED_BY(mu_);
4235 Data* datap2_ PT_GUARDED_BY(mu_);
4236 };
4237
4238 } // end namespace GuardedNonPrimitiveTypeTest
4239
4240
4241 namespace GuardedNonPrimitive_MemberAccess {
4242
4243 class Cell {
4244 public:
4245 Cell(int i);
4246
4247 void cellMethod();
4248
4249 int a;
4250 };
4251
4252
4253 class Foo {
4254 public:
4255 int a;
4256 Cell c GUARDED_BY(cell_mu_);
4257 Cell* cp PT_GUARDED_BY(cell_mu_);
4258
4259 void myMethod();
4260
4261 Mutex cell_mu_;
4262 };
4263
4264
4265 class Bar {
4266 private:
4267 Mutex mu_;
4268 Foo foo GUARDED_BY(mu_);
4269 Foo* foop PT_GUARDED_BY(mu_);
4270
test()4271 void test() {
4272 foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4273
4274 int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
4275 foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
4276
4277 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4278 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4279
4280 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
4281 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
4282
4283 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
4284 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
4285 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
4286 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
4287
4288 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4289 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4290 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4291 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4292
4293 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4294 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
4295 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
4296 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
4297 };
4298 };
4299
4300 } // namespace GuardedNonPrimitive_MemberAccess
4301
4302
4303 namespace TestThrowExpr {
4304
4305 class Foo {
4306 Mutex mu_;
4307
4308 bool hasError();
4309
test()4310 void test() {
4311 mu_.Lock();
4312 if (hasError()) {
4313 throw "ugly";
4314 }
4315 mu_.Unlock();
4316 }
4317 };
4318
4319 } // end namespace TestThrowExpr
4320
4321
4322 namespace UnevaluatedContextTest {
4323
4324 // parse attribute expressions in an unevaluated context.
4325
4326 static inline Mutex* getMutex1();
4327 static inline Mutex* getMutex2();
4328
4329 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1());
4330
4331 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2());
4332
4333 } // end namespace UnevaluatedContextTest
4334
4335
4336 namespace LockUnlockFunctionTest {
4337
4338 // Check built-in lock functions
4339 class LOCKABLE MyLockable {
4340 public:
lock()4341 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
readerLock()4342 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); }
unlock()4343 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
4344
4345 private:
4346 Mutex mu_;
4347 };
4348
4349
4350 class Foo {
4351 public:
4352 // Correct lock/unlock functions
lock()4353 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4354 mu_.Lock();
4355 }
4356
readerLock()4357 void readerLock() SHARED_LOCK_FUNCTION(mu_) {
4358 mu_.ReaderLock();
4359 }
4360
unlock()4361 void unlock() UNLOCK_FUNCTION(mu_) {
4362 mu_.Unlock();
4363 }
4364
unlockExclusive()4365 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_) {
4366 mu_.Unlock();
4367 }
4368
unlockShared()4369 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_) {
4370 mu_.ReaderUnlock();
4371 }
4372
4373 // Check failure to lock.
lockBad()4374 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4375 mu2_.Lock();
4376 mu2_.Unlock();
4377 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4378
readerLockBad()4379 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4380 mu2_.Lock();
4381 mu2_.Unlock();
4382 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
4383
unlockBad()4384 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4385 mu2_.Lock();
4386 mu2_.Unlock();
4387 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4388
4389 // Check locking the wrong thing.
lockBad2()4390 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4391 mu2_.Lock(); // expected-note {{mutex acquired here}}
4392 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4393 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4394
4395
readerLockBad2()4396 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4397 mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
4398 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
4399 // expected-warning {{mutex 'mu2_' is still held at the end of function}}
4400
4401
unlockBad2()4402 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
4403 mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
4404 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4405
4406 private:
4407 Mutex mu_;
4408 Mutex mu2_;
4409 };
4410
4411 } // end namespace LockUnlockFunctionTest
4412
4413
4414 namespace AssertHeldTest {
4415
4416 class Foo {
4417 public:
4418 int c;
4419 int a GUARDED_BY(mu_);
4420 Mutex mu_;
4421
test1()4422 void test1() {
4423 mu_.AssertHeld();
4424 int b = a;
4425 a = 0;
4426 }
4427
test2()4428 void test2() {
4429 mu_.AssertReaderHeld();
4430 int b = a;
4431 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
4432 }
4433
test3()4434 void test3() {
4435 if (c) {
4436 mu_.AssertHeld();
4437 }
4438 else {
4439 mu_.AssertHeld();
4440 }
4441 int b = a;
4442 a = 0;
4443 }
4444
test4()4445 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4446 mu_.AssertHeld();
4447 int b = a;
4448 a = 0;
4449 }
4450
test5()4451 void test5() UNLOCK_FUNCTION(mu_) {
4452 mu_.AssertHeld();
4453 mu_.Unlock();
4454 }
4455
test6()4456 void test6() {
4457 mu_.AssertHeld();
4458 mu_.Unlock();
4459 } // should this be a warning?
4460
test7()4461 void test7() {
4462 if (c) {
4463 mu_.AssertHeld();
4464 }
4465 else {
4466 mu_.Lock();
4467 }
4468 int b = a;
4469 a = 0;
4470 mu_.Unlock();
4471 }
4472
test8()4473 void test8() {
4474 if (c) {
4475 mu_.Lock();
4476 }
4477 else {
4478 mu_.AssertHeld();
4479 }
4480 int b = a;
4481 a = 0;
4482 mu_.Unlock();
4483 }
4484
test9()4485 void test9() {
4486 if (c) {
4487 mu_.AssertHeld();
4488 }
4489 else {
4490 mu_.Lock(); // expected-note {{mutex acquired here}}
4491 }
4492 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4493
test10()4494 void test10() {
4495 if (c) {
4496 mu_.Lock(); // expected-note {{mutex acquired here}}
4497 }
4498 else {
4499 mu_.AssertHeld();
4500 }
4501 } // expected-warning {{mutex 'mu_' is still held at the end of function}}
4502
4503 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
4504
test11()4505 void test11() {
4506 assertMu();
4507 int b = a;
4508 a = 0;
4509 }
4510 };
4511
4512 } // end namespace AssertHeldTest
4513
4514
4515 namespace LogicalConditionalTryLock {
4516
4517 class Foo {
4518 public:
4519 Mutex mu;
4520 int a GUARDED_BY(mu);
4521 bool c;
4522
4523 bool newc();
4524
test1()4525 void test1() {
4526 if (c && mu.TryLock()) {
4527 a = 0;
4528 mu.Unlock();
4529 }
4530 }
4531
test2()4532 void test2() {
4533 bool b = mu.TryLock();
4534 if (c && b) {
4535 a = 0;
4536 mu.Unlock();
4537 }
4538 }
4539
test3()4540 void test3() {
4541 if (c || !mu.TryLock())
4542 return;
4543 a = 0;
4544 mu.Unlock();
4545 }
4546
test4()4547 void test4() {
4548 while (c && mu.TryLock()) {
4549 a = 0;
4550 c = newc();
4551 mu.Unlock();
4552 }
4553 }
4554
test5()4555 void test5() {
4556 while (c) {
4557 if (newc() || !mu.TryLock())
4558 break;
4559 a = 0;
4560 mu.Unlock();
4561 }
4562 }
4563
test6()4564 void test6() {
4565 mu.Lock();
4566 do {
4567 a = 0;
4568 mu.Unlock();
4569 } while (newc() && mu.TryLock());
4570 }
4571
test7()4572 void test7() {
4573 for (bool b = mu.TryLock(); c && b;) {
4574 a = 0;
4575 mu.Unlock();
4576 }
4577 }
4578
test8()4579 void test8() {
4580 if (c && newc() && mu.TryLock()) {
4581 a = 0;
4582 mu.Unlock();
4583 }
4584 }
4585
test9()4586 void test9() {
4587 if (!(c && newc() && mu.TryLock()))
4588 return;
4589 a = 0;
4590 mu.Unlock();
4591 }
4592
test10()4593 void test10() {
4594 if (!(c || !mu.TryLock())) {
4595 a = 0;
4596 mu.Unlock();
4597 }
4598 }
4599 };
4600
4601 } // end namespace LogicalConditionalTryLock
4602
4603
4604
4605 namespace PtGuardedByTest {
4606
4607 void doSomething();
4608
4609 class Cell {
4610 public:
4611 int a;
4612 };
4613
4614
4615 // This mainly duplicates earlier tests, but just to make sure...
4616 class PtGuardedBySanityTest {
4617 Mutex mu1;
4618 Mutex mu2;
4619 int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4620 Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4621 int sa[10] GUARDED_BY(mu1);
4622 Cell sc[10] GUARDED_BY(mu1);
4623
test1()4624 void test1() {
4625 mu1.Lock();
4626 if (a == 0) doSomething(); // OK, we don't dereference.
4627 a = 0;
4628 c = 0;
4629 if (sa[0] == 42) doSomething();
4630 sa[0] = 57;
4631 if (sc[0].a == 42) doSomething();
4632 sc[0].a = 57;
4633 mu1.Unlock();
4634 }
4635
test2()4636 void test2() {
4637 mu1.ReaderLock();
4638 if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4639 *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4640
4641 if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4642 c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4643
4644 if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4645 (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4646
4647 if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
4648 a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
4649 if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
4650 c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
4651 mu1.Unlock();
4652 }
4653
test3()4654 void test3() {
4655 mu2.Lock();
4656 if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4657 *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4658
4659 if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4660 c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4661
4662 if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4663 (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4664
4665 if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4666 a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
4667 if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4668 c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
4669 mu2.Unlock();
4670 }
4671
test4()4672 void test4() { // Literal arrays
4673 if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4674 sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4675 if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4676 sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4677
4678 if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
4679 *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
4680 if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4681 (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4682 if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
4683 sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
4684 }
4685
test5()4686 void test5() {
4687 mu1.ReaderLock(); // OK -- correct use.
4688 mu2.Lock();
4689 if (*a == 0) doSomething();
4690 *a = 0;
4691
4692 if (c->a == 0) doSomething();
4693 c->a = 0;
4694
4695 if ((*c).a == 0) doSomething();
4696 (*c).a = 0;
4697 mu2.Unlock();
4698 mu1.Unlock();
4699 }
4700 };
4701
4702
4703 class SmartPtr_PtGuardedBy_Test {
4704 Mutex mu1;
4705 Mutex mu2;
4706 SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4707 SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
4708
test1()4709 void test1() {
4710 mu1.ReaderLock();
4711 mu2.Lock();
4712
4713 sp.get();
4714 if (*sp == 0) doSomething();
4715 *sp = 0;
4716 sq->a = 0;
4717
4718 if (sp[0] == 0) doSomething();
4719 sp[0] = 0;
4720
4721 mu2.Unlock();
4722 mu1.Unlock();
4723 }
4724
test2()4725 void test2() {
4726 mu2.Lock();
4727
4728 sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4729 if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4730 *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4731 sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4732
4733 if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4734 sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
4735 if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4736 sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
4737
4738 mu2.Unlock();
4739 }
4740
test3()4741 void test3() {
4742 mu1.Lock();
4743
4744 sp.get();
4745 if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4746 *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4747 sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4748
4749 if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4750 sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
4751 if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4752 sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
4753
4754 mu1.Unlock();
4755 }
4756 };
4757
4758 } // end namespace PtGuardedByTest
4759
4760
4761 namespace NonMemberCalleeICETest {
4762
4763 class A {
Run()4764 void Run() {
4765 (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
4766 }
4767
4768 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M);
4769 Mutex M;
4770 };
4771
4772 } // end namespace NonMemberCalleeICETest
4773
4774
4775 namespace pt_guard_attribute_type {
4776 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
4777 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
4778
test()4779 void test() {
4780 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
4781 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
4782
4783 typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}}
4784 typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}}
4785 }
4786 } // end namespace pt_guard_attribute_type
4787
4788
4789 namespace ThreadAttributesOnLambdas {
4790
4791 class Foo {
4792 Mutex mu_;
4793
4794 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
4795
test()4796 void test() {
4797 auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
4798 LockedFunction();
4799 };
4800
4801 auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
4802 LockedFunction();
4803 };
4804
4805 auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
4806 mu_.Lock();
4807 };
4808
4809 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
4810 func2();
4811 func3();
4812 mu_.Unlock();
4813 }
4814 };
4815
4816 } // end namespace ThreadAttributesOnLambdas
4817
4818
4819
4820 namespace AttributeExpressionCornerCases {
4821
4822 class Foo {
4823 int a GUARDED_BY(getMu());
4824
4825 Mutex* getMu() LOCK_RETURNED("");
4826 Mutex* getUniv() LOCK_RETURNED("*");
4827
test1()4828 void test1() {
4829 a = 0;
4830 }
4831
test2()4832 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) {
4833 a = 0;
4834 }
4835
4836 void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu);
4837
test3()4838 void test3() {
4839 foo(nullptr);
4840 }
4841 };
4842
4843
4844 class MapTest {
4845 struct MuCell { Mutex* mu; };
4846
4847 MyMap<MyString, Mutex*> map;
4848 MyMap<MyString, MuCell> mapCell;
4849
4850 int a GUARDED_BY(map["foo"]);
4851 int b GUARDED_BY(mapCell["foo"].mu);
4852
test()4853 void test() {
4854 map["foo"]->Lock();
4855 a = 0;
4856 map["foo"]->Unlock();
4857 }
4858
test2()4859 void test2() {
4860 mapCell["foo"].mu->Lock();
4861 b = 0;
4862 mapCell["foo"].mu->Unlock();
4863 }
4864 };
4865
4866
4867 class PreciseSmartPtr {
4868 SmartPtr<Mutex> mu;
4869 int val GUARDED_BY(mu);
4870
compare(PreciseSmartPtr & a,PreciseSmartPtr & b)4871 static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) {
4872 a.mu->Lock();
4873 bool result = (a.val == b.val); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \
4874 // expected-note {{found near match 'a.mu'}}
4875 a.mu->Unlock();
4876 return result;
4877 }
4878 };
4879
4880
4881 class SmartRedeclare {
4882 SmartPtr<Mutex> mu;
4883 int val GUARDED_BY(mu);
4884
4885 void test() EXCLUSIVE_LOCKS_REQUIRED(mu);
4886 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4887 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get());
4888 };
4889
4890
test()4891 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) {
4892 val = 0;
4893 }
4894
test2()4895 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) {
4896 val = 0;
4897 }
4898
test3()4899 void SmartRedeclare::test3() {
4900 val = 0;
4901 }
4902
4903
4904 namespace CustomMutex {
4905
4906
4907 class LOCKABLE BaseMutex { };
4908 class DerivedMutex : public BaseMutex { };
4909
4910 void customLock(const BaseMutex *m) EXCLUSIVE_LOCK_FUNCTION(m);
4911 void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m);
4912
4913 static struct DerivedMutex custMu;
4914
doSomethingRequiringLock()4915 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { }
4916
customTest()4917 void customTest() {
4918 customLock(reinterpret_cast<BaseMutex*>(&custMu)); // ignore casts
4919 doSomethingRequiringLock();
4920 customUnlock(reinterpret_cast<BaseMutex*>(&custMu));
4921 }
4922
4923 } // end namespace CustomMutex
4924
4925 } // end AttributeExpressionCornerCases
4926
4927
4928 namespace ScopedLockReturnedInvalid {
4929
4930 class Opaque;
4931
4932 Mutex* getMutex(Opaque* o) LOCK_RETURNED("");
4933
test(Opaque * o)4934 void test(Opaque* o) {
4935 MutexLock lock(getMutex(o));
4936 }
4937
4938 } // end namespace ScopedLockReturnedInvalid
4939
4940
4941 namespace NegativeRequirements {
4942
4943 class Bar {
4944 Mutex mu;
4945 int a GUARDED_BY(mu);
4946
4947 public:
baz()4948 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4949 mu.Lock();
4950 a = 0;
4951 mu.Unlock();
4952 }
4953 };
4954
4955
4956 class Foo {
4957 Mutex mu;
4958 int a GUARDED_BY(mu);
4959
4960 public:
foo()4961 void foo() {
4962 mu.Lock(); // warning? needs !mu?
4963 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}}
4964 bar();
4965 mu.Unlock();
4966 }
4967
bar()4968 void bar() {
4969 bar2(); // expected-warning {{calling function 'bar2' requires holding '!mu'}}
4970 }
4971
bar2()4972 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4973 baz();
4974 }
4975
baz()4976 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
4977 mu.Lock();
4978 a = 0;
4979 mu.Unlock();
4980 }
4981
test()4982 void test() {
4983 Bar b;
4984 b.baz(); // no warning -- in different class.
4985 }
4986 };
4987
4988 } // end namespace NegativeRequirements
4989
4990
4991 namespace NegativeThreadRoles {
4992
4993 typedef int __attribute__((capability("role"))) ThreadRole;
4994
acquire(ThreadRole R)4995 void acquire(ThreadRole R) EXCLUSIVE_LOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
release(ThreadRole R)4996 void release(ThreadRole R) UNLOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {}
4997
4998 ThreadRole FlightControl, Logger;
4999
5000 extern void enque_log_msg(const char *msg);
log_msg(const char * msg)5001 void log_msg(const char *msg) {
5002 enque_log_msg(msg);
5003 }
5004
dispatch_log(const char * msg)5005 void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {}
dispatch_log2(const char * msg)5006 void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {}
5007
flight_control_entry(void)5008 void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) {
5009 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */
5010 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */
5011 }
5012
spawn_fake_flight_control_thread(void)5013 void spawn_fake_flight_control_thread(void) {
5014 acquire(FlightControl);
5015 flight_control_entry();
5016 release(FlightControl);
5017 }
5018
5019 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
logger_entry(void)5020 void logger_entry(void) __attribute__((requires_capability(Logger))) {
5021 const char *msg;
5022
5023 while ((msg = deque_log_msg())) {
5024 dispatch_log(msg);
5025 }
5026 }
5027
spawn_fake_logger_thread(void)5028 void spawn_fake_logger_thread(void) {
5029 acquire(Logger);
5030 logger_entry();
5031 release(Logger);
5032 }
5033
main(void)5034 int main(void) {
5035 spawn_fake_flight_control_thread();
5036 spawn_fake_logger_thread();
5037
5038 for (;;)
5039 ; /* Pretend to dispatch things. */
5040
5041 return 0;
5042 }
5043
5044 } // end namespace NegativeThreadRoles
5045
5046
5047 namespace AssertSharedExclusive {
5048
5049 void doSomething();
5050
5051 class Foo {
5052 Mutex mu;
5053 int a GUARDED_BY(mu);
5054
test()5055 void test() SHARED_LOCKS_REQUIRED(mu) {
5056 mu.AssertHeld();
5057 if (a > 0)
5058 doSomething();
5059 }
5060 };
5061
5062 } // end namespace AssertSharedExclusive
5063
5064
5065 namespace RangeBasedForAndReferences {
5066
5067 class Foo {
5068 struct MyStruct {
5069 int a;
5070 };
5071
5072 Mutex mu;
5073 int a GUARDED_BY(mu);
5074 MyContainer<int> cntr GUARDED_BY(mu);
5075 MyStruct s GUARDED_BY(mu);
5076 int arr[10] GUARDED_BY(mu);
5077
nonref_test()5078 void nonref_test() {
5079 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5080 b = 0; // no warning
5081 }
5082
auto_test()5083 void auto_test() {
5084 auto b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
5085 b = 0; // no warning
5086 auto &c = a; // no warning
5087 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5088 }
5089
ref_test()5090 void ref_test() {
5091 int &b = a;
5092 int &c = b;
5093 int &d = c;
5094 b = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5095 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5096 d = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
5097
5098 MyStruct &rs = s;
5099 rs.a = 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}}
5100
5101 int (&rarr)[10] = arr;
5102 rarr[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}}
5103 }
5104
ptr_test()5105 void ptr_test() {
5106 int *b = &a;
5107 *b = 0; // no expected warning yet
5108 }
5109
for_test()5110 void for_test() {
5111 int total = 0;
5112 for (int i : cntr) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}}
5113 total += i;
5114 }
5115 }
5116 };
5117
5118
5119 } // end namespace RangeBasedForAndReferences
5120
5121
5122
5123 namespace PassByRefTest {
5124
5125 class Foo {
5126 public:
Foo()5127 Foo() : a(0), b(0) { }
5128
5129 int a;
5130 int b;
5131
5132 void operator+(const Foo& f);
5133
5134 void operator[](const Foo& g);
5135
5136 void operator()();
5137 };
5138
5139 template<class T>
5140 T&& mymove(T& f);
5141
5142
5143 // test top-level functions
5144 void copy(Foo f);
5145 void write1(Foo& f);
5146 void write2(int a, Foo& f);
5147 void read1(const Foo& f);
5148 void read2(int a, const Foo& f);
5149 void destroy(Foo&& f);
5150
5151 void operator/(const Foo& f, const Foo& g);
5152 void operator*(const Foo& f, const Foo& g);
5153
5154 // Test constructors.
5155 struct FooRead {
5156 FooRead(const Foo &);
5157 };
5158 struct FooWrite {
5159 FooWrite(Foo &);
5160 };
5161
5162 // Test variadic functions
5163 template<typename... T>
copyVariadic(T...)5164 void copyVariadic(T...) {}
5165 template<typename... T>
writeVariadic(T &...)5166 void writeVariadic(T&...) {}
5167 template<typename... T>
readVariadic(const T &...)5168 void readVariadic(const T&...) {}
5169
5170 void copyVariadicC(int, ...);
5171
5172 class Bar {
5173 public:
5174 Mutex mu;
5175 Foo foo GUARDED_BY(mu);
5176 Foo foo2 GUARDED_BY(mu);
5177 Foo* foop PT_GUARDED_BY(mu);
5178 SmartPtr<Foo> foosp PT_GUARDED_BY(mu);
5179
5180 // test methods.
5181 void mwrite1(Foo& f);
5182 void mwrite2(int a, Foo& f);
5183 void mread1(const Foo& f);
5184 void mread2(int a, const Foo& f);
5185
5186 // static methods
5187 static void smwrite1(Foo& f);
5188 static void smwrite2(int a, Foo& f);
5189 static void smread1(const Foo& f);
5190 static void smread2(int a, const Foo& f);
5191
5192 void operator<<(const Foo& f);
5193
test1()5194 void test1() {
5195 copy(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5196 write1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5197 write2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5198 read1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5199 read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5200 destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5201
5202 copyVariadic(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5203 readVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5204 writeVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5205 copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5206
5207 FooRead reader(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5208 FooWrite writer(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5209
5210 mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5211 mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5212 mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5213 mread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5214
5215 smwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5216 smwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5217 smread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5218 smread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5219
5220 foo + foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5221 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5222 foo / foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5223 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5224 foo * foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5225 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5226 foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \
5227 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}}
5228 foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}}
5229 (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}}
5230
5231 copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}}
5232 write1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5233 write2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5234 read1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5235 read2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5236 destroy(mymove(*foop)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}}
5237
5238 copy(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5239 write1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5240 write2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5241 read1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5242 read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5243 destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}}
5244
5245 // TODO -- these require better smart pointer handling.
5246 copy(*foosp.get());
5247 write1(*foosp.get());
5248 write2(10, *foosp.get());
5249 read1(*foosp.get());
5250 read2(10, *foosp.get());
5251 destroy(mymove(*foosp.get()));
5252 }
5253 };
5254
5255
5256 } // end namespace PassByRefTest
5257
5258
5259 namespace AcquiredBeforeAfterText {
5260
5261 class Foo {
5262 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5263 Mutex mu2;
5264 Mutex mu3;
5265
test1()5266 void test1() {
5267 mu1.Lock();
5268 mu2.Lock();
5269 mu3.Lock();
5270
5271 mu3.Unlock();
5272 mu2.Unlock();
5273 mu1.Unlock();
5274 }
5275
test2()5276 void test2() {
5277 mu2.Lock();
5278 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5279 mu1.Unlock();
5280 mu2.Unlock();
5281 }
5282
test3()5283 void test3() {
5284 mu3.Lock();
5285 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5286 mu1.Unlock();
5287 mu3.Unlock();
5288 }
5289
test4()5290 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) {
5291 mu2.Lock();
5292 mu2.Unlock();
5293 }
5294
test5()5295 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5296 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5297 mu1.Unlock();
5298 }
5299
test6()5300 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) {
5301 mu1.AssertHeld();
5302 }
5303
test7()5304 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { }
5305
test8()5306 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { }
5307 };
5308
5309
5310 class Foo2 {
5311 Mutex mu1;
5312 Mutex mu2 ACQUIRED_AFTER(mu1);
5313 Mutex mu3 ACQUIRED_AFTER(mu1);
5314
test1()5315 void test1() {
5316 mu1.Lock();
5317 mu2.Lock();
5318 mu3.Lock();
5319
5320 mu3.Unlock();
5321 mu2.Unlock();
5322 mu1.Unlock();
5323 }
5324
test2()5325 void test2() {
5326 mu2.Lock();
5327 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5328 mu1.Unlock();
5329 mu2.Unlock();
5330 }
5331
test3()5332 void test3() {
5333 mu3.Lock();
5334 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5335 mu1.Unlock();
5336 mu3.Unlock();
5337 }
5338 };
5339
5340
5341 class Foo3 {
5342 Mutex mu1 ACQUIRED_BEFORE(mu2);
5343 Mutex mu2;
5344 Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4);
5345 Mutex mu4;
5346
test1()5347 void test1() {
5348 mu1.Lock();
5349 mu2.Lock();
5350 mu3.Lock();
5351 mu4.Lock();
5352
5353 mu4.Unlock();
5354 mu3.Unlock();
5355 mu2.Unlock();
5356 mu1.Unlock();
5357 }
5358
test2()5359 void test2() {
5360 mu4.Lock();
5361 mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}}
5362
5363 mu2.Unlock();
5364 mu4.Unlock();
5365 }
5366
test3()5367 void test3() {
5368 mu4.Lock();
5369 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}}
5370
5371 mu1.Unlock();
5372 mu4.Unlock();
5373 }
5374
test4()5375 void test4() {
5376 mu3.Lock();
5377 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}}
5378
5379 mu1.Unlock();
5380 mu3.Unlock();
5381 }
5382 };
5383
5384
5385 // Test transitive DAG traversal with AFTER
5386 class Foo4 {
5387 Mutex mu1;
5388 Mutex mu2 ACQUIRED_AFTER(mu1);
5389 Mutex mu3 ACQUIRED_AFTER(mu1);
5390 Mutex mu4 ACQUIRED_AFTER(mu2, mu3);
5391 Mutex mu5 ACQUIRED_AFTER(mu4);
5392 Mutex mu6 ACQUIRED_AFTER(mu4);
5393 Mutex mu7 ACQUIRED_AFTER(mu5, mu6);
5394 Mutex mu8 ACQUIRED_AFTER(mu7);
5395
test()5396 void test() {
5397 mu8.Lock();
5398 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5399 mu1.Unlock();
5400 mu8.Unlock();
5401 }
5402 };
5403
5404
5405 // Test transitive DAG traversal with BEFORE
5406 class Foo5 {
5407 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3);
5408 Mutex mu2 ACQUIRED_BEFORE(mu4);
5409 Mutex mu3 ACQUIRED_BEFORE(mu4);
5410 Mutex mu4 ACQUIRED_BEFORE(mu5, mu6);
5411 Mutex mu5 ACQUIRED_BEFORE(mu7);
5412 Mutex mu6 ACQUIRED_BEFORE(mu7);
5413 Mutex mu7 ACQUIRED_BEFORE(mu8);
5414 Mutex mu8;
5415
test()5416 void test() {
5417 mu8.Lock();
5418 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}}
5419 mu1.Unlock();
5420 mu8.Unlock();
5421 }
5422 };
5423
5424
5425 class Foo6 {
5426 Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}}
5427 Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}}
5428 Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}}
5429
5430 Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}}
5431 Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}}
5432
test0()5433 void test0() {
5434 mu_a.Lock();
5435 mu_b.Lock();
5436 mu_b.Unlock();
5437 mu_a.Unlock();
5438 }
5439
test1a()5440 void test1a() {
5441 mu1.Lock();
5442 mu1.Unlock();
5443 }
5444
test1b()5445 void test1b() {
5446 mu1.Lock();
5447 mu_a.Lock();
5448 mu_b.Lock();
5449 mu_b.Unlock();
5450 mu_a.Unlock();
5451 mu1.Unlock();
5452 }
5453
test()5454 void test() {
5455 mu2.Lock();
5456 mu2.Unlock();
5457 }
5458
test3()5459 void test3() {
5460 mu3.Lock();
5461 mu3.Unlock();
5462 }
5463 };
5464
5465 } // end namespace AcquiredBeforeAfterTest
5466
5467
5468 namespace ScopedAdoptTest {
5469
5470 class Foo {
5471 Mutex mu;
5472 int a GUARDED_BY(mu);
5473 int b;
5474
test1()5475 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) {
5476 MutexLock slock(&mu, true);
5477 a = 0;
5478 }
5479
test2()5480 void test2() SHARED_UNLOCK_FUNCTION(mu) {
5481 ReaderMutexLock slock(&mu, true);
5482 b = a;
5483 }
5484
test3()5485 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5486 MutexLock slock(&mu, true);
5487 a = 0;
5488 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5489
test4()5490 void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}}
5491 ReaderMutexLock slock(&mu, true);
5492 b = a;
5493 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}}
5494
5495 };
5496
5497 } // end namespace ScopedAdoptTest
5498
5499
5500 namespace TestReferenceNoThreadSafetyAnalysis {
5501
5502 #define TS_UNCHECKED_READ(x) ts_unchecked_read(x)
5503
5504 // Takes a reference to a guarded data member, and returns an unguarded
5505 // reference.
5506 template <class T>
ts_unchecked_read(const T & v)5507 inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
5508 return v;
5509 }
5510
5511 template <class T>
ts_unchecked_read(T & v)5512 inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
5513 return v;
5514 }
5515
5516
5517 class Foo {
5518 public:
Foo()5519 Foo(): a(0) { }
5520
5521 int a;
5522 };
5523
5524
5525 class Bar {
5526 public:
Bar()5527 Bar() : a(0) { }
5528
5529 Mutex mu;
5530 int a GUARDED_BY(mu);
5531 Foo foo GUARDED_BY(mu);
5532 };
5533
5534
test()5535 void test() {
5536 Bar bar;
5537 const Bar cbar;
5538
5539 int a = TS_UNCHECKED_READ(bar.a); // nowarn
5540 TS_UNCHECKED_READ(bar.a) = 1; // nowarn
5541
5542 int b = TS_UNCHECKED_READ(bar.foo).a; // nowarn
5543 TS_UNCHECKED_READ(bar.foo).a = 1; // nowarn
5544
5545 int c = TS_UNCHECKED_READ(cbar.a); // nowarn
5546 }
5547
5548 #undef TS_UNCHECKED_READ
5549
5550 } // end namespace TestReferenceNoThreadSafetyAnalysis
5551
5552
5553 namespace GlobalAcquiredBeforeAfterTest {
5554
5555 Mutex mu1;
5556 Mutex mu2 ACQUIRED_AFTER(mu1);
5557
test3()5558 void test3() {
5559 mu2.Lock();
5560 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}}
5561 mu1.Unlock();
5562 mu2.Unlock();
5563 }
5564
5565 } // end namespace GlobalAcquiredBeforeAfterTest
5566
5567
5568 namespace LifetimeExtensionText {
5569
5570 struct Holder {
~HolderLifetimeExtensionText::Holder5571 virtual ~Holder() throw() {}
5572 int i = 0;
5573 };
5574
test()5575 void test() {
5576 // Should not crash.
5577 const auto &value = Holder().i;
5578 }
5579
5580 } // end namespace LifetimeExtensionTest
5581
5582
5583 namespace LockableUnions {
5584
5585 union LOCKABLE MutexUnion {
5586 int a;
5587 char* b;
5588
5589 void Lock() EXCLUSIVE_LOCK_FUNCTION();
5590 void Unlock() UNLOCK_FUNCTION();
5591 };
5592
5593 MutexUnion muun2;
5594 MutexUnion muun1 ACQUIRED_BEFORE(muun2);
5595
test()5596 void test() {
5597 muun2.Lock();
5598 muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}}
5599 muun1.Unlock();
5600 muun2.Unlock();
5601 }
5602
5603 } // end namespace LockableUnions
5604
5605 // This used to crash.
5606 class acquired_before_empty_str {
WaitUntilSpaceAvailable()5607 void WaitUntilSpaceAvailable() {
5608 lock_.ReaderLock(); // expected-note {{acquired here}}
5609 } // expected-warning {{mutex 'lock_' is still held at the end of function}}
5610 Mutex lock_ ACQUIRED_BEFORE("");
5611 };
5612
5613 namespace PR34800 {
5614 struct A {
5615 operator int() const;
5616 };
5617 struct B {
5618 bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
5619 int h;
5620 };
5621 struct C {
5622 B *operator[](int);
5623 };
5624 C c;
f()5625 void f() { c[A()]->g(); }
5626 } // namespace PR34800
5627
5628 namespace ReturnScopedLockable {
5629 template<typename Object> class SCOPED_LOCKABLE ReadLockedPtr {
5630 public:
5631 ReadLockedPtr(Object *ptr) SHARED_LOCK_FUNCTION((*this)->mutex);
5632 ReadLockedPtr(ReadLockedPtr &&) SHARED_LOCK_FUNCTION((*this)->mutex);
5633 ~ReadLockedPtr() UNLOCK_FUNCTION();
5634
operator ->() const5635 Object *operator->() const { return object; }
5636
5637 private:
5638 Object *object;
5639 };
5640
5641 struct Object {
5642 int f() SHARED_LOCKS_REQUIRED(mutex);
5643 Mutex mutex;
5644 };
5645
5646 ReadLockedPtr<Object> get();
use()5647 int use() {
5648 auto ptr = get();
5649 return ptr->f();
5650 }
5651 }
5652
5653 namespace PR38640 {
f()5654 void f() {
5655 // Self-referencing assignment previously caused an infinite loop when thread
5656 // safety analysis was enabled.
5657 int &i = i; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}}
5658 }
5659 }
5660
5661 namespace Derived_Smart_Pointer {
5662 template <class T>
5663 class SmartPtr_Derived : public SmartPtr<T> {};
5664
5665 class Foo {
5666 public:
5667 SmartPtr_Derived<Mutex> mu_;
5668 int a GUARDED_BY(mu_);
5669 int b GUARDED_BY(mu_.get());
5670 int c GUARDED_BY(*mu_);
5671
5672 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
5673 void Unlock() UNLOCK_FUNCTION(mu_);
5674
test0()5675 void test0() {
5676 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
5677 b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
5678 c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
5679 }
5680
test1()5681 void test1() {
5682 Lock();
5683 a = 1;
5684 b = 1;
5685 c = 1;
5686 Unlock();
5687 }
5688 };
5689
5690 class Bar {
5691 SmartPtr_Derived<Foo> foo;
5692
test0()5693 void test0() {
5694 foo->a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
5695 (*foo).b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
5696 foo.get()->c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
5697 }
5698
test1()5699 void test1() {
5700 foo->Lock();
5701 foo->a = 1;
5702 foo->Unlock();
5703
5704 foo->mu_->Lock();
5705 foo->b = 1;
5706 foo->mu_->Unlock();
5707
5708 MutexLock lock(foo->mu_.get());
5709 foo->c = 1;
5710 }
5711 };
5712
5713 class PointerGuard {
5714 Mutex mu1;
5715 Mutex mu2;
5716 SmartPtr_Derived<int> i GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
5717
test0()5718 void test0() {
5719 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5720 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \
5721 // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
5722
5723 }
5724
test1()5725 void test1() {
5726 mu1.Lock();
5727
5728 i.get();
5729 *i = 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}}
5730
5731 mu1.Unlock();
5732 }
5733
test2()5734 void test2() {
5735 mu2.Lock();
5736
5737 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5738 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}}
5739
5740 mu2.Unlock();
5741 }
5742
test3()5743 void test3() {
5744 mu1.Lock();
5745 mu2.Lock();
5746
5747 i.get();
5748 *i = 2;
5749
5750 mu2.Unlock();
5751 mu1.Unlock();
5752 }
5753 };
5754 }
5755