Clang Project

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