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