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