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