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