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