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