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