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