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