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(); 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(); 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(); 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(); 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(); 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(); 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); 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); 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(); 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; 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(); 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 } // end namespace TemporaryCleanupExpr 3055 3056 3057 3058 namespace SmartPointerTests { 3059 3060 class Foo { 3061 public: 3062 SmartPtr<Mutex> mu_; 3063 int a GUARDED_BY(mu_); 3064 int b GUARDED_BY(mu_.get()); 3065 int c GUARDED_BY(*mu_); 3066 3067 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_); 3068 void Unlock() UNLOCK_FUNCTION(mu_); 3069 3070 void test0(); 3071 void test1(); 3072 void test2(); 3073 void test3(); 3074 void test4(); 3075 void test5(); 3076 void test6(); 3077 void test7(); 3078 void test8(); 3079 }; 3080 3081 void Foo::test0() { 3082 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3083 b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}} 3084 c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}} 3085 } 3086 3087 void Foo::test1() { 3088 mu_->Lock(); 3089 a = 0; 3090 b = 0; 3091 c = 0; 3092 mu_->Unlock(); 3093 } 3094 3095 void Foo::test2() { 3096 (*mu_).Lock(); 3097 a = 0; 3098 b = 0; 3099 c = 0; 3100 (*mu_).Unlock(); 3101 } 3102 3103 3104 void Foo::test3() { 3105 mu_.get()->Lock(); 3106 a = 0; 3107 b = 0; 3108 c = 0; 3109 mu_.get()->Unlock(); 3110 } 3111 3112 3113 void Foo::test4() { 3114 MutexLock lock(mu_.get()); 3115 a = 0; 3116 b = 0; 3117 c = 0; 3118 } 3119 3120 3121 void Foo::test5() { 3122 MutexLock lock(&(*mu_)); 3123 a = 0; 3124 b = 0; 3125 c = 0; 3126 } 3127 3128 3129 void Foo::test6() { 3130 Lock(); 3131 a = 0; 3132 b = 0; 3133 c = 0; 3134 Unlock(); 3135 } 3136 3137 3138 void Foo::test7() { 3139 { 3140 Lock(); 3141 mu_->Unlock(); 3142 } 3143 { 3144 mu_->Lock(); 3145 Unlock(); 3146 } 3147 { 3148 mu_.get()->Lock(); 3149 mu_->Unlock(); 3150 } 3151 { 3152 mu_->Lock(); 3153 mu_.get()->Unlock(); 3154 } 3155 { 3156 mu_.get()->Lock(); 3157 (*mu_).Unlock(); 3158 } 3159 { 3160 (*mu_).Lock(); 3161 mu_->Unlock(); 3162 } 3163 } 3164 3165 3166 void Foo::test8() { 3167 mu_->Lock(); 3168 mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}} 3169 (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}} 3170 mu_.get()->Unlock(); 3171 Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}} 3172 } 3173 3174 3175 class Bar { 3176 SmartPtr<Foo> foo; 3177 3178 void test0(); 3179 void test1(); 3180 void test2(); 3181 void test3(); 3182 }; 3183 3184 3185 void Bar::test0() { 3186 foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}} 3187 (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}} 3188 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}} 3189 } 3190 3191 3192 void Bar::test1() { 3193 foo->mu_->Lock(); 3194 foo->a = 0; 3195 (*foo).b = 0; 3196 foo.get()->c = 0; 3197 foo->mu_->Unlock(); 3198 } 3199 3200 3201 void Bar::test2() { 3202 (*foo).mu_->Lock(); 3203 foo->a = 0; 3204 (*foo).b = 0; 3205 foo.get()->c = 0; 3206 foo.get()->mu_->Unlock(); 3207 } 3208 3209 3210 void Bar::test3() { 3211 MutexLock lock(foo->mu_.get()); 3212 foo->a = 0; 3213 (*foo).b = 0; 3214 foo.get()->c = 0; 3215 } 3216 3217 } // end namespace SmartPointerTests 3218 3219 3220 3221 namespace DuplicateAttributeTest { 3222 3223 class LOCKABLE Foo { 3224 public: 3225 Mutex mu1_; 3226 Mutex mu2_; 3227 Mutex mu3_; 3228 int a GUARDED_BY(mu1_); 3229 int b GUARDED_BY(mu2_); 3230 int c GUARDED_BY(mu3_); 3231 3232 void lock() EXCLUSIVE_LOCK_FUNCTION(); 3233 void unlock() UNLOCK_FUNCTION(); 3234 3235 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_); 3236 void slock1() SHARED_LOCK_FUNCTION(mu1_); 3237 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_); 3238 void locklots() 3239 EXCLUSIVE_LOCK_FUNCTION(mu1_) 3240 EXCLUSIVE_LOCK_FUNCTION(mu2_) 3241 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_); 3242 3243 void unlock1() UNLOCK_FUNCTION(mu1_); 3244 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_); 3245 void unlocklots() 3246 UNLOCK_FUNCTION(mu1_) 3247 UNLOCK_FUNCTION(mu2_) 3248 UNLOCK_FUNCTION(mu1_, mu2_, mu3_); 3249 }; 3250 3251 3252 void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { } 3253 void Foo::unlock() UNLOCK_FUNCTION() { } 3254 3255 void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) { 3256 mu1_.Lock(); 3257 } 3258 3259 void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) { 3260 mu1_.ReaderLock(); 3261 } 3262 3263 void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) { 3264 mu1_.Lock(); 3265 mu2_.Lock(); 3266 mu3_.Lock(); 3267 } 3268 3269 void Foo::locklots() 3270 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_) 3271 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) { 3272 mu1_.Lock(); 3273 mu2_.Lock(); 3274 mu3_.Lock(); 3275 } 3276 3277 void Foo::unlock1() UNLOCK_FUNCTION(mu1_) { 3278 mu1_.Unlock(); 3279 } 3280 3281 void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) { 3282 mu1_.Unlock(); 3283 mu2_.Unlock(); 3284 mu3_.Unlock(); 3285 } 3286 3287 void Foo::unlocklots() 3288 UNLOCK_FUNCTION(mu1_, mu2_) 3289 UNLOCK_FUNCTION(mu2_, mu3_) { 3290 mu1_.Unlock(); 3291 mu2_.Unlock(); 3292 mu3_.Unlock(); 3293 } 3294 3295 3296 void test0() { 3297 Foo foo; 3298 foo.lock(); 3299 foo.unlock(); 3300 3301 foo.lock(); 3302 foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}} 3303 foo.unlock(); 3304 foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}} 3305 } 3306 3307 3308 void test1() { 3309 Foo foo; 3310 foo.lock1(); 3311 foo.a = 0; 3312 foo.unlock1(); 3313 3314 foo.lock1(); 3315 foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} 3316 foo.a = 0; 3317 foo.unlock1(); 3318 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} 3319 } 3320 3321 3322 int test2() { 3323 Foo foo; 3324 foo.slock1(); 3325 int d1 = foo.a; 3326 foo.unlock1(); 3327 3328 foo.slock1(); 3329 foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} 3330 int d2 = foo.a; 3331 foo.unlock1(); 3332 foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} 3333 return d1 + d2; 3334 } 3335 3336 3337 void test3() { 3338 Foo foo; 3339 foo.lock3(); 3340 foo.a = 0; 3341 foo.b = 0; 3342 foo.c = 0; 3343 foo.unlock3(); 3344 3345 foo.lock3(); 3346 foo.lock3(); // \ 3347 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \ 3348 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \ 3349 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}} 3350 foo.a = 0; 3351 foo.b = 0; 3352 foo.c = 0; 3353 foo.unlock3(); 3354 foo.unlock3(); // \ 3355 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \ 3356 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \ 3357 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}} 3358 } 3359 3360 3361 void testlots() { 3362 Foo foo; 3363 foo.locklots(); 3364 foo.a = 0; 3365 foo.b = 0; 3366 foo.c = 0; 3367 foo.unlocklots(); 3368 3369 foo.locklots(); 3370 foo.locklots(); // \ 3371 // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \ 3372 // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \ 3373 // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}} 3374 foo.a = 0; 3375 foo.b = 0; 3376 foo.c = 0; 3377 foo.unlocklots(); 3378 foo.unlocklots(); // \ 3379 // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \ 3380 // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \ 3381 // expected-warning {{releasing mutex 'foo.mu3_' that was not held}} 3382 } 3383 3384 } // end namespace DuplicateAttributeTest 3385 3386 3387 3388 namespace TryLockEqTest { 3389 3390 class Foo { 3391 Mutex mu_; 3392 int a GUARDED_BY(mu_); 3393 bool c; 3394 3395 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_); 3396 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_); 3397 void unlock() UNLOCK_FUNCTION(mu_); 3398 3399 void test1(); 3400 void test2(); 3401 }; 3402 3403 3404 void Foo::test1() { 3405 if (tryLockMutexP() == 0) { 3406 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3407 return; 3408 } 3409 a = 0; 3410 unlock(); 3411 3412 if (tryLockMutexP() != 0) { 3413 a = 0; 3414 unlock(); 3415 } 3416 3417 if (0 != tryLockMutexP()) { 3418 a = 0; 3419 unlock(); 3420 } 3421 3422 if (!(tryLockMutexP() == 0)) { 3423 a = 0; 3424 unlock(); 3425 } 3426 3427 if (tryLockMutexI() == 0) { 3428 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3429 return; 3430 } 3431 a = 0; 3432 unlock(); 3433 3434 if (0 == tryLockMutexI()) { 3435 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3436 return; 3437 } 3438 a = 0; 3439 unlock(); 3440 3441 if (tryLockMutexI() == 1) { 3442 a = 0; 3443 unlock(); 3444 } 3445 3446 if (mu_.TryLock() == false) { 3447 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3448 return; 3449 } 3450 a = 0; 3451 unlock(); 3452 3453 if (mu_.TryLock() == true) { 3454 a = 0; 3455 unlock(); 3456 } 3457 else { 3458 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3459 } 3460 3461 #if __has_feature(cxx_nullptr) 3462 if (tryLockMutexP() == nullptr) { 3463 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3464 return; 3465 } 3466 a = 0; 3467 unlock(); 3468 #endif 3469 } 3470 3471 } // end namespace TryLockEqTest 3472 3473 3474 namespace ExistentialPatternMatching { 3475 3476 class Graph { 3477 public: 3478 Mutex mu_; 3479 }; 3480 3481 void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_); 3482 void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_); 3483 3484 class Node { 3485 public: 3486 int a GUARDED_BY(&Graph::mu_); 3487 3488 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) { 3489 a = 0; 3490 } 3491 void foo2() LOCKS_EXCLUDED(&Graph::mu_); 3492 }; 3493 3494 void test() { 3495 Graph g1; 3496 Graph g2; 3497 Node n1; 3498 3499 n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}} 3500 n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}} 3501 n1.foo2(); 3502 3503 g1.mu_.Lock(); 3504 n1.a = 0; 3505 n1.foo(); 3506 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}} 3507 g1.mu_.Unlock(); 3508 3509 g2.mu_.Lock(); 3510 n1.a = 0; 3511 n1.foo(); 3512 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}} 3513 g2.mu_.Unlock(); 3514 3515 LockAllGraphs(); 3516 n1.a = 0; 3517 n1.foo(); 3518 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}} 3519 UnlockAllGraphs(); 3520 3521 LockAllGraphs(); 3522 g1.mu_.Unlock(); 3523 3524 LockAllGraphs(); 3525 g2.mu_.Unlock(); 3526 3527 LockAllGraphs(); 3528 g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}} 3529 g1.mu_.Unlock(); 3530 } 3531 3532 } // end namespace ExistentialPatternMatching 3533 3534 3535 namespace StringIgnoreTest { 3536 3537 class Foo { 3538 public: 3539 Mutex mu_; 3540 void lock() EXCLUSIVE_LOCK_FUNCTION(""); 3541 void unlock() UNLOCK_FUNCTION(""); 3542 void goober() EXCLUSIVE_LOCKS_REQUIRED(""); 3543 void roober() SHARED_LOCKS_REQUIRED(""); 3544 }; 3545 3546 3547 class Bar : public Foo { 3548 public: 3549 void bar(Foo* f) { 3550 f->unlock(); 3551 f->goober(); 3552 f->roober(); 3553 f->lock(); 3554 }; 3555 }; 3556 3557 } // end namespace StringIgnoreTest 3558 3559 3560 namespace LockReturnedScopeFix { 3561 3562 class Base { 3563 protected: 3564 struct Inner; 3565 bool c; 3566 3567 const Mutex& getLock(const Inner* i); 3568 3569 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i)); 3570 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i)); 3571 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i)); 3572 3573 void bar(Inner* i); 3574 }; 3575 3576 3577 struct Base::Inner { 3578 Mutex lock_; 3579 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_); 3580 }; 3581 3582 3583 const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) { 3584 return i->lock_; 3585 } 3586 3587 3588 void Base::foo(Inner* i) { 3589 i->doSomething(); 3590 } 3591 3592 void Base::bar(Inner* i) { 3593 if (c) { 3594 i->lock_.Lock(); 3595 unlockInner(i); 3596 } 3597 else { 3598 lockInner(i); 3599 i->lock_.Unlock(); 3600 } 3601 } 3602 3603 } // end namespace LockReturnedScopeFix 3604 3605 3606 namespace TrylockWithCleanups { 3607 3608 struct Foo { 3609 Mutex mu_; 3610 int a GUARDED_BY(mu_); 3611 }; 3612 3613 Foo* GetAndLockFoo(const MyString& s) 3614 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_); 3615 3616 static void test() { 3617 Foo* lt = GetAndLockFoo("foo"); 3618 if (!lt) return; 3619 int a = lt->a; 3620 lt->mu_.Unlock(); 3621 } 3622 3623 } // end namespace TrylockWithCleanups 3624 3625 3626 namespace UniversalLock { 3627 3628 class Foo { 3629 Mutex mu_; 3630 bool c; 3631 3632 int a GUARDED_BY(mu_); 3633 void r_foo() SHARED_LOCKS_REQUIRED(mu_); 3634 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_); 3635 3636 void test1() { 3637 int b; 3638 3639 beginNoWarnOnReads(); 3640 b = a; 3641 r_foo(); 3642 endNoWarnOnReads(); 3643 3644 beginNoWarnOnWrites(); 3645 a = 0; 3646 w_foo(); 3647 endNoWarnOnWrites(); 3648 } 3649 3650 // don't warn on joins with universal lock 3651 void test2() { 3652 if (c) { 3653 beginNoWarnOnWrites(); 3654 } 3655 a = 0; // \ 3656 // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 3657 endNoWarnOnWrites(); // \ 3658 // expected-warning {{releasing mutex '*' that was not held}} 3659 } 3660 3661 3662 // make sure the universal lock joins properly 3663 void test3() { 3664 if (c) { 3665 mu_.Lock(); 3666 beginNoWarnOnWrites(); 3667 } 3668 else { 3669 beginNoWarnOnWrites(); 3670 mu_.Lock(); 3671 } 3672 a = 0; 3673 endNoWarnOnWrites(); 3674 mu_.Unlock(); 3675 } 3676 3677 3678 // combine universal lock with other locks 3679 void test4() { 3680 beginNoWarnOnWrites(); 3681 mu_.Lock(); 3682 mu_.Unlock(); 3683 endNoWarnOnWrites(); 3684 3685 mu_.Lock(); 3686 beginNoWarnOnWrites(); 3687 endNoWarnOnWrites(); 3688 mu_.Unlock(); 3689 3690 mu_.Lock(); 3691 beginNoWarnOnWrites(); 3692 mu_.Unlock(); 3693 endNoWarnOnWrites(); 3694 } 3695 }; 3696 3697 } // end namespace UniversalLock 3698 3699 3700 namespace TemplateLockReturned { 3701 3702 template<class T> 3703 class BaseT { 3704 public: 3705 virtual void baseMethod() = 0; 3706 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; } 3707 3708 Mutex mutex_; 3709 int a GUARDED_BY(mutex_); 3710 }; 3711 3712 3713 class Derived : public BaseT<int> { 3714 public: 3715 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) { 3716 a = 0; 3717 } 3718 }; 3719 3720 } // end namespace TemplateLockReturned 3721 3722 3723 namespace ExprMatchingBugFix { 3724 3725 class Foo { 3726 public: 3727 Mutex mu_; 3728 }; 3729 3730 3731 class Bar { 3732 public: 3733 bool c; 3734 Foo* foo; 3735 Bar(Foo* f) : foo(f) { } 3736 3737 struct Nested { 3738 Foo* foo; 3739 Nested(Foo* f) : foo(f) { } 3740 3741 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_); 3742 }; 3743 3744 void test(); 3745 }; 3746 3747 3748 void Bar::test() { 3749 foo->mu_.Lock(); 3750 if (c) { 3751 Nested *n = new Nested(foo); 3752 n->unlockFoo(); 3753 } 3754 else { 3755 foo->mu_.Unlock(); 3756 } 3757 } 3758 3759 }; // end namespace ExprMatchingBugfix 3760 3761 3762 namespace ComplexNameTest { 3763 3764 class Foo { 3765 public: 3766 static Mutex mu_; 3767 3768 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 3769 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 3770 3771 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; } 3772 }; 3773 3774 class Bar { 3775 public: 3776 static Mutex mu_; 3777 3778 Bar() LOCKS_EXCLUDED(mu_) { } 3779 ~Bar() LOCKS_EXCLUDED(mu_) { } 3780 3781 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; } 3782 }; 3783 3784 3785 void test1() { 3786 Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}} 3787 int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}} 3788 } // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}} 3789 3790 3791 void test2() { 3792 Bar::mu_.Lock(); 3793 { 3794 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}} 3795 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}} 3796 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}} 3797 Bar::mu_.Unlock(); 3798 } 3799 3800 }; // end namespace ComplexNameTest 3801 3802 3803 namespace UnreachableExitTest { 3804 3805 class FemmeFatale { 3806 public: 3807 FemmeFatale(); 3808 ~FemmeFatale() __attribute__((noreturn)); 3809 }; 3810 3811 void exitNow() __attribute__((noreturn)); 3812 void exitDestruct(const MyString& ms) __attribute__((noreturn)); 3813 3814 Mutex fatalmu_; 3815 3816 void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3817 exitNow(); 3818 } 3819 3820 void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3821 FemmeFatale femme; 3822 } 3823 3824 bool c; 3825 3826 void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3827 if (c) { 3828 exitNow(); 3829 } 3830 else { 3831 FemmeFatale femme; 3832 } 3833 } 3834 3835 void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3836 exitDestruct("foo"); 3837 } 3838 3839 } // end namespace UnreachableExitTest 3840 3841 3842 namespace VirtualMethodCanonicalizationTest { 3843 3844 class Base { 3845 public: 3846 virtual Mutex* getMutex() = 0; 3847 }; 3848 3849 class Base2 : public Base { 3850 public: 3851 Mutex* getMutex(); 3852 }; 3853 3854 class Base3 : public Base2 { 3855 public: 3856 Mutex* getMutex(); 3857 }; 3858 3859 class Derived : public Base3 { 3860 public: 3861 Mutex* getMutex(); // overrides Base::getMutex() 3862 }; 3863 3864 void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { } 3865 3866 void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) { 3867 baseFun(d); 3868 } 3869 3870 } // end namespace VirtualMethodCanonicalizationTest 3871 3872 3873 namespace TemplateFunctionParamRemapTest { 3874 3875 template <class T> 3876 struct Cell { 3877 T dummy_; 3878 Mutex* mu_; 3879 }; 3880 3881 class Foo { 3882 public: 3883 template <class T> 3884 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_); 3885 3886 void test(); 3887 }; 3888 3889 template<class T> 3890 void Foo::elr(Cell<T>* c1) { } 3891 3892 void Foo::test() { 3893 Cell<int> cell; 3894 elr(&cell); // \ 3895 // expected-warning {{calling function 'elr<int>' requires holding mutex 'cell.mu_' exclusively}} 3896 } 3897 3898 3899 template<class T> 3900 void globalELR(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_); 3901 3902 template<class T> 3903 void globalELR(Cell<T>* c1) { } 3904 3905 void globalTest() { 3906 Cell<int> cell; 3907 globalELR(&cell); // \ 3908 // expected-warning {{calling function 'globalELR<int>' requires holding mutex 'cell.mu_' exclusively}} 3909 } 3910 3911 3912 template<class T> 3913 void globalELR2(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_); 3914 3915 // second declaration 3916 template<class T> 3917 void globalELR2(Cell<T>* c2); 3918 3919 template<class T> 3920 void globalELR2(Cell<T>* c3) { } 3921 3922 // re-declaration after definition 3923 template<class T> 3924 void globalELR2(Cell<T>* c4); 3925 3926 void globalTest2() { 3927 Cell<int> cell; 3928 globalELR2(&cell); // \ 3929 // expected-warning {{calling function 'globalELR2<int>' requires holding mutex 'cell.mu_' exclusively}} 3930 } 3931 3932 3933 template<class T> 3934 class FooT { 3935 public: 3936 void elr(Cell<T>* c) EXCLUSIVE_LOCKS_REQUIRED(c->mu_); 3937 }; 3938 3939 template<class T> 3940 void FooT<T>::elr(Cell<T>* c1) { } 3941 3942 void testFooT() { 3943 Cell<int> cell; 3944 FooT<int> foo; 3945 foo.elr(&cell); // \ 3946 // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}} 3947 } 3948 3949 } // end namespace TemplateFunctionParamRemapTest 3950 3951 3952 namespace SelfConstructorTest { 3953 3954 class SelfLock { 3955 public: 3956 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_); 3957 ~SelfLock() UNLOCK_FUNCTION(mu_); 3958 3959 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_); 3960 3961 Mutex mu_; 3962 }; 3963 3964 class LOCKABLE SelfLock2 { 3965 public: 3966 SelfLock2() EXCLUSIVE_LOCK_FUNCTION(); 3967 ~SelfLock2() UNLOCK_FUNCTION(); 3968 3969 void foo() EXCLUSIVE_LOCKS_REQUIRED(this); 3970 }; 3971 3972 3973 void test() { 3974 SelfLock s; 3975 s.foo(); 3976 } 3977 3978 void test2() { 3979 SelfLock2 s2; 3980 s2.foo(); 3981 } 3982 3983 } // end namespace SelfConstructorTest 3984 3985 3986 namespace MultipleAttributeTest { 3987 3988 class Foo { 3989 Mutex mu1_; 3990 Mutex mu2_; 3991 int a GUARDED_BY(mu1_); 3992 int b GUARDED_BY(mu2_); 3993 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_); 3994 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_); 3995 3996 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_) 3997 EXCLUSIVE_LOCKS_REQUIRED(mu2_); 3998 void foo2() SHARED_LOCKS_REQUIRED(mu1_) 3999 SHARED_LOCKS_REQUIRED(mu2_); 4000 void foo3() LOCKS_EXCLUDED(mu1_) 4001 LOCKS_EXCLUDED(mu2_); 4002 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_) 4003 EXCLUSIVE_LOCK_FUNCTION(mu2_); 4004 void readerlock() SHARED_LOCK_FUNCTION(mu1_) 4005 SHARED_LOCK_FUNCTION(mu2_); 4006 void unlock() UNLOCK_FUNCTION(mu1_) 4007 UNLOCK_FUNCTION(mu2_); 4008 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_) 4009 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_); 4010 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_) 4011 SHARED_TRYLOCK_FUNCTION(true, mu2_); 4012 void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_) 4013 ASSERT_EXCLUSIVE_LOCK(mu2_); 4014 4015 void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_); 4016 4017 void assertShared() ASSERT_SHARED_LOCK(mu1_) 4018 ASSERT_SHARED_LOCK(mu2_); 4019 4020 void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_); 4021 4022 void test(); 4023 void testAssert(); 4024 void testAssertShared(); 4025 }; 4026 4027 4028 void Foo::foo1() { 4029 a = 1; 4030 b = 2; 4031 } 4032 4033 void Foo::foo2() { 4034 int result = a + b; 4035 } 4036 4037 void Foo::foo3() { } 4038 void Foo::lock() { mu1_.Lock(); mu2_.Lock(); } 4039 void Foo::readerlock() { mu1_.ReaderLock(); mu2_.ReaderLock(); } 4040 void Foo::unlock() { mu1_.Unlock(); mu2_.Unlock(); } 4041 bool Foo::trylock() { return true; } 4042 bool Foo::readertrylock() { return true; } 4043 4044 4045 void Foo::test() { 4046 mu1_.Lock(); 4047 foo1(); // expected-warning {{}} 4048 c = 0; // expected-warning {{}} 4049 *d = 0; // expected-warning {{}} 4050 mu1_.Unlock(); 4051 4052 mu1_.ReaderLock(); 4053 foo2(); // expected-warning {{}} 4054 int x = c; // expected-warning {{}} 4055 int y = *d; // expected-warning {{}} 4056 mu1_.Unlock(); 4057 4058 mu2_.Lock(); 4059 foo3(); // expected-warning {{}} 4060 mu2_.Unlock(); 4061 4062 lock(); 4063 a = 0; 4064 b = 0; 4065 unlock(); 4066 4067 readerlock(); 4068 int z = a + b; 4069 unlock(); 4070 4071 if (trylock()) { 4072 a = 0; 4073 b = 0; 4074 unlock(); 4075 } 4076 4077 if (readertrylock()) { 4078 int zz = a + b; 4079 unlock(); 4080 } 4081 } 4082 4083 // Force duplication of attributes 4084 void Foo::assertBoth() { } 4085 void Foo::alsoAssertBoth() { } 4086 void Foo::assertShared() { } 4087 void Foo::alsoAssertShared() { } 4088 4089 void Foo::testAssert() { 4090 { 4091 assertBoth(); 4092 a = 0; 4093 b = 0; 4094 } 4095 { 4096 alsoAssertBoth(); 4097 a = 0; 4098 b = 0; 4099 } 4100 } 4101 4102 void Foo::testAssertShared() { 4103 { 4104 assertShared(); 4105 int zz = a + b; 4106 } 4107 4108 { 4109 alsoAssertShared(); 4110 int zz = a + b; 4111 } 4112 } 4113 4114 4115 } // end namespace MultipleAttributeTest 4116 4117 4118 namespace GuardedNonPrimitiveTypeTest { 4119 4120 4121 class Data { 4122 public: 4123 Data(int i) : dat(i) { } 4124 4125 int getValue() const { return dat; } 4126 void setValue(int i) { dat = i; } 4127 4128 int operator[](int i) const { return dat; } 4129 int& operator[](int i) { return dat; } 4130 4131 void operator()() { } 4132 4133 private: 4134 int dat; 4135 }; 4136 4137 4138 class DataCell { 4139 public: 4140 DataCell(const Data& d) : dat(d) { } 4141 4142 private: 4143 Data dat; 4144 }; 4145 4146 4147 void showDataCell(const DataCell& dc); 4148 4149 4150 class Foo { 4151 public: 4152 // method call tests 4153 void test() { 4154 data_.setValue(0); // FIXME -- should be writing \ 4155 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4156 int a = data_.getValue(); // \ 4157 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4158 4159 datap1_->setValue(0); // FIXME -- should be writing \ 4160 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} 4161 a = datap1_->getValue(); // \ 4162 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} 4163 4164 datap2_->setValue(0); // FIXME -- should be writing \ 4165 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4166 a = datap2_->getValue(); // \ 4167 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4168 4169 (*datap2_).setValue(0); // FIXME -- should be writing \ 4170 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4171 a = (*datap2_).getValue(); // \ 4172 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4173 4174 mu_.Lock(); 4175 data_.setValue(1); 4176 datap1_->setValue(1); 4177 datap2_->setValue(1); 4178 mu_.Unlock(); 4179 4180 mu_.ReaderLock(); 4181 a = data_.getValue(); 4182 datap1_->setValue(0); // reads datap1_, writes *datap1_ 4183 a = datap1_->getValue(); 4184 a = datap2_->getValue(); 4185 mu_.Unlock(); 4186 } 4187 4188 // operator tests 4189 void test2() { 4190 data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} 4191 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \ 4192 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4193 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \ 4194 // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4195 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \ 4196 // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} 4197 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \ 4198 // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4199 4200 data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4201 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4202 4203 data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4204 } 4205 4206 // const operator tests 4207 void test3() const { 4208 Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4209 4210 //FIXME 4211 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4212 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}} 4213 4214 int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}} 4215 } 4216 4217 private: 4218 Mutex mu_; 4219 Data data_ GUARDED_BY(mu_); 4220 Data* datap1_ GUARDED_BY(mu_); 4221 Data* datap2_ PT_GUARDED_BY(mu_); 4222 }; 4223 4224 } // end namespace GuardedNonPrimitiveTypeTest 4225 4226 4227 namespace GuardedNonPrimitive_MemberAccess { 4228 4229 class Cell { 4230 public: 4231 Cell(int i); 4232 4233 void cellMethod(); 4234 4235 int a; 4236 }; 4237 4238 4239 class Foo { 4240 public: 4241 int a; 4242 Cell c GUARDED_BY(cell_mu_); 4243 Cell* cp PT_GUARDED_BY(cell_mu_); 4244 4245 void myMethod(); 4246 4247 Mutex cell_mu_; 4248 }; 4249 4250 4251 class Bar { 4252 private: 4253 Mutex mu_; 4254 Foo foo GUARDED_BY(mu_); 4255 Foo* foop PT_GUARDED_BY(mu_); 4256 4257 void test() { 4258 foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} 4259 4260 int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} 4261 foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}} 4262 4263 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} 4264 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}} 4265 4266 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} 4267 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}} 4268 4269 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \ 4270 // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}} 4271 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \ 4272 // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}} 4273 4274 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \ 4275 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}} 4276 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \ 4277 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}} 4278 4279 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \ 4280 // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}} 4281 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \ 4282 // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}} 4283 }; 4284 }; 4285 4286 } // namespace GuardedNonPrimitive_MemberAccess 4287 4288 4289 namespace TestThrowExpr { 4290 4291 class Foo { 4292 Mutex mu_; 4293 4294 bool hasError(); 4295 4296 void test() { 4297 mu_.Lock(); 4298 if (hasError()) { 4299 throw "ugly"; 4300 } 4301 mu_.Unlock(); 4302 } 4303 }; 4304 4305 } // end namespace TestThrowExpr 4306 4307 4308 namespace UnevaluatedContextTest { 4309 4310 // parse attribute expressions in an unevaluated context. 4311 4312 static inline Mutex* getMutex1(); 4313 static inline Mutex* getMutex2(); 4314 4315 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1()); 4316 4317 void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2()); 4318 4319 } // end namespace UnevaluatedContextTest 4320 4321 4322 namespace LockUnlockFunctionTest { 4323 4324 // Check built-in lock functions 4325 class LOCKABLE MyLockable { 4326 public: 4327 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); } 4328 void readerLock() SHARED_LOCK_FUNCTION() { mu_.ReaderLock(); } 4329 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); } 4330 4331 private: 4332 Mutex mu_; 4333 }; 4334 4335 4336 class Foo { 4337 public: 4338 // Correct lock/unlock functions 4339 void lock() EXCLUSIVE_LOCK_FUNCTION(mu_) { 4340 mu_.Lock(); 4341 } 4342 4343 void readerLock() SHARED_LOCK_FUNCTION(mu_) { 4344 mu_.ReaderLock(); 4345 } 4346 4347 void unlock() UNLOCK_FUNCTION(mu_) { 4348 mu_.Unlock(); 4349 } 4350 4351 void unlockExclusive() EXCLUSIVE_UNLOCK_FUNCTION(mu_) { 4352 mu_.Unlock(); 4353 } 4354 4355 void unlockShared() SHARED_UNLOCK_FUNCTION(mu_) { 4356 mu_.ReaderUnlock(); 4357 } 4358 4359 // Check failure to lock. 4360 void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4361 mu2_.Lock(); 4362 mu2_.Unlock(); 4363 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} 4364 4365 void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4366 mu2_.Lock(); 4367 mu2_.Unlock(); 4368 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} 4369 4370 void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4371 mu2_.Lock(); 4372 mu2_.Unlock(); 4373 } // expected-warning {{mutex 'mu_' is still held at the end of function}} 4374 4375 // Check locking the wrong thing. 4376 void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4377 mu2_.Lock(); // expected-note {{mutex acquired here}} 4378 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \ 4379 // expected-warning {{mutex 'mu2_' is still held at the end of function}} 4380 4381 4382 void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4383 mu2_.ReaderLock(); // expected-note {{mutex acquired here}} 4384 } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \ 4385 // expected-warning {{mutex 'mu2_' is still held at the end of function}} 4386 4387 4388 void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}} 4389 mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}} 4390 } // expected-warning {{mutex 'mu_' is still held at the end of function}} 4391 4392 private: 4393 Mutex mu_; 4394 Mutex mu2_; 4395 }; 4396 4397 } // end namespace LockUnlockFunctionTest 4398 4399 4400 namespace AssertHeldTest { 4401 4402 class Foo { 4403 public: 4404 int c; 4405 int a GUARDED_BY(mu_); 4406 Mutex mu_; 4407 4408 void test1() { 4409 mu_.AssertHeld(); 4410 int b = a; 4411 a = 0; 4412 } 4413 4414 void test2() { 4415 mu_.AssertReaderHeld(); 4416 int b = a; 4417 a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 4418 } 4419 4420 void test3() { 4421 if (c) { 4422 mu_.AssertHeld(); 4423 } 4424 else { 4425 mu_.AssertHeld(); 4426 } 4427 int b = a; 4428 a = 0; 4429 } 4430 4431 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 4432 mu_.AssertHeld(); 4433 int b = a; 4434 a = 0; 4435 } 4436 4437 void test5() UNLOCK_FUNCTION(mu_) { 4438 mu_.AssertHeld(); 4439 mu_.Unlock(); 4440 } 4441 4442 void test6() { 4443 mu_.AssertHeld(); 4444 mu_.Unlock(); 4445 } // should this be a warning? 4446 4447 void test7() { 4448 if (c) { 4449 mu_.AssertHeld(); 4450 } 4451 else { 4452 mu_.Lock(); 4453 } 4454 int b = a; 4455 a = 0; 4456 mu_.Unlock(); 4457 } 4458 4459 void test8() { 4460 if (c) { 4461 mu_.Lock(); 4462 } 4463 else { 4464 mu_.AssertHeld(); 4465 } 4466 int b = a; 4467 a = 0; 4468 mu_.Unlock(); 4469 } 4470 4471 void test9() { 4472 if (c) { 4473 mu_.AssertHeld(); 4474 } 4475 else { 4476 mu_.Lock(); // expected-note {{mutex acquired here}} 4477 } 4478 } // expected-warning {{mutex 'mu_' is still held at the end of function}} 4479 4480 void test10() { 4481 if (c) { 4482 mu_.Lock(); // expected-note {{mutex acquired here}} 4483 } 4484 else { 4485 mu_.AssertHeld(); 4486 } 4487 } // expected-warning {{mutex 'mu_' is still held at the end of function}} 4488 4489 void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_); 4490 4491 void test11() { 4492 assertMu(); 4493 int b = a; 4494 a = 0; 4495 } 4496 }; 4497 4498 } // end namespace AssertHeldTest 4499 4500 4501 namespace LogicalConditionalTryLock { 4502 4503 class Foo { 4504 public: 4505 Mutex mu; 4506 int a GUARDED_BY(mu); 4507 bool c; 4508 4509 bool newc(); 4510 4511 void test1() { 4512 if (c && mu.TryLock()) { 4513 a = 0; 4514 mu.Unlock(); 4515 } 4516 } 4517 4518 void test2() { 4519 bool b = mu.TryLock(); 4520 if (c && b) { 4521 a = 0; 4522 mu.Unlock(); 4523 } 4524 } 4525 4526 void test3() { 4527 if (c || !mu.TryLock()) 4528 return; 4529 a = 0; 4530 mu.Unlock(); 4531 } 4532 4533 void test4() { 4534 while (c && mu.TryLock()) { 4535 a = 0; 4536 c = newc(); 4537 mu.Unlock(); 4538 } 4539 } 4540 4541 void test5() { 4542 while (c) { 4543 if (newc() || !mu.TryLock()) 4544 break; 4545 a = 0; 4546 mu.Unlock(); 4547 } 4548 } 4549 4550 void test6() { 4551 mu.Lock(); 4552 do { 4553 a = 0; 4554 mu.Unlock(); 4555 } while (newc() && mu.TryLock()); 4556 } 4557 4558 void test7() { 4559 for (bool b = mu.TryLock(); c && b;) { 4560 a = 0; 4561 mu.Unlock(); 4562 } 4563 } 4564 4565 void test8() { 4566 if (c && newc() && mu.TryLock()) { 4567 a = 0; 4568 mu.Unlock(); 4569 } 4570 } 4571 4572 void test9() { 4573 if (!(c && newc() && mu.TryLock())) 4574 return; 4575 a = 0; 4576 mu.Unlock(); 4577 } 4578 4579 void test10() { 4580 if (!(c || !mu.TryLock())) { 4581 a = 0; 4582 mu.Unlock(); 4583 } 4584 } 4585 }; 4586 4587 } // end namespace LogicalConditionalTryLock 4588 4589 4590 4591 namespace PtGuardedByTest { 4592 4593 void doSomething(); 4594 4595 class Cell { 4596 public: 4597 int a; 4598 }; 4599 4600 4601 // This mainly duplicates earlier tests, but just to make sure... 4602 class PtGuardedBySanityTest { 4603 Mutex mu1; 4604 Mutex mu2; 4605 int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 4606 Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 4607 int sa[10] GUARDED_BY(mu1); 4608 Cell sc[10] GUARDED_BY(mu1); 4609 4610 void test1() { 4611 mu1.Lock(); 4612 if (a == 0) doSomething(); // OK, we don't dereference. 4613 a = 0; 4614 c = 0; 4615 if (sa[0] == 42) doSomething(); 4616 sa[0] = 57; 4617 if (sc[0].a == 42) doSomething(); 4618 sc[0].a = 57; 4619 mu1.Unlock(); 4620 } 4621 4622 void test2() { 4623 mu1.ReaderLock(); 4624 if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}} 4625 *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}} 4626 4627 if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}} 4628 c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}} 4629 4630 if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}} 4631 (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}} 4632 4633 if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}} 4634 a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}} 4635 if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}} 4636 c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}} 4637 mu1.Unlock(); 4638 } 4639 4640 void test3() { 4641 mu2.Lock(); 4642 if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}} 4643 *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}} 4644 4645 if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4646 c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4647 4648 if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4649 (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4650 4651 if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}} 4652 a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}} 4653 if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4654 c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}} 4655 mu2.Unlock(); 4656 } 4657 4658 void test4() { // Literal arrays 4659 if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}} 4660 sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}} 4661 if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}} 4662 sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}} 4663 4664 if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}} 4665 *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}} 4666 if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}} 4667 (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}} 4668 if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}} 4669 sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}} 4670 } 4671 4672 void test5() { 4673 mu1.ReaderLock(); // OK -- correct use. 4674 mu2.Lock(); 4675 if (*a == 0) doSomething(); 4676 *a = 0; 4677 4678 if (c->a == 0) doSomething(); 4679 c->a = 0; 4680 4681 if ((*c).a == 0) doSomething(); 4682 (*c).a = 0; 4683 mu2.Unlock(); 4684 mu1.Unlock(); 4685 } 4686 }; 4687 4688 4689 class SmartPtr_PtGuardedBy_Test { 4690 Mutex mu1; 4691 Mutex mu2; 4692 SmartPtr<int> sp GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 4693 SmartPtr<Cell> sq GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 4694 4695 void test1() { 4696 mu1.ReaderLock(); 4697 mu2.Lock(); 4698 4699 sp.get(); 4700 if (*sp == 0) doSomething(); 4701 *sp = 0; 4702 sq->a = 0; 4703 4704 if (sp[0] == 0) doSomething(); 4705 sp[0] = 0; 4706 4707 mu2.Unlock(); 4708 mu1.Unlock(); 4709 } 4710 4711 void test2() { 4712 mu2.Lock(); 4713 4714 sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}} 4715 if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}} 4716 *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}} 4717 sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}} 4718 4719 if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}} 4720 sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}} 4721 if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}} 4722 sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}} 4723 4724 mu2.Unlock(); 4725 } 4726 4727 void test3() { 4728 mu1.Lock(); 4729 4730 sp.get(); 4731 if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}} 4732 *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}} 4733 sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}} 4734 4735 if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}} 4736 sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}} 4737 if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}} 4738 sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}} 4739 4740 mu1.Unlock(); 4741 } 4742 }; 4743 4744 } // end namespace PtGuardedByTest 4745 4746 4747 namespace NonMemberCalleeICETest { 4748 4749 class A { 4750 void Run() { 4751 (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}} 4752 } 4753 4754 void RunHelper() EXCLUSIVE_LOCKS_REQUIRED(M); 4755 Mutex M; 4756 }; 4757 4758 } // end namespace NonMemberCalleeICETest 4759 4760 4761 namespace pt_guard_attribute_type { 4762 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}} 4763 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}} 4764 4765 void test() { 4766 int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}} 4767 int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}} 4768 4769 typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to}} 4770 typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to}} 4771 } 4772 } // end namespace pt_guard_attribute_type 4773 4774 4775 namespace ThreadAttributesOnLambdas { 4776 4777 class Foo { 4778 Mutex mu_; 4779 4780 void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_); 4781 4782 void test() { 4783 auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 4784 LockedFunction(); 4785 }; 4786 4787 auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS { 4788 LockedFunction(); 4789 }; 4790 4791 auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) { 4792 mu_.Lock(); 4793 }; 4794 4795 func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}} 4796 func2(); 4797 func3(); 4798 mu_.Unlock(); 4799 } 4800 }; 4801 4802 } // end namespace ThreadAttributesOnLambdas 4803 4804 4805 4806 namespace AttributeExpressionCornerCases { 4807 4808 class Foo { 4809 int a GUARDED_BY(getMu()); 4810 4811 Mutex* getMu() LOCK_RETURNED(""); 4812 Mutex* getUniv() LOCK_RETURNED("*"); 4813 4814 void test1() { 4815 a = 0; 4816 } 4817 4818 void test2() EXCLUSIVE_LOCKS_REQUIRED(getUniv()) { 4819 a = 0; 4820 } 4821 4822 void foo(Mutex* mu) EXCLUSIVE_LOCKS_REQUIRED(mu); 4823 4824 void test3() { 4825 foo(nullptr); 4826 } 4827 }; 4828 4829 4830 class MapTest { 4831 struct MuCell { Mutex* mu; }; 4832 4833 MyMap<MyString, Mutex*> map; 4834 MyMap<MyString, MuCell> mapCell; 4835 4836 int a GUARDED_BY(map["foo"]); 4837 int b GUARDED_BY(mapCell["foo"].mu); 4838 4839 void test() { 4840 map["foo"]->Lock(); 4841 a = 0; 4842 map["foo"]->Unlock(); 4843 } 4844 4845 void test2() { 4846 mapCell["foo"].mu->Lock(); 4847 b = 0; 4848 mapCell["foo"].mu->Unlock(); 4849 } 4850 }; 4851 4852 4853 class PreciseSmartPtr { 4854 SmartPtr<Mutex> mu; 4855 int val GUARDED_BY(mu); 4856 4857 static bool compare(PreciseSmartPtr& a, PreciseSmartPtr &b) { 4858 a.mu->Lock(); 4859 bool result = (a.val == b.val); // expected-warning {{reading variable 'val' requires holding mutex 'b.mu'}} \ 4860 // expected-note {{found near match 'a.mu'}} 4861 a.mu->Unlock(); 4862 return result; 4863 } 4864 }; 4865 4866 4867 class SmartRedeclare { 4868 SmartPtr<Mutex> mu; 4869 int val GUARDED_BY(mu); 4870 4871 void test() EXCLUSIVE_LOCKS_REQUIRED(mu); 4872 void test2() EXCLUSIVE_LOCKS_REQUIRED(mu.get()); 4873 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu.get()); 4874 }; 4875 4876 4877 void SmartRedeclare::test() EXCLUSIVE_LOCKS_REQUIRED(mu.get()) { 4878 val = 0; 4879 } 4880 4881 void SmartRedeclare::test2() EXCLUSIVE_LOCKS_REQUIRED(mu) { 4882 val = 0; 4883 } 4884 4885 void SmartRedeclare::test3() { 4886 val = 0; 4887 } 4888 4889 4890 namespace CustomMutex { 4891 4892 4893 class LOCKABLE BaseMutex { }; 4894 class DerivedMutex : public BaseMutex { }; 4895 4896 void customLock(const BaseMutex *m) EXCLUSIVE_LOCK_FUNCTION(m); 4897 void customUnlock(const BaseMutex *m) UNLOCK_FUNCTION(m); 4898 4899 static struct DerivedMutex custMu; 4900 4901 static void doSomethingRequiringLock() EXCLUSIVE_LOCKS_REQUIRED(custMu) { } 4902 4903 void customTest() { 4904 customLock(reinterpret_cast<BaseMutex*>(&custMu)); // ignore casts 4905 doSomethingRequiringLock(); 4906 customUnlock(reinterpret_cast<BaseMutex*>(&custMu)); 4907 } 4908 4909 } // end namespace CustomMutex 4910 4911 } // end AttributeExpressionCornerCases 4912 4913 4914 namespace ScopedLockReturnedInvalid { 4915 4916 class Opaque; 4917 4918 Mutex* getMutex(Opaque* o) LOCK_RETURNED(""); 4919 4920 void test(Opaque* o) { 4921 MutexLock lock(getMutex(o)); 4922 } 4923 4924 } // end namespace ScopedLockReturnedInvalid 4925 4926 4927 namespace NegativeRequirements { 4928 4929 class Bar { 4930 Mutex mu; 4931 int a GUARDED_BY(mu); 4932 4933 public: 4934 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 4935 mu.Lock(); 4936 a = 0; 4937 mu.Unlock(); 4938 } 4939 }; 4940 4941 4942 class Foo { 4943 Mutex mu; 4944 int a GUARDED_BY(mu); 4945 4946 public: 4947 void foo() { 4948 mu.Lock(); // warning? needs !mu? 4949 baz(); // expected-warning {{cannot call function 'baz' while mutex 'mu' is held}} 4950 bar(); 4951 mu.Unlock(); 4952 } 4953 4954 void bar() { 4955 bar2(); // expected-warning {{calling function 'bar2' requires holding '!mu'}} 4956 } 4957 4958 void bar2() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 4959 baz(); 4960 } 4961 4962 void baz() EXCLUSIVE_LOCKS_REQUIRED(!mu) { 4963 mu.Lock(); 4964 a = 0; 4965 mu.Unlock(); 4966 } 4967 4968 void test() { 4969 Bar b; 4970 b.baz(); // no warning -- in different class. 4971 } 4972 }; 4973 4974 } // end namespace NegativeRequirements 4975 4976 4977 namespace NegativeThreadRoles { 4978 4979 typedef int __attribute__((capability("role"))) ThreadRole; 4980 4981 void acquire(ThreadRole R) EXCLUSIVE_LOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {} 4982 void release(ThreadRole R) UNLOCK_FUNCTION(R) NO_THREAD_SAFETY_ANALYSIS {} 4983 4984 ThreadRole FlightControl, Logger; 4985 4986 extern void enque_log_msg(const char *msg); 4987 void log_msg(const char *msg) { 4988 enque_log_msg(msg); 4989 } 4990 4991 void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl))) {} 4992 void dispatch_log2(const char *msg) __attribute__((requires_capability(Logger))) {} 4993 4994 void flight_control_entry(void) __attribute__((requires_capability(FlightControl))) { 4995 dispatch_log("wrong"); /* expected-warning {{cannot call function 'dispatch_log' while mutex 'FlightControl' is held}} */ 4996 dispatch_log2("also wrong"); /* expected-warning {{calling function 'dispatch_log2' requires holding role 'Logger' exclusively}} */ 4997 } 4998 4999 void spawn_fake_flight_control_thread(void) { 5000 acquire(FlightControl); 5001 flight_control_entry(); 5002 release(FlightControl); 5003 } 5004 5005 extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger))); 5006 void logger_entry(void) __attribute__((requires_capability(Logger))) { 5007 const char *msg; 5008 5009 while ((msg = deque_log_msg())) { 5010 dispatch_log(msg); 5011 } 5012 } 5013 5014 void spawn_fake_logger_thread(void) { 5015 acquire(Logger); 5016 logger_entry(); 5017 release(Logger); 5018 } 5019 5020 int main(void) { 5021 spawn_fake_flight_control_thread(); 5022 spawn_fake_logger_thread(); 5023 5024 for (;;) 5025 ; /* Pretend to dispatch things. */ 5026 5027 return 0; 5028 } 5029 5030 } // end namespace NegativeThreadRoles 5031 5032 5033 namespace AssertSharedExclusive { 5034 5035 void doSomething(); 5036 5037 class Foo { 5038 Mutex mu; 5039 int a GUARDED_BY(mu); 5040 5041 void test() SHARED_LOCKS_REQUIRED(mu) { 5042 mu.AssertHeld(); 5043 if (a > 0) 5044 doSomething(); 5045 } 5046 }; 5047 5048 } // end namespace AssertSharedExclusive 5049 5050 5051 namespace RangeBasedForAndReferences { 5052 5053 class Foo { 5054 struct MyStruct { 5055 int a; 5056 }; 5057 5058 Mutex mu; 5059 int a GUARDED_BY(mu); 5060 MyContainer<int> cntr GUARDED_BY(mu); 5061 MyStruct s GUARDED_BY(mu); 5062 int arr[10] GUARDED_BY(mu); 5063 5064 void nonref_test() { 5065 int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}} 5066 b = 0; // no warning 5067 } 5068 5069 void auto_test() { 5070 auto b = a; // expected-warning {{reading variable 'a' requires holding mutex 'mu'}} 5071 b = 0; // no warning 5072 auto &c = a; // no warning 5073 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} 5074 } 5075 5076 void ref_test() { 5077 int &b = a; 5078 int &c = b; 5079 int &d = c; 5080 b = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} 5081 c = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} 5082 d = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}} 5083 5084 MyStruct &rs = s; 5085 rs.a = 0; // expected-warning {{writing variable 's' requires holding mutex 'mu' exclusively}} 5086 5087 int (&rarr)[10] = arr; 5088 rarr[2] = 0; // expected-warning {{writing variable 'arr' requires holding mutex 'mu' exclusively}} 5089 } 5090 5091 void ptr_test() { 5092 int *b = &a; 5093 *b = 0; // no expected warning yet 5094 } 5095 5096 void for_test() { 5097 int total = 0; 5098 for (int i : cntr) { // expected-warning2 {{reading variable 'cntr' requires holding mutex 'mu'}} 5099 total += i; 5100 } 5101 } 5102 }; 5103 5104 5105 } // end namespace RangeBasedForAndReferences 5106 5107 5108 5109 namespace PassByRefTest { 5110 5111 class Foo { 5112 public: 5113 Foo() : a(0), b(0) { } 5114 5115 int a; 5116 int b; 5117 5118 void operator+(const Foo& f); 5119 5120 void operator[](const Foo& g); 5121 5122 void operator()(); 5123 }; 5124 5125 template<class T> 5126 T&& mymove(T& f); 5127 5128 5129 // test top-level functions 5130 void copy(Foo f); 5131 void write1(Foo& f); 5132 void write2(int a, Foo& f); 5133 void read1(const Foo& f); 5134 void read2(int a, const Foo& f); 5135 void destroy(Foo&& f); 5136 5137 void operator/(const Foo& f, const Foo& g); 5138 void operator*(const Foo& f, const Foo& g); 5139 5140 // Test constructors. 5141 struct FooRead { 5142 FooRead(const Foo &); 5143 }; 5144 struct FooWrite { 5145 FooWrite(Foo &); 5146 }; 5147 5148 // Test variadic functions 5149 template<typename... T> 5150 void copyVariadic(T...) {} 5151 template<typename... T> 5152 void writeVariadic(T&...) {} 5153 template<typename... T> 5154 void readVariadic(const T&...) {} 5155 5156 void copyVariadicC(int, ...); 5157 5158 class Bar { 5159 public: 5160 Mutex mu; 5161 Foo foo GUARDED_BY(mu); 5162 Foo foo2 GUARDED_BY(mu); 5163 Foo* foop PT_GUARDED_BY(mu); 5164 SmartPtr<Foo> foosp PT_GUARDED_BY(mu); 5165 5166 // test methods. 5167 void mwrite1(Foo& f); 5168 void mwrite2(int a, Foo& f); 5169 void mread1(const Foo& f); 5170 void mread2(int a, const Foo& f); 5171 5172 // static methods 5173 static void smwrite1(Foo& f); 5174 static void smwrite2(int a, Foo& f); 5175 static void smread1(const Foo& f); 5176 static void smread2(int a, const Foo& f); 5177 5178 void operator<<(const Foo& f); 5179 5180 void test1() { 5181 copy(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} 5182 write1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5183 write2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5184 read1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5185 read2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5186 destroy(mymove(foo)); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5187 5188 copyVariadic(foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} 5189 readVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5190 writeVariadic(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5191 copyVariadicC(1, foo); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} 5192 5193 FooRead reader(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5194 FooWrite writer(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5195 5196 mwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5197 mwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5198 mread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5199 mread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5200 5201 smwrite1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5202 smwrite2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5203 smread1(foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5204 smread2(10, foo); // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5205 5206 foo + foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \ 5207 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} 5208 foo / foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \ 5209 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} 5210 foo * foo2; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \ 5211 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} 5212 foo[foo2]; // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} \ 5213 // expected-warning {{passing variable 'foo2' by reference requires holding mutex 'mu'}} 5214 foo(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu'}} 5215 (*this) << foo; // expected-warning {{passing variable 'foo' by reference requires holding mutex 'mu'}} 5216 5217 copy(*foop); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu'}} 5218 write1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}} 5219 write2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}} 5220 read1(*foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}} 5221 read2(10, *foop); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}} 5222 destroy(mymove(*foop)); // expected-warning {{passing the value that 'foop' points to by reference requires holding mutex 'mu'}} 5223 5224 copy(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5225 write1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5226 write2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5227 read1(*foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5228 read2(10, *foosp); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5229 destroy(mymove(*foosp)); // expected-warning {{reading the value pointed to by 'foosp' requires holding mutex 'mu'}} 5230 5231 // TODO -- these require better smart pointer handling. 5232 copy(*foosp.get()); 5233 write1(*foosp.get()); 5234 write2(10, *foosp.get()); 5235 read1(*foosp.get()); 5236 read2(10, *foosp.get()); 5237 destroy(mymove(*foosp.get())); 5238 } 5239 }; 5240 5241 5242 } // end namespace PassByRefTest 5243 5244 5245 namespace AcquiredBeforeAfterText { 5246 5247 class Foo { 5248 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3); 5249 Mutex mu2; 5250 Mutex mu3; 5251 5252 void test1() { 5253 mu1.Lock(); 5254 mu2.Lock(); 5255 mu3.Lock(); 5256 5257 mu3.Unlock(); 5258 mu2.Unlock(); 5259 mu1.Unlock(); 5260 } 5261 5262 void test2() { 5263 mu2.Lock(); 5264 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} 5265 mu1.Unlock(); 5266 mu2.Unlock(); 5267 } 5268 5269 void test3() { 5270 mu3.Lock(); 5271 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} 5272 mu1.Unlock(); 5273 mu3.Unlock(); 5274 } 5275 5276 void test4() EXCLUSIVE_LOCKS_REQUIRED(mu1) { 5277 mu2.Lock(); 5278 mu2.Unlock(); 5279 } 5280 5281 void test5() EXCLUSIVE_LOCKS_REQUIRED(mu2) { 5282 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} 5283 mu1.Unlock(); 5284 } 5285 5286 void test6() EXCLUSIVE_LOCKS_REQUIRED(mu2) { 5287 mu1.AssertHeld(); 5288 } 5289 5290 void test7() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2, mu3) { } 5291 5292 void test8() EXCLUSIVE_LOCKS_REQUIRED(mu3, mu2, mu1) { } 5293 }; 5294 5295 5296 class Foo2 { 5297 Mutex mu1; 5298 Mutex mu2 ACQUIRED_AFTER(mu1); 5299 Mutex mu3 ACQUIRED_AFTER(mu1); 5300 5301 void test1() { 5302 mu1.Lock(); 5303 mu2.Lock(); 5304 mu3.Lock(); 5305 5306 mu3.Unlock(); 5307 mu2.Unlock(); 5308 mu1.Unlock(); 5309 } 5310 5311 void test2() { 5312 mu2.Lock(); 5313 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} 5314 mu1.Unlock(); 5315 mu2.Unlock(); 5316 } 5317 5318 void test3() { 5319 mu3.Lock(); 5320 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} 5321 mu1.Unlock(); 5322 mu3.Unlock(); 5323 } 5324 }; 5325 5326 5327 class Foo3 { 5328 Mutex mu1 ACQUIRED_BEFORE(mu2); 5329 Mutex mu2; 5330 Mutex mu3 ACQUIRED_AFTER(mu2) ACQUIRED_BEFORE(mu4); 5331 Mutex mu4; 5332 5333 void test1() { 5334 mu1.Lock(); 5335 mu2.Lock(); 5336 mu3.Lock(); 5337 mu4.Lock(); 5338 5339 mu4.Unlock(); 5340 mu3.Unlock(); 5341 mu2.Unlock(); 5342 mu1.Unlock(); 5343 } 5344 5345 void test2() { 5346 mu4.Lock(); 5347 mu2.Lock(); // expected-warning {{mutex 'mu2' must be acquired before 'mu4'}} 5348 5349 mu2.Unlock(); 5350 mu4.Unlock(); 5351 } 5352 5353 void test3() { 5354 mu4.Lock(); 5355 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu4'}} 5356 5357 mu1.Unlock(); 5358 mu4.Unlock(); 5359 } 5360 5361 void test4() { 5362 mu3.Lock(); 5363 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu3'}} 5364 5365 mu1.Unlock(); 5366 mu3.Unlock(); 5367 } 5368 }; 5369 5370 5371 // Test transitive DAG traversal with AFTER 5372 class Foo4 { 5373 Mutex mu1; 5374 Mutex mu2 ACQUIRED_AFTER(mu1); 5375 Mutex mu3 ACQUIRED_AFTER(mu1); 5376 Mutex mu4 ACQUIRED_AFTER(mu2, mu3); 5377 Mutex mu5 ACQUIRED_AFTER(mu4); 5378 Mutex mu6 ACQUIRED_AFTER(mu4); 5379 Mutex mu7 ACQUIRED_AFTER(mu5, mu6); 5380 Mutex mu8 ACQUIRED_AFTER(mu7); 5381 5382 void test() { 5383 mu8.Lock(); 5384 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}} 5385 mu1.Unlock(); 5386 mu8.Unlock(); 5387 } 5388 }; 5389 5390 5391 // Test transitive DAG traversal with BEFORE 5392 class Foo5 { 5393 Mutex mu1 ACQUIRED_BEFORE(mu2, mu3); 5394 Mutex mu2 ACQUIRED_BEFORE(mu4); 5395 Mutex mu3 ACQUIRED_BEFORE(mu4); 5396 Mutex mu4 ACQUIRED_BEFORE(mu5, mu6); 5397 Mutex mu5 ACQUIRED_BEFORE(mu7); 5398 Mutex mu6 ACQUIRED_BEFORE(mu7); 5399 Mutex mu7 ACQUIRED_BEFORE(mu8); 5400 Mutex mu8; 5401 5402 void test() { 5403 mu8.Lock(); 5404 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu8'}} 5405 mu1.Unlock(); 5406 mu8.Unlock(); 5407 } 5408 }; 5409 5410 5411 class Foo6 { 5412 Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}} 5413 Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}} 5414 Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}} 5415 5416 Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}} 5417 Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}} 5418 5419 void test0() { 5420 mu_a.Lock(); 5421 mu_b.Lock(); 5422 mu_b.Unlock(); 5423 mu_a.Unlock(); 5424 } 5425 5426 void test1a() { 5427 mu1.Lock(); 5428 mu1.Unlock(); 5429 } 5430 5431 void test1b() { 5432 mu1.Lock(); 5433 mu_a.Lock(); 5434 mu_b.Lock(); 5435 mu_b.Unlock(); 5436 mu_a.Unlock(); 5437 mu1.Unlock(); 5438 } 5439 5440 void test() { 5441 mu2.Lock(); 5442 mu2.Unlock(); 5443 } 5444 5445 void test3() { 5446 mu3.Lock(); 5447 mu3.Unlock(); 5448 } 5449 }; 5450 5451 } // end namespace AcquiredBeforeAfterTest 5452 5453 5454 namespace ScopedAdoptTest { 5455 5456 class Foo { 5457 Mutex mu; 5458 int a GUARDED_BY(mu); 5459 int b; 5460 5461 void test1() EXCLUSIVE_UNLOCK_FUNCTION(mu) { 5462 MutexLock slock(&mu, true); 5463 a = 0; 5464 } 5465 5466 void test2() SHARED_UNLOCK_FUNCTION(mu) { 5467 ReaderMutexLock slock(&mu, true); 5468 b = a; 5469 } 5470 5471 void test3() EXCLUSIVE_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}} 5472 MutexLock slock(&mu, true); 5473 a = 0; 5474 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}} 5475 5476 void test4() SHARED_LOCKS_REQUIRED(mu) { // expected-note {{mutex acquired here}} 5477 ReaderMutexLock slock(&mu, true); 5478 b = a; 5479 } // expected-warning {{expecting mutex 'mu' to be held at the end of function}} 5480 5481 }; 5482 5483 } // end namespace ScopedAdoptTest 5484 5485 5486 namespace TestReferenceNoThreadSafetyAnalysis { 5487 5488 #define TS_UNCHECKED_READ(x) ts_unchecked_read(x) 5489 5490 // Takes a reference to a guarded data member, and returns an unguarded 5491 // reference. 5492 template <class T> 5493 inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS { 5494 return v; 5495 } 5496 5497 template <class T> 5498 inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS { 5499 return v; 5500 } 5501 5502 5503 class Foo { 5504 public: 5505 Foo(): a(0) { } 5506 5507 int a; 5508 }; 5509 5510 5511 class Bar { 5512 public: 5513 Bar() : a(0) { } 5514 5515 Mutex mu; 5516 int a GUARDED_BY(mu); 5517 Foo foo GUARDED_BY(mu); 5518 }; 5519 5520 5521 void test() { 5522 Bar bar; 5523 const Bar cbar; 5524 5525 int a = TS_UNCHECKED_READ(bar.a); // nowarn 5526 TS_UNCHECKED_READ(bar.a) = 1; // nowarn 5527 5528 int b = TS_UNCHECKED_READ(bar.foo).a; // nowarn 5529 TS_UNCHECKED_READ(bar.foo).a = 1; // nowarn 5530 5531 int c = TS_UNCHECKED_READ(cbar.a); // nowarn 5532 } 5533 5534 #undef TS_UNCHECKED_READ 5535 5536 } // end namespace TestReferenceNoThreadSafetyAnalysis 5537 5538 5539 namespace GlobalAcquiredBeforeAfterTest { 5540 5541 Mutex mu1; 5542 Mutex mu2 ACQUIRED_AFTER(mu1); 5543 5544 void test3() { 5545 mu2.Lock(); 5546 mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} 5547 mu1.Unlock(); 5548 mu2.Unlock(); 5549 } 5550 5551 } // end namespace GlobalAcquiredBeforeAfterTest 5552 5553 5554 namespace LifetimeExtensionText { 5555 5556 struct Holder { 5557 virtual ~Holder() throw() {} 5558 int i = 0; 5559 }; 5560 5561 void test() { 5562 // Should not crash. 5563 const auto &value = Holder().i; 5564 } 5565 5566 } // end namespace LifetimeExtensionTest 5567 5568 5569 namespace LockableUnions { 5570 5571 union LOCKABLE MutexUnion { 5572 int a; 5573 char* b; 5574 5575 void Lock() EXCLUSIVE_LOCK_FUNCTION(); 5576 void Unlock() UNLOCK_FUNCTION(); 5577 }; 5578 5579 MutexUnion muun2; 5580 MutexUnion muun1 ACQUIRED_BEFORE(muun2); 5581 5582 void test() { 5583 muun2.Lock(); 5584 muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}} 5585 muun1.Unlock(); 5586 muun2.Unlock(); 5587 } 5588 5589 } // end namespace LockableUnions 5590 5591 // This used to crash. 5592 class acquired_before_empty_str { 5593 void WaitUntilSpaceAvailable() { 5594 lock_.ReaderLock(); // expected-note {{acquired here}} 5595 } // expected-warning {{mutex 'lock_' is still held at the end of function}} 5596 Mutex lock_ ACQUIRED_BEFORE(""); 5597 }; 5598 5599 namespace PR34800 { 5600 struct A { 5601 operator int() const; 5602 }; 5603 struct B { 5604 bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}} 5605 int h; 5606 }; 5607 struct C { 5608 B *operator[](int); 5609 }; 5610 C c; 5611 void f() { c[A()]->g(); } 5612 } // namespace PR34800 5613 5614 namespace ReturnScopedLockable { 5615 template<typename Object> class SCOPED_LOCKABLE ReadLockedPtr { 5616 public: 5617 ReadLockedPtr(Object *ptr) SHARED_LOCK_FUNCTION((*this)->mutex); 5618 ReadLockedPtr(ReadLockedPtr &&) SHARED_LOCK_FUNCTION((*this)->mutex); 5619 ~ReadLockedPtr() UNLOCK_FUNCTION(); 5620 5621 Object *operator->() const { return object; } 5622 5623 private: 5624 Object *object; 5625 }; 5626 5627 struct Object { 5628 int f() SHARED_LOCKS_REQUIRED(mutex); 5629 Mutex mutex; 5630 }; 5631 5632 ReadLockedPtr<Object> get(); 5633 int use() { 5634 auto ptr = get(); 5635 return ptr->f(); 5636 } 5637 } 5638 5639 namespace PR38640 { 5640 void f() { 5641 // Self-referencing assignment previously caused an infinite loop when thread 5642 // safety analysis was enabled. 5643 int &i = i; // expected-warning {{reference 'i' is not yet bound to a value when used within its own initialization}} 5644 } 5645 } 5646 5647 namespace Derived_Smart_Pointer { 5648 template <class T> 5649 class SmartPtr_Derived : public SmartPtr<T> {}; 5650 5651 class Foo { 5652 public: 5653 SmartPtr_Derived<Mutex> mu_; 5654 int a GUARDED_BY(mu_); 5655 int b GUARDED_BY(mu_.get()); 5656 int c GUARDED_BY(*mu_); 5657 5658 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_); 5659 void Unlock() UNLOCK_FUNCTION(mu_); 5660 5661 void test0() { 5662 a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}} 5663 b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}} 5664 c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}} 5665 } 5666 5667 void test1() { 5668 Lock(); 5669 a = 1; 5670 b = 1; 5671 c = 1; 5672 Unlock(); 5673 } 5674 }; 5675 5676 class Bar { 5677 SmartPtr_Derived<Foo> foo; 5678 5679 void test0() { 5680 foo->a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}} 5681 (*foo).b = 1; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}} 5682 foo.get()->c = 1; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}} 5683 } 5684 5685 void test1() { 5686 foo->Lock(); 5687 foo->a = 1; 5688 foo->Unlock(); 5689 5690 foo->mu_->Lock(); 5691 foo->b = 1; 5692 foo->mu_->Unlock(); 5693 5694 MutexLock lock(foo->mu_.get()); 5695 foo->c = 1; 5696 } 5697 }; 5698 5699 class PointerGuard { 5700 Mutex mu1; 5701 Mutex mu2; 5702 SmartPtr_Derived<int> i GUARDED_BY(mu1) PT_GUARDED_BY(mu2); 5703 5704 void test0() { 5705 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} 5706 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} \ 5707 // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}} 5708 5709 } 5710 5711 void test1() { 5712 mu1.Lock(); 5713 5714 i.get(); 5715 *i = 2; // expected-warning {{reading the value pointed to by 'i' requires holding mutex 'mu2'}} 5716 5717 mu1.Unlock(); 5718 } 5719 5720 void test2() { 5721 mu2.Lock(); 5722 5723 i.get(); // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} 5724 *i = 2; // expected-warning {{reading variable 'i' requires holding mutex 'mu1'}} 5725 5726 mu2.Unlock(); 5727 } 5728 5729 void test3() { 5730 mu1.Lock(); 5731 mu2.Lock(); 5732 5733 i.get(); 5734 *i = 2; 5735 5736 mu2.Unlock(); 5737 mu1.Unlock(); 5738 } 5739 }; 5740 } 5741