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