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