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