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