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