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