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