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