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