1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -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 EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) 17#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) 18#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) 19#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 20#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 21#define EXCLUSIVE_LOCKS_REQUIRED(...) \ 22 __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 23#define SHARED_LOCKS_REQUIRED(...) \ 24 __attribute__ ((shared_locks_required(__VA_ARGS__))) 25#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 26 27 28class __attribute__((lockable)) Mutex { 29 public: 30 void Lock() __attribute__((exclusive_lock_function)); 31 void ReaderLock() __attribute__((shared_lock_function)); 32 void Unlock() __attribute__((unlock_function)); 33 bool TryLock() __attribute__((exclusive_trylock_function(true))); 34 bool ReaderTryLock() __attribute__((shared_trylock_function(true))); 35 void LockWhen(const int &cond) __attribute__((exclusive_lock_function)); 36}; 37 38class __attribute__((scoped_lockable)) MutexLock { 39 public: 40 MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); 41 ~MutexLock() __attribute__((unlock_function)); 42}; 43 44class __attribute__((scoped_lockable)) ReaderMutexLock { 45 public: 46 ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); 47 ~ReaderMutexLock() __attribute__((unlock_function)); 48}; 49 50class SCOPED_LOCKABLE ReleasableMutexLock { 51 public: 52 ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu); 53 ~ReleasableMutexLock() UNLOCK_FUNCTION(); 54 55 void Release() UNLOCK_FUNCTION(); 56}; 57 58 59// The universal lock, written "*", allows checking to be selectively turned 60// off for a particular piece of code. 61void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*"); 62void endNoWarnOnReads() UNLOCK_FUNCTION("*"); 63void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*"); 64void endNoWarnOnWrites() UNLOCK_FUNCTION("*"); 65 66 67// For testing handling of smart pointers. 68template<class T> 69class SmartPtr { 70public: 71 SmartPtr(T* p) : ptr_(p) { } 72 SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { } 73 ~SmartPtr(); 74 75 T* get() const { return ptr_; } 76 T* operator->() const { return ptr_; } 77 T& operator*() const { return *ptr_; } 78 79private: 80 T* ptr_; 81}; 82 83 84// For testing destructor calls and cleanup. 85class MyString { 86public: 87 MyString(const char* s); 88 ~MyString(); 89}; 90 91 92 93Mutex sls_mu; 94 95Mutex sls_mu2 __attribute__((acquired_after(sls_mu))); 96int sls_guard_var __attribute__((guarded_var)) = 0; 97int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0; 98 99bool getBool(); 100 101class MutexWrapper { 102public: 103 Mutex mu; 104 int x __attribute__((guarded_by(mu))); 105 void MyLock() __attribute__((exclusive_lock_function(mu))); 106}; 107 108MutexWrapper sls_mw; 109 110void sls_fun_0() { 111 sls_mw.mu.Lock(); 112 sls_mw.x = 5; 113 sls_mw.mu.Unlock(); 114} 115 116void sls_fun_2() { 117 sls_mu.Lock(); 118 int x = sls_guard_var; 119 sls_mu.Unlock(); 120} 121 122void sls_fun_3() { 123 sls_mu.Lock(); 124 sls_guard_var = 2; 125 sls_mu.Unlock(); 126} 127 128void sls_fun_4() { 129 sls_mu2.Lock(); 130 sls_guard_var = 2; 131 sls_mu2.Unlock(); 132} 133 134void sls_fun_5() { 135 sls_mu.Lock(); 136 int x = sls_guardby_var; 137 sls_mu.Unlock(); 138} 139 140void sls_fun_6() { 141 sls_mu.Lock(); 142 sls_guardby_var = 2; 143 sls_mu.Unlock(); 144} 145 146void sls_fun_7() { 147 sls_mu.Lock(); 148 sls_mu2.Lock(); 149 sls_mu2.Unlock(); 150 sls_mu.Unlock(); 151} 152 153void sls_fun_8() { 154 sls_mu.Lock(); 155 if (getBool()) 156 sls_mu.Unlock(); 157 else 158 sls_mu.Unlock(); 159} 160 161void sls_fun_9() { 162 if (getBool()) 163 sls_mu.Lock(); 164 else 165 sls_mu.Lock(); 166 sls_mu.Unlock(); 167} 168 169void sls_fun_good_6() { 170 if (getBool()) { 171 sls_mu.Lock(); 172 } else { 173 if (getBool()) { 174 getBool(); // EMPTY 175 } else { 176 getBool(); // EMPTY 177 } 178 sls_mu.Lock(); 179 } 180 sls_mu.Unlock(); 181} 182 183void sls_fun_good_7() { 184 sls_mu.Lock(); 185 while (getBool()) { 186 sls_mu.Unlock(); 187 if (getBool()) { 188 if (getBool()) { 189 sls_mu.Lock(); 190 continue; 191 } 192 } 193 sls_mu.Lock(); 194 } 195 sls_mu.Unlock(); 196} 197 198void sls_fun_good_8() { 199 sls_mw.MyLock(); 200 sls_mw.mu.Unlock(); 201} 202 203void sls_fun_bad_1() { 204 sls_mu.Unlock(); // \ 205 // expected-warning{{unlocking 'sls_mu' that was not locked}} 206} 207 208void sls_fun_bad_2() { 209 sls_mu.Lock(); 210 sls_mu.Lock(); // \ 211 // expected-warning{{locking 'sls_mu' that is already locked}} 212 sls_mu.Unlock(); 213} 214 215void sls_fun_bad_3() { 216 sls_mu.Lock(); // expected-note {{mutex acquired here}} 217} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} 218 219void sls_fun_bad_4() { 220 if (getBool()) 221 sls_mu.Lock(); // expected-note{{mutex acquired here}} 222 else 223 sls_mu2.Lock(); // expected-note{{mutex acquired here}} 224} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \ 225 // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} 226 227void sls_fun_bad_5() { 228 sls_mu.Lock(); // expected-note {{mutex acquired here}} 229 if (getBool()) 230 sls_mu.Unlock(); 231} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} 232 233void sls_fun_bad_6() { 234 if (getBool()) { 235 sls_mu.Lock(); // expected-note {{mutex acquired here}} 236 } else { 237 if (getBool()) { 238 getBool(); // EMPTY 239 } else { 240 getBool(); // EMPTY 241 } 242 } 243 sls_mu.Unlock(); // \ 244 expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\ 245 expected-warning{{unlocking 'sls_mu' that was not locked}} 246} 247 248void sls_fun_bad_7() { 249 sls_mu.Lock(); 250 while (getBool()) { 251 sls_mu.Unlock(); 252 if (getBool()) { 253 if (getBool()) { 254 continue; // \ 255 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 256 } 257 } 258 sls_mu.Lock(); // expected-note {{mutex acquired here}} 259 } 260 sls_mu.Unlock(); 261} 262 263void sls_fun_bad_8() { 264 sls_mu.Lock(); // expected-note{{mutex acquired here}} 265 266 do { 267 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 268 } while (getBool()); 269} 270 271void sls_fun_bad_9() { 272 do { 273 sls_mu.Lock(); // \ 274 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \ 275 // expected-note{{mutex acquired here}} 276 } while (getBool()); 277 sls_mu.Unlock(); 278} 279 280void sls_fun_bad_10() { 281 sls_mu.Lock(); // expected-note 2{{mutex acquired here}} 282 while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 283 sls_mu.Unlock(); 284 } 285} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} 286 287void sls_fun_bad_11() { 288 while (getBool()) { // \ 289 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 290 sls_mu.Lock(); // expected-note {{mutex acquired here}} 291 } 292 sls_mu.Unlock(); // \ 293 // expected-warning{{unlocking 'sls_mu' that was not locked}} 294} 295 296void sls_fun_bad_12() { 297 sls_mu.Lock(); // expected-note {{mutex acquired here}} 298 while (getBool()) { 299 sls_mu.Unlock(); 300 if (getBool()) { 301 if (getBool()) { 302 break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} 303 } 304 } 305 sls_mu.Lock(); 306 } 307 sls_mu.Unlock(); 308} 309 310//-----------------------------------------// 311// Handling lock expressions in attribute args 312// -------------------------------------------// 313 314Mutex aa_mu; 315 316class GlobalLocker { 317public: 318 void globalLock() __attribute__((exclusive_lock_function(aa_mu))); 319 void globalUnlock() __attribute__((unlock_function(aa_mu))); 320}; 321 322GlobalLocker glock; 323 324void aa_fun_1() { 325 glock.globalLock(); 326 glock.globalUnlock(); 327} 328 329void aa_fun_bad_1() { 330 glock.globalUnlock(); // \ 331 // expected-warning{{unlocking 'aa_mu' that was not locked}} 332} 333 334void aa_fun_bad_2() { 335 glock.globalLock(); 336 glock.globalLock(); // \ 337 // expected-warning{{locking 'aa_mu' that is already locked}} 338 glock.globalUnlock(); 339} 340 341void aa_fun_bad_3() { 342 glock.globalLock(); // expected-note{{mutex acquired here}} 343} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}} 344 345//--------------------------------------------------// 346// Regression tests for unusual method names 347//--------------------------------------------------// 348 349Mutex wmu; 350 351// Test diagnostics for other method names. 352class WeirdMethods { 353 // FIXME: can't currently check inside constructors and destructors. 354 WeirdMethods() { 355 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}} 356 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}} 357 ~WeirdMethods() { 358 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}} 359 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}} 360 void operator++() { 361 wmu.Lock(); // expected-note {{mutex acquired here}} 362 } // expected-warning {{mutex 'wmu' is still locked at the end of function}} 363 operator int*() { 364 wmu.Lock(); // expected-note {{mutex acquired here}} 365 return 0; 366 } // expected-warning {{mutex 'wmu' is still locked at the end of function}} 367}; 368 369//-----------------------------------------------// 370// Errors for guarded by or guarded var variables 371// ----------------------------------------------// 372 373int *pgb_gvar __attribute__((pt_guarded_var)); 374int *pgb_var __attribute__((pt_guarded_by(sls_mu))); 375 376class PGBFoo { 377 public: 378 int x; 379 int *pgb_field __attribute__((guarded_by(sls_mu2))) 380 __attribute__((pt_guarded_by(sls_mu))); 381 void testFoo() { 382 pgb_field = &x; // \ 383 // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}} 384 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 385 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 386 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 387 // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}} 388 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 389 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 390 } 391}; 392 393class GBFoo { 394 public: 395 int gb_field __attribute__((guarded_by(sls_mu))); 396 397 void testFoo() { 398 gb_field = 0; // \ 399 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}} 400 } 401 402 void testNoAnal() __attribute__((no_thread_safety_analysis)) { 403 gb_field = 0; 404 } 405}; 406 407GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu))); 408 409void gb_fun_0() { 410 sls_mu.Lock(); 411 int x = *pgb_var; 412 sls_mu.Unlock(); 413} 414 415void gb_fun_1() { 416 sls_mu.Lock(); 417 *pgb_var = 2; 418 sls_mu.Unlock(); 419} 420 421void gb_fun_2() { 422 int x; 423 pgb_var = &x; 424} 425 426void gb_fun_3() { 427 int *x = pgb_var; 428} 429 430void gb_bad_0() { 431 sls_guard_var = 1; // \ 432 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 433} 434 435void gb_bad_1() { 436 int x = sls_guard_var; // \ 437 // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}} 438} 439 440void gb_bad_2() { 441 sls_guardby_var = 1; // \ 442 // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}} 443} 444 445void gb_bad_3() { 446 int x = sls_guardby_var; // \ 447 // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}} 448} 449 450void gb_bad_4() { 451 *pgb_gvar = 1; // \ 452 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}} 453} 454 455void gb_bad_5() { 456 int x = *pgb_gvar; // \ 457 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}} 458} 459 460void gb_bad_6() { 461 *pgb_var = 1; // \ 462 // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}} 463} 464 465void gb_bad_7() { 466 int x = *pgb_var; // \ 467 // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}} 468} 469 470void gb_bad_8() { 471 GBFoo G; 472 G.gb_field = 0; // \ 473 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}} 474} 475 476void gb_bad_9() { 477 sls_guard_var++; // \ 478 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 479 sls_guard_var--; // \ 480 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 481 ++sls_guard_var; // \ 482 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 483 --sls_guard_var;// \ 484 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 485} 486 487//-----------------------------------------------// 488// Warnings on variables with late parsed attributes 489// ----------------------------------------------// 490 491class LateFoo { 492public: 493 int a __attribute__((guarded_by(mu))); 494 int b; 495 496 void foo() __attribute__((exclusive_locks_required(mu))) { } 497 498 void test() { 499 a = 0; // \ 500 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 501 b = a; // \ 502 // expected-warning {{reading variable 'a' requires locking 'mu'}} 503 c = 0; // \ 504 // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}} 505 } 506 507 int c __attribute__((guarded_by(mu))); 508 509 Mutex mu; 510}; 511 512class LateBar { 513 public: 514 int a_ __attribute__((guarded_by(mu1_))); 515 int b_; 516 int *q __attribute__((pt_guarded_by(mu))); 517 Mutex mu1_; 518 Mutex mu; 519 LateFoo Foo; 520 LateFoo Foo2; 521 LateFoo *FooPointer; 522}; 523 524LateBar b1, *b3; 525 526void late_0() { 527 LateFoo FooA; 528 LateFoo FooB; 529 FooA.mu.Lock(); 530 FooA.a = 5; 531 FooA.mu.Unlock(); 532} 533 534void late_1() { 535 LateBar BarA; 536 BarA.FooPointer->mu.Lock(); 537 BarA.FooPointer->a = 2; 538 BarA.FooPointer->mu.Unlock(); 539} 540 541void late_bad_0() { 542 LateFoo fooA; 543 LateFoo fooB; 544 fooA.mu.Lock(); 545 fooB.a = 5; // \ 546 // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \ 547 // expected-note{{found near match 'fooA.mu'}} 548 fooA.mu.Unlock(); 549} 550 551void late_bad_1() { 552 Mutex mu; 553 mu.Lock(); 554 b1.mu1_.Lock(); 555 int res = b1.a_ + b3->b_; 556 b3->b_ = *b1.q; // \ 557 // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}} 558 b1.mu1_.Unlock(); 559 b1.b_ = res; 560 mu.Unlock(); 561} 562 563void late_bad_2() { 564 LateBar BarA; 565 BarA.FooPointer->mu.Lock(); 566 BarA.Foo.a = 2; // \ 567 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \ 568 // expected-note{{found near match 'BarA.FooPointer->mu'}} 569 BarA.FooPointer->mu.Unlock(); 570} 571 572void late_bad_3() { 573 LateBar BarA; 574 BarA.Foo.mu.Lock(); 575 BarA.FooPointer->a = 2; // \ 576 // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \ 577 // expected-note{{found near match 'BarA.Foo.mu'}} 578 BarA.Foo.mu.Unlock(); 579} 580 581void late_bad_4() { 582 LateBar BarA; 583 BarA.Foo.mu.Lock(); 584 BarA.Foo2.a = 2; // \ 585 // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \ 586 // expected-note{{found near match 'BarA.Foo.mu'}} 587 BarA.Foo.mu.Unlock(); 588} 589 590//-----------------------------------------------// 591// Extra warnings for shared vs. exclusive locks 592// ----------------------------------------------// 593 594void shared_fun_0() { 595 sls_mu.Lock(); 596 do { 597 sls_mu.Unlock(); 598 sls_mu.Lock(); 599 } while (getBool()); 600 sls_mu.Unlock(); 601} 602 603void shared_fun_1() { 604 sls_mu.ReaderLock(); // \ 605 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 606 do { 607 sls_mu.Unlock(); 608 sls_mu.Lock(); // \ 609 // expected-note {{the other lock of mutex 'sls_mu' is here}} 610 } while (getBool()); 611 sls_mu.Unlock(); 612} 613 614void shared_fun_3() { 615 if (getBool()) 616 sls_mu.Lock(); 617 else 618 sls_mu.Lock(); 619 *pgb_var = 1; 620 sls_mu.Unlock(); 621} 622 623void shared_fun_4() { 624 if (getBool()) 625 sls_mu.ReaderLock(); 626 else 627 sls_mu.ReaderLock(); 628 int x = sls_guardby_var; 629 sls_mu.Unlock(); 630} 631 632void shared_fun_8() { 633 if (getBool()) 634 sls_mu.Lock(); // \ 635 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 636 else 637 sls_mu.ReaderLock(); // \ 638 // expected-note {{the other lock of mutex 'sls_mu' is here}} 639 sls_mu.Unlock(); 640} 641 642void shared_bad_0() { 643 sls_mu.Lock(); // \ 644 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 645 do { 646 sls_mu.Unlock(); 647 sls_mu.ReaderLock(); // \ 648 // expected-note {{the other lock of mutex 'sls_mu' is here}} 649 } while (getBool()); 650 sls_mu.Unlock(); 651} 652 653void shared_bad_1() { 654 if (getBool()) 655 sls_mu.Lock(); // \ 656 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 657 else 658 sls_mu.ReaderLock(); // \ 659 // expected-note {{the other lock of mutex 'sls_mu' is here}} 660 *pgb_var = 1; 661 sls_mu.Unlock(); 662} 663 664void shared_bad_2() { 665 if (getBool()) 666 sls_mu.ReaderLock(); // \ 667 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 668 else 669 sls_mu.Lock(); // \ 670 // expected-note {{the other lock of mutex 'sls_mu' is here}} 671 *pgb_var = 1; 672 sls_mu.Unlock(); 673} 674 675// FIXME: Add support for functions (not only methods) 676class LRBar { 677 public: 678 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu))); 679 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu))); 680 void le_fun() __attribute__((locks_excluded(sls_mu))); 681}; 682 683class LRFoo { 684 public: 685 void test() __attribute__((exclusive_locks_required(sls_mu))); 686 void testShared() __attribute__((shared_locks_required(sls_mu2))); 687}; 688 689void elr_fun() __attribute__((exclusive_locks_required(sls_mu))); 690void elr_fun() {} 691 692LRFoo MyLRFoo; 693LRBar Bar; 694 695void es_fun_0() { 696 aa_mu.Lock(); 697 Bar.aa_elr_fun(); 698 aa_mu.Unlock(); 699} 700 701void es_fun_1() { 702 aa_mu.Lock(); 703 Bar.aa_elr_fun_s(); 704 aa_mu.Unlock(); 705} 706 707void es_fun_2() { 708 aa_mu.ReaderLock(); 709 Bar.aa_elr_fun_s(); 710 aa_mu.Unlock(); 711} 712 713void es_fun_3() { 714 sls_mu.Lock(); 715 MyLRFoo.test(); 716 sls_mu.Unlock(); 717} 718 719void es_fun_4() { 720 sls_mu2.Lock(); 721 MyLRFoo.testShared(); 722 sls_mu2.Unlock(); 723} 724 725void es_fun_5() { 726 sls_mu2.ReaderLock(); 727 MyLRFoo.testShared(); 728 sls_mu2.Unlock(); 729} 730 731void es_fun_6() { 732 Bar.le_fun(); 733} 734 735void es_fun_7() { 736 sls_mu.Lock(); 737 elr_fun(); 738 sls_mu.Unlock(); 739} 740 741void es_fun_8() __attribute__((no_thread_safety_analysis)); 742 743void es_fun_8() { 744 Bar.aa_elr_fun_s(); 745} 746 747void es_fun_9() __attribute__((shared_locks_required(aa_mu))); 748void es_fun_9() { 749 Bar.aa_elr_fun_s(); 750} 751 752void es_fun_10() __attribute__((exclusive_locks_required(aa_mu))); 753void es_fun_10() { 754 Bar.aa_elr_fun_s(); 755} 756 757void es_bad_0() { 758 Bar.aa_elr_fun(); // \ 759 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 760} 761 762void es_bad_1() { 763 aa_mu.ReaderLock(); 764 Bar.aa_elr_fun(); // \ 765 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 766 aa_mu.Unlock(); 767} 768 769void es_bad_2() { 770 Bar.aa_elr_fun_s(); // \ 771 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}} 772} 773 774void es_bad_3() { 775 MyLRFoo.test(); // \ 776 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 777} 778 779void es_bad_4() { 780 MyLRFoo.testShared(); // \ 781 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}} 782} 783 784void es_bad_5() { 785 sls_mu.ReaderLock(); 786 MyLRFoo.test(); // \ 787 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 788 sls_mu.Unlock(); 789} 790 791void es_bad_6() { 792 sls_mu.Lock(); 793 Bar.le_fun(); // \ 794 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 795 sls_mu.Unlock(); 796} 797 798void es_bad_7() { 799 sls_mu.ReaderLock(); 800 Bar.le_fun(); // \ 801 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 802 sls_mu.Unlock(); 803} 804 805 806//-----------------------------------------------// 807// Unparseable lock expressions 808// ----------------------------------------------// 809 810// FIXME -- derive new tests for unhandled expressions 811 812 813//----------------------------------------------------------------------------// 814// The following test cases are ported from the gcc thread safety implementation 815// They are each wrapped inside a namespace with the test number of the gcc test 816// 817// FIXME: add all the gcc tests, once this analysis passes them. 818//----------------------------------------------------------------------------// 819 820//-----------------------------------------// 821// Good testcases (no errors) 822//-----------------------------------------// 823 824namespace thread_annot_lock_20 { 825class Bar { 826 public: 827 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_); 828 static int b_ GUARDED_BY(mu1_); 829 static Mutex mu1_; 830 static int a_ GUARDED_BY(mu1_); 831}; 832 833Bar b1; 834 835int Bar::func1() 836{ 837 int res = 5; 838 839 if (a_ == 4) 840 res = b_; 841 return res; 842} 843} // end namespace thread_annot_lock_20 844 845namespace thread_annot_lock_22 { 846// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 847// uses in class definitions. 848Mutex mu; 849 850class Bar { 851 public: 852 int a_ GUARDED_BY(mu1_); 853 int b_; 854 int *q PT_GUARDED_BY(mu); 855 Mutex mu1_ ACQUIRED_AFTER(mu); 856}; 857 858Bar b1, *b3; 859int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 860int res GUARDED_BY(mu) = 5; 861 862int func(int i) 863{ 864 int x; 865 mu.Lock(); 866 b1.mu1_.Lock(); 867 res = b1.a_ + b3->b_; 868 *p = i; 869 b1.a_ = res + b3->b_; 870 b3->b_ = *b1.q; 871 b1.mu1_.Unlock(); 872 b1.b_ = res; 873 x = res; 874 mu.Unlock(); 875 return x; 876} 877} // end namespace thread_annot_lock_22 878 879namespace thread_annot_lock_27_modified { 880// test lock annotations applied to function definitions 881// Modified: applied annotations only to function declarations 882Mutex mu1; 883Mutex mu2 ACQUIRED_AFTER(mu1); 884 885class Foo { 886 public: 887 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1); 888}; 889 890int Foo::method1(int i) { 891 return i; 892} 893 894 895int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1); 896int foo(int i) { 897 return i; 898} 899 900static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1); 901static int bar(int i) { 902 return i; 903} 904 905void main() { 906 Foo a; 907 908 mu1.Lock(); 909 mu2.Lock(); 910 a.method1(1); 911 foo(2); 912 mu2.Unlock(); 913 bar(3); 914 mu1.Unlock(); 915} 916} // end namespace thread_annot_lock_27_modified 917 918 919namespace thread_annot_lock_38 { 920// Test the case where a template member function is annotated with lock 921// attributes in a non-template class. 922class Foo { 923 public: 924 void func1(int y) LOCKS_EXCLUDED(mu_); 925 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_); 926 private: 927 Mutex mu_; 928}; 929 930Foo *foo; 931 932void main() 933{ 934 foo->func1(5); 935 foo->func2(5); 936} 937} // end namespace thread_annot_lock_38 938 939namespace thread_annot_lock_43 { 940// Tests lock canonicalization 941class Foo { 942 public: 943 Mutex *mu_; 944}; 945 946class FooBar { 947 public: 948 Foo *foo_; 949 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; } 950 int a_ GUARDED_BY(foo_->mu_); 951}; 952 953FooBar *fb; 954 955void main() 956{ 957 int x; 958 fb->foo_->mu_->Lock(); 959 x = fb->GetA(); 960 fb->foo_->mu_->Unlock(); 961} 962} // end namespace thread_annot_lock_43 963 964namespace thread_annot_lock_49 { 965// Test the support for use of lock expression in the annotations 966class Foo { 967 public: 968 Mutex foo_mu_; 969}; 970 971class Bar { 972 private: 973 Foo *foo; 974 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_); 975 976 public: 977 void Test1() { 978 foo->foo_mu_.Lock(); 979 bar_mu_.Lock(); 980 bar_mu_.Unlock(); 981 foo->foo_mu_.Unlock(); 982 } 983}; 984 985void main() { 986 Bar bar; 987 bar.Test1(); 988} 989} // end namespace thread_annot_lock_49 990 991namespace thread_annot_lock_61_modified { 992 // Modified to fix the compiler errors 993 // Test the fix for a bug introduced by the support of pass-by-reference 994 // paramters. 995 struct Foo { Foo &operator<< (bool) {return *this;} }; 996 Foo &getFoo(); 997 struct Bar { Foo &func () {return getFoo();} }; 998 struct Bas { void operator& (Foo &) {} }; 999 void mumble() 1000 { 1001 Bas() & Bar().func() << "" << ""; 1002 Bas() & Bar().func() << ""; 1003 } 1004} // end namespace thread_annot_lock_61_modified 1005 1006 1007namespace thread_annot_lock_65 { 1008// Test the fix for a bug in the support of allowing reader locks for 1009// non-const, non-modifying overload functions. (We didn't handle the builtin 1010// properly.) 1011enum MyFlags { 1012 Zero, 1013 One, 1014 Two, 1015 Three, 1016 Four, 1017 Five, 1018 Six, 1019 Seven, 1020 Eight, 1021 Nine 1022}; 1023 1024inline MyFlags 1025operator|(MyFlags a, MyFlags b) 1026{ 1027 return MyFlags(static_cast<int>(a) | static_cast<int>(b)); 1028} 1029 1030inline MyFlags& 1031operator|=(MyFlags& a, MyFlags b) 1032{ 1033 return a = a | b; 1034} 1035} // end namespace thread_annot_lock_65 1036 1037namespace thread_annot_lock_66_modified { 1038// Modified: Moved annotation to function defn 1039// Test annotations on out-of-line definitions of member functions where the 1040// annotations refer to locks that are also data members in the class. 1041Mutex mu; 1042 1043class Foo { 1044 public: 1045 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2); 1046 int data GUARDED_BY(mu1); 1047 Mutex *mu1; 1048 Mutex *mu2; 1049}; 1050 1051int Foo::method1(int i) 1052{ 1053 return data + i; 1054} 1055 1056void main() 1057{ 1058 Foo a; 1059 1060 a.mu2->Lock(); 1061 a.mu1->Lock(); 1062 mu.Lock(); 1063 a.method1(1); 1064 mu.Unlock(); 1065 a.mu1->Unlock(); 1066 a.mu2->Unlock(); 1067} 1068} // end namespace thread_annot_lock_66_modified 1069 1070namespace thread_annot_lock_68_modified { 1071// Test a fix to a bug in the delayed name binding with nested template 1072// instantiation. We use a stack to make sure a name is not resolved to an 1073// inner context. 1074template <typename T> 1075class Bar { 1076 Mutex mu_; 1077}; 1078 1079template <typename T> 1080class Foo { 1081 public: 1082 void func(T x) { 1083 mu_.Lock(); 1084 count_ = x; 1085 mu_.Unlock(); 1086 } 1087 1088 private: 1089 T count_ GUARDED_BY(mu_); 1090 Bar<T> bar_; 1091 Mutex mu_; 1092}; 1093 1094void main() 1095{ 1096 Foo<int> *foo; 1097 foo->func(5); 1098} 1099} // end namespace thread_annot_lock_68_modified 1100 1101namespace thread_annot_lock_30_modified { 1102// Test delay parsing of lock attribute arguments with nested classes. 1103// Modified: trylocks replaced with exclusive_lock_fun 1104int a = 0; 1105 1106class Bar { 1107 struct Foo; 1108 1109 public: 1110 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu); 1111 1112 int func() { 1113 MyLock(); 1114// if (foo == 0) { 1115// return 0; 1116// } 1117 a = 5; 1118 mu.Unlock(); 1119 return 1; 1120 } 1121 1122 class FooBar { 1123 int x; 1124 int y; 1125 }; 1126 1127 private: 1128 Mutex mu; 1129}; 1130 1131Bar *bar; 1132 1133void main() 1134{ 1135 bar->func(); 1136} 1137} // end namespace thread_annot_lock_30_modified 1138 1139namespace thread_annot_lock_47 { 1140// Test the support for annotations on virtual functions. 1141// This is a good test case. (i.e. There should be no warning emitted by the 1142// compiler.) 1143class Base { 1144 public: 1145 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1146 virtual void func2() LOCKS_EXCLUDED(mu_); 1147 Mutex mu_; 1148}; 1149 1150class Child : public Base { 1151 public: 1152 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1153 virtual void func2() LOCKS_EXCLUDED(mu_); 1154}; 1155 1156void main() { 1157 Child *c; 1158 Base *b = c; 1159 1160 b->mu_.Lock(); 1161 b->func1(); 1162 b->mu_.Unlock(); 1163 b->func2(); 1164 1165 c->mu_.Lock(); 1166 c->func1(); 1167 c->mu_.Unlock(); 1168 c->func2(); 1169} 1170} // end namespace thread_annot_lock_47 1171 1172//-----------------------------------------// 1173// Tests which produce errors 1174//-----------------------------------------// 1175 1176namespace thread_annot_lock_13 { 1177Mutex mu1; 1178Mutex mu2; 1179 1180int g GUARDED_BY(mu1); 1181int w GUARDED_BY(mu2); 1182 1183class Foo { 1184 public: 1185 void bar() LOCKS_EXCLUDED(mu_, mu1); 1186 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2); 1187 1188 private: 1189 int a_ GUARDED_BY(mu_); 1190 public: 1191 Mutex mu_ ACQUIRED_AFTER(mu1); 1192}; 1193 1194int Foo::foo() 1195{ 1196 int res; 1197 w = 5; 1198 res = a_ + 5; 1199 return res; 1200} 1201 1202void Foo::bar() 1203{ 1204 int x; 1205 mu_.Lock(); 1206 x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}} 1207 a_ = x + 1; 1208 mu_.Unlock(); 1209 if (x > 5) { 1210 mu1.Lock(); 1211 g = 2; 1212 mu1.Unlock(); 1213 } 1214} 1215 1216void main() 1217{ 1218 Foo f1, *f2; 1219 f1.mu_.Lock(); 1220 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}} 1221 mu2.Lock(); 1222 f1.foo(); 1223 mu2.Unlock(); 1224 f1.mu_.Unlock(); 1225 f2->mu_.Lock(); 1226 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}} 1227 f2->mu_.Unlock(); 1228 mu2.Lock(); 1229 w = 2; 1230 mu2.Unlock(); 1231} 1232} // end namespace thread_annot_lock_13 1233 1234namespace thread_annot_lock_18_modified { 1235// Modified: Trylocks removed 1236// Test the ability to distnguish between the same lock field of 1237// different objects of a class. 1238 class Bar { 1239 public: 1240 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_); 1241 void MyUnlock() UNLOCK_FUNCTION(mu1_); 1242 int a_ GUARDED_BY(mu1_); 1243 1244 private: 1245 Mutex mu1_; 1246}; 1247 1248Bar *b1, *b2; 1249 1250void func() 1251{ 1252 b1->MyLock(); 1253 b1->a_ = 5; 1254 b2->a_ = 3; // \ 1255 // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \ 1256 // expected-note {{found near match 'b1->mu1_'}} 1257 b2->MyLock(); 1258 b2->MyUnlock(); 1259 b1->MyUnlock(); 1260} 1261} // end namespace thread_annot_lock_18_modified 1262 1263namespace thread_annot_lock_21 { 1264// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 1265// uses in class definitions. 1266Mutex mu; 1267 1268class Bar { 1269 public: 1270 int a_ GUARDED_BY(mu1_); 1271 int b_; 1272 int *q PT_GUARDED_BY(mu); 1273 Mutex mu1_ ACQUIRED_AFTER(mu); 1274}; 1275 1276Bar b1, *b3; 1277int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 1278 1279int res GUARDED_BY(mu) = 5; 1280 1281int func(int i) 1282{ 1283 int x; 1284 b3->mu1_.Lock(); 1285 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \ 1286 // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \ 1287 // expected-note {{found near match 'b3->mu1_'}} 1288 *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \ 1289 // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}} 1290 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \ 1291 // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \ 1292 // expected-note {{found near match 'b3->mu1_'}} 1293 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}} 1294 b3->mu1_.Unlock(); 1295 b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1296 x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1297 return x; 1298} 1299} // end namespace thread_annot_lock_21 1300 1301namespace thread_annot_lock_35_modified { 1302// Test the analyzer's ability to distinguish the lock field of different 1303// objects. 1304class Foo { 1305 private: 1306 Mutex lock_; 1307 int a_ GUARDED_BY(lock_); 1308 1309 public: 1310 void Func(Foo* child) LOCKS_EXCLUDED(lock_) { 1311 Foo *new_foo = new Foo; 1312 1313 lock_.Lock(); 1314 1315 child->Func(new_foo); // There shouldn't be any warning here as the 1316 // acquired lock is not in child. 1317 child->bar(7); // \ 1318 // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \ 1319 // expected-note {{found near match 'lock_'}} 1320 child->a_ = 5; // \ 1321 // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \ 1322 // expected-note {{found near match 'lock_'}} 1323 lock_.Unlock(); 1324 } 1325 1326 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) { 1327 a_ = y; 1328 } 1329}; 1330 1331Foo *x; 1332 1333void main() { 1334 Foo *child = new Foo; 1335 x->Func(child); 1336} 1337} // end namespace thread_annot_lock_35_modified 1338 1339namespace thread_annot_lock_36_modified { 1340// Modified to move the annotations to function defns. 1341// Test the analyzer's ability to distinguish the lock field of different 1342// objects 1343class Foo { 1344 private: 1345 Mutex lock_; 1346 int a_ GUARDED_BY(lock_); 1347 1348 public: 1349 void Func(Foo* child) LOCKS_EXCLUDED(lock_); 1350 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_); 1351}; 1352 1353void Foo::Func(Foo* child) { 1354 Foo *new_foo = new Foo; 1355 1356 lock_.Lock(); 1357 1358 child->lock_.Lock(); 1359 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}} 1360 child->bar(7); 1361 child->a_ = 5; 1362 child->lock_.Unlock(); 1363 1364 lock_.Unlock(); 1365} 1366 1367void Foo::bar(int y) { 1368 a_ = y; 1369} 1370 1371 1372Foo *x; 1373 1374void main() { 1375 Foo *child = new Foo; 1376 x->Func(child); 1377} 1378} // end namespace thread_annot_lock_36_modified 1379 1380 1381namespace thread_annot_lock_42 { 1382// Test support of multiple lock attributes of the same kind on a decl. 1383class Foo { 1384 private: 1385 Mutex mu1, mu2, mu3; 1386 int x GUARDED_BY(mu1) GUARDED_BY(mu2); 1387 int y GUARDED_BY(mu2); 1388 1389 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) { 1390 mu2.Lock(); 1391 y = 2; 1392 mu2.Unlock(); 1393 } 1394 1395 public: 1396 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) { 1397 x = 5; 1398 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \ 1399 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}} 1400 } 1401}; 1402 1403Foo *foo; 1404 1405void func() 1406{ 1407 foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \ 1408 // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}} 1409} 1410} // end namespace thread_annot_lock_42 1411 1412namespace thread_annot_lock_46 { 1413// Test the support for annotations on virtual functions. 1414class Base { 1415 public: 1416 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1417 virtual void func2() LOCKS_EXCLUDED(mu_); 1418 Mutex mu_; 1419}; 1420 1421class Child : public Base { 1422 public: 1423 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1424 virtual void func2() LOCKS_EXCLUDED(mu_); 1425}; 1426 1427void main() { 1428 Child *c; 1429 Base *b = c; 1430 1431 b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}} 1432 b->mu_.Lock(); 1433 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}} 1434 b->mu_.Unlock(); 1435 1436 c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}} 1437 c->mu_.Lock(); 1438 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}} 1439 c->mu_.Unlock(); 1440} 1441} // end namespace thread_annot_lock_46 1442 1443namespace thread_annot_lock_67_modified { 1444// Modified: attributes on definitions moved to declarations 1445// Test annotations on out-of-line definitions of member functions where the 1446// annotations refer to locks that are also data members in the class. 1447Mutex mu; 1448Mutex mu3; 1449 1450class Foo { 1451 public: 1452 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3); 1453 int data GUARDED_BY(mu1); 1454 Mutex *mu1; 1455 Mutex *mu2; 1456}; 1457 1458int Foo::method1(int i) { 1459 return data + i; 1460} 1461 1462void main() 1463{ 1464 Foo a; 1465 a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \ 1466 // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \ 1467 // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \ 1468 // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}} 1469} 1470} // end namespace thread_annot_lock_67_modified 1471 1472 1473namespace substitution_test { 1474 class MyData { 1475 public: 1476 Mutex mu; 1477 1478 void lockData() __attribute__((exclusive_lock_function(mu))) { } 1479 void unlockData() __attribute__((unlock_function(mu))) { } 1480 1481 void doSomething() __attribute__((exclusive_locks_required(mu))) { } 1482 }; 1483 1484 1485 class DataLocker { 1486 public: 1487 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { } 1488 void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { } 1489 }; 1490 1491 1492 class Foo { 1493 public: 1494 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { } 1495 1496 void bar1(MyData* d) { 1497 d->lockData(); 1498 foo(d); 1499 d->unlockData(); 1500 } 1501 1502 void bar2(MyData* d) { 1503 DataLocker dlr; 1504 dlr.lockData(d); 1505 foo(d); 1506 dlr.unlockData(d); 1507 } 1508 1509 void bar3(MyData* d1, MyData* d2) { 1510 DataLocker dlr; 1511 dlr.lockData(d1); // expected-note {{mutex acquired here}} 1512 dlr.unlockData(d2); // \ 1513 // expected-warning {{unlocking 'd2->mu' that was not locked}} 1514 } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}} 1515 1516 void bar4(MyData* d1, MyData* d2) { 1517 DataLocker dlr; 1518 dlr.lockData(d1); 1519 foo(d2); // \ 1520 // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \ 1521 // expected-note {{found near match 'd1->mu'}} 1522 dlr.unlockData(d1); 1523 } 1524 }; 1525} // end namespace substituation_test 1526 1527 1528 1529namespace constructor_destructor_tests { 1530 Mutex fooMu; 1531 int myVar GUARDED_BY(fooMu); 1532 1533 class Foo { 1534 public: 1535 Foo() __attribute__((exclusive_lock_function(fooMu))) { } 1536 ~Foo() __attribute__((unlock_function(fooMu))) { } 1537 }; 1538 1539 void fooTest() { 1540 Foo foo; 1541 myVar = 0; 1542 } 1543} 1544 1545 1546namespace template_member_test { 1547 1548 struct S { int n; }; 1549 struct T { 1550 Mutex m; 1551 S *s GUARDED_BY(this->m); 1552 }; 1553 Mutex m; 1554 struct U { 1555 union { 1556 int n; 1557 }; 1558 } *u GUARDED_BY(m); 1559 1560 template<typename U> 1561 struct IndirectLock { 1562 int DoNaughtyThings(T *t) { 1563 u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}} 1564 return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}} 1565 } 1566 }; 1567 1568 template struct IndirectLock<int>; // expected-note {{here}} 1569 1570 struct V { 1571 void f(int); 1572 void f(double); 1573 1574 Mutex m; 1575 V *p GUARDED_BY(this->m); 1576 }; 1577 template<typename U> struct W { 1578 V v; 1579 void f(U u) { 1580 v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}} 1581 } 1582 }; 1583 template struct W<int>; // expected-note {{here}} 1584 1585} 1586 1587namespace test_scoped_lockable { 1588 1589struct TestScopedLockable { 1590 Mutex mu1; 1591 Mutex mu2; 1592 int a __attribute__((guarded_by(mu1))); 1593 int b __attribute__((guarded_by(mu2))); 1594 1595 bool getBool(); 1596 1597 void foo1() { 1598 MutexLock mulock(&mu1); 1599 a = 5; 1600 } 1601 1602 void foo2() { 1603 ReaderMutexLock mulock1(&mu1); 1604 if (getBool()) { 1605 MutexLock mulock2a(&mu2); 1606 b = a + 1; 1607 } 1608 else { 1609 MutexLock mulock2b(&mu2); 1610 b = a + 2; 1611 } 1612 } 1613 1614 void foo3() { 1615 MutexLock mulock_a(&mu1); 1616 MutexLock mulock_b(&mu1); // \ 1617 // expected-warning {{locking 'mu1' that is already locked}} 1618 } 1619 1620 void foo4() { 1621 MutexLock mulock1(&mu1), mulock2(&mu2); 1622 a = b+1; 1623 b = a+1; 1624 } 1625}; 1626 1627} // end namespace test_scoped_lockable 1628 1629 1630namespace FunctionAttrTest { 1631 1632class Foo { 1633public: 1634 Mutex mu_; 1635 int a GUARDED_BY(mu_); 1636}; 1637 1638Foo fooObj; 1639 1640void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_); 1641 1642void bar() { 1643 foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}} 1644 fooObj.mu_.Lock(); 1645 foo(); 1646 fooObj.mu_.Unlock(); 1647} 1648 1649}; // end namespace FunctionAttrTest 1650 1651 1652namespace TryLockTest { 1653 1654struct TestTryLock { 1655 Mutex mu; 1656 int a GUARDED_BY(mu); 1657 bool cond; 1658 1659 void foo1() { 1660 if (mu.TryLock()) { 1661 a = 1; 1662 mu.Unlock(); 1663 } 1664 } 1665 1666 void foo2() { 1667 if (!mu.TryLock()) return; 1668 a = 2; 1669 mu.Unlock(); 1670 } 1671 1672 void foo3() { 1673 bool b = mu.TryLock(); 1674 if (b) { 1675 a = 3; 1676 mu.Unlock(); 1677 } 1678 } 1679 1680 void foo4() { 1681 bool b = mu.TryLock(); 1682 if (!b) return; 1683 a = 4; 1684 mu.Unlock(); 1685 } 1686 1687 void foo5() { 1688 while (mu.TryLock()) { 1689 a = a + 1; 1690 mu.Unlock(); 1691 } 1692 } 1693 1694 void foo6() { 1695 bool b = mu.TryLock(); 1696 b = !b; 1697 if (b) return; 1698 a = 6; 1699 mu.Unlock(); 1700 } 1701 1702 void foo7() { 1703 bool b1 = mu.TryLock(); 1704 bool b2 = !b1; 1705 bool b3 = !b2; 1706 if (b3) { 1707 a = 7; 1708 mu.Unlock(); 1709 } 1710 } 1711 1712 // Test use-def chains: join points 1713 void foo8() { 1714 bool b = mu.TryLock(); 1715 bool b2 = b; 1716 if (cond) 1717 b = true; 1718 if (b) { // b should be unknown at this point, because of the join point 1719 a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}} 1720 } 1721 if (b2) { // b2 should be known at this point. 1722 a = 8; 1723 mu.Unlock(); 1724 } 1725 } 1726 1727 // Test use-def-chains: back edges 1728 void foo9() { 1729 bool b = mu.TryLock(); 1730 1731 for (int i = 0; i < 10; ++i); 1732 1733 if (b) { // b is still known, because the loop doesn't alter it 1734 a = 9; 1735 mu.Unlock(); 1736 } 1737 } 1738 1739 // Test use-def chains: back edges 1740 void foo10() { 1741 bool b = mu.TryLock(); 1742 1743 while (cond) { 1744 if (b) { // b should be uknown at this point b/c of the loop 1745 a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}} 1746 } 1747 b = !b; 1748 } 1749 } 1750 1751 // Test merge of exclusive trylock 1752 void foo11() { 1753 if (cond) { 1754 if (!mu.TryLock()) 1755 return; 1756 } 1757 else { 1758 mu.Lock(); 1759 } 1760 a = 10; 1761 mu.Unlock(); 1762 } 1763 1764 // Test merge of shared trylock 1765 void foo12() { 1766 if (cond) { 1767 if (!mu.ReaderTryLock()) 1768 return; 1769 } 1770 else { 1771 mu.ReaderLock(); 1772 } 1773 int i = a; 1774 mu.Unlock(); 1775 } 1776}; // end TestTrylock 1777 1778} // end namespace TrylockTest 1779 1780 1781namespace TestTemplateAttributeInstantiation { 1782 1783class Foo1 { 1784public: 1785 Mutex mu_; 1786 int a GUARDED_BY(mu_); 1787}; 1788 1789class Foo2 { 1790public: 1791 int a GUARDED_BY(mu_); 1792 Mutex mu_; 1793}; 1794 1795 1796class Bar { 1797public: 1798 // Test non-dependent expressions in attributes on template functions 1799 template <class T> 1800 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) { 1801 foo->a = 0; 1802 } 1803 1804 // Test dependent expressions in attributes on template functions 1805 template <class T> 1806 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) { 1807 fooT->a = 0; 1808 } 1809}; 1810 1811 1812template <class T> 1813class BarT { 1814public: 1815 Foo1 fooBase; 1816 T fooBaseT; 1817 1818 // Test non-dependent expression in ordinary method on template class 1819 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) { 1820 fooBase.a = 0; 1821 } 1822 1823 // Test dependent expressions in ordinary methods on template class 1824 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) { 1825 fooBaseT.a = 0; 1826 } 1827 1828 // Test dependent expressions in template method in template class 1829 template <class T2> 1830 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) { 1831 fooBaseT.a = 0; 1832 fooT->a = 0; 1833 } 1834}; 1835 1836template <class T> 1837class Cell { 1838public: 1839 Mutex mu_; 1840 // Test dependent guarded_by 1841 T data GUARDED_BY(mu_); 1842 1843 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 1844 data = 0; 1845 } 1846 1847 void foo() { 1848 mu_.Lock(); 1849 data = 0; 1850 mu_.Unlock(); 1851 } 1852}; 1853 1854void test() { 1855 Bar b; 1856 BarT<Foo2> bt; 1857 Foo1 f1; 1858 Foo2 f2; 1859 1860 f1.mu_.Lock(); 1861 f2.mu_.Lock(); 1862 bt.fooBase.mu_.Lock(); 1863 bt.fooBaseT.mu_.Lock(); 1864 1865 b.barND(&f1, &f2); 1866 b.barD(&f1, &f2); 1867 bt.barND(); 1868 bt.barD(); 1869 bt.barTD(&f2); 1870 1871 f1.mu_.Unlock(); 1872 bt.barTD(&f1); // \ 1873 // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \ 1874 // expected-note {{found near match 'bt.fooBase.mu_'}} 1875 1876 bt.fooBase.mu_.Unlock(); 1877 bt.fooBaseT.mu_.Unlock(); 1878 f2.mu_.Unlock(); 1879 1880 Cell<int> cell; 1881 cell.data = 0; // \ 1882 // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}} 1883 cell.foo(); 1884 cell.mu_.Lock(); 1885 cell.fooEx(); 1886 cell.mu_.Unlock(); 1887} 1888 1889 1890template <class T> 1891class CellDelayed { 1892public: 1893 // Test dependent guarded_by 1894 T data GUARDED_BY(mu_); 1895 static T static_data GUARDED_BY(static_mu_); 1896 1897 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) { 1898 this->data = other->data; 1899 } 1900 1901 template <class T2> 1902 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) { 1903 this->data = otherT->data; 1904 } 1905 1906 void foo() { 1907 mu_.Lock(); 1908 data = 0; 1909 mu_.Unlock(); 1910 } 1911 1912 Mutex mu_; 1913 static Mutex static_mu_; 1914}; 1915 1916void testDelayed() { 1917 CellDelayed<int> celld; 1918 CellDelayed<int> celld2; 1919 celld.foo(); 1920 celld.mu_.Lock(); 1921 celld2.mu_.Lock(); 1922 1923 celld.fooEx(&celld2); 1924 celld.fooExT(&celld2); 1925 1926 celld2.mu_.Unlock(); 1927 celld.mu_.Unlock(); 1928} 1929 1930}; // end namespace TestTemplateAttributeInstantiation 1931 1932 1933namespace FunctionDeclDefTest { 1934 1935class Foo { 1936public: 1937 Mutex mu_; 1938 int a GUARDED_BY(mu_); 1939 1940 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_); 1941}; 1942 1943// EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_ 1944void Foo::foo1(Foo *f_defined) { 1945 f_defined->a = 0; 1946}; 1947 1948void test() { 1949 Foo myfoo; 1950 myfoo.foo1(&myfoo); // \ 1951 // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}} 1952 myfoo.mu_.Lock(); 1953 myfoo.foo1(&myfoo); 1954 myfoo.mu_.Unlock(); 1955} 1956 1957}; 1958 1959namespace GoingNative { 1960 1961 struct __attribute__((lockable)) mutex { 1962 void lock() __attribute__((exclusive_lock_function)); 1963 void unlock() __attribute__((unlock_function)); 1964 // ... 1965 }; 1966 bool foo(); 1967 bool bar(); 1968 mutex m; 1969 void test() { 1970 m.lock(); 1971 while (foo()) { 1972 m.unlock(); 1973 // ... 1974 if (bar()) { 1975 // ... 1976 if (foo()) 1977 continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}} 1978 //... 1979 } 1980 // ... 1981 m.lock(); // expected-note {{mutex acquired here}} 1982 } 1983 m.unlock(); 1984 } 1985 1986} 1987 1988 1989 1990namespace FunctionDefinitionTest { 1991 1992class Foo { 1993public: 1994 void foo1(); 1995 void foo2(); 1996 void foo3(Foo *other); 1997 1998 template<class T> 1999 void fooT1(const T& dummy1); 2000 2001 template<class T> 2002 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_); 2003 2004 Mutex mu_; 2005 int a GUARDED_BY(mu_); 2006}; 2007 2008template<class T> 2009class FooT { 2010public: 2011 void foo(); 2012 2013 Mutex mu_; 2014 T a GUARDED_BY(mu_); 2015}; 2016 2017 2018void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS { 2019 a = 1; 2020} 2021 2022void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 2023 a = 2; 2024} 2025 2026void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) { 2027 other->a = 3; 2028} 2029 2030template<class T> 2031void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) { 2032 a = dummy1; 2033} 2034 2035/* TODO -- uncomment with template instantiation of attributes. 2036template<class T> 2037void Foo::fooT2(const T& dummy2) { 2038 a = dummy2; 2039} 2040*/ 2041 2042void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { 2043 f->a = 1; 2044} 2045 2046void fooF2(Foo *f); 2047void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { 2048 f->a = 2; 2049} 2050 2051void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_); 2052void fooF3(Foo *f) { 2053 f->a = 3; 2054} 2055 2056template<class T> 2057void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 2058 a = 0; 2059} 2060 2061void test() { 2062 int dummy = 0; 2063 Foo myFoo; 2064 2065 myFoo.foo2(); // \ 2066 // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}} 2067 myFoo.foo3(&myFoo); // \ 2068 // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}} 2069 myFoo.fooT1(dummy); // \ 2070 // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}} 2071 2072 myFoo.fooT2(dummy); // \ 2073 // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}} 2074 2075 fooF1(&myFoo); // \ 2076 // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}} 2077 fooF2(&myFoo); // \ 2078 // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}} 2079 fooF3(&myFoo); // \ 2080 // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}} 2081 2082 myFoo.mu_.Lock(); 2083 myFoo.foo2(); 2084 myFoo.foo3(&myFoo); 2085 myFoo.fooT1(dummy); 2086 2087 myFoo.fooT2(dummy); 2088 2089 fooF1(&myFoo); 2090 fooF2(&myFoo); 2091 fooF3(&myFoo); 2092 myFoo.mu_.Unlock(); 2093 2094 FooT<int> myFooT; 2095 myFooT.foo(); // \ 2096 // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}} 2097} 2098 2099} // end namespace FunctionDefinitionTest 2100 2101 2102namespace SelfLockingTest { 2103 2104class LOCKABLE MyLock { 2105public: 2106 int foo GUARDED_BY(this); 2107 2108 void lock() EXCLUSIVE_LOCK_FUNCTION(); 2109 void unlock() UNLOCK_FUNCTION(); 2110 2111 void doSomething() { 2112 this->lock(); // allow 'this' as a lock expression 2113 foo = 0; 2114 doSomethingElse(); 2115 this->unlock(); 2116 } 2117 2118 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) { 2119 foo = 1; 2120 }; 2121 2122 void test() { 2123 foo = 2; // \ 2124 // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}} 2125 } 2126}; 2127 2128 2129class LOCKABLE MyLock2 { 2130public: 2131 Mutex mu_; 2132 int foo GUARDED_BY(this); 2133 2134 // don't check inside lock and unlock functions 2135 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); } 2136 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); } 2137 2138 // don't check inside constructors and destructors 2139 MyLock2() { foo = 1; } 2140 ~MyLock2() { foo = 0; } 2141}; 2142 2143 2144} // end namespace SelfLockingTest 2145 2146 2147namespace InvalidNonstatic { 2148 2149// Forward decl here causes bogus "invalid use of non-static data member" 2150// on reference to mutex_ in guarded_by attribute. 2151class Foo; 2152 2153class Foo { 2154 Mutex* mutex_; 2155 2156 int foo __attribute__((guarded_by(mutex_))); 2157}; 2158 2159} // end namespace InvalidNonStatic 2160 2161 2162namespace NoReturnTest { 2163 2164bool condition(); 2165void fatal() __attribute__((noreturn)); 2166 2167Mutex mu_; 2168 2169void test1() { 2170 MutexLock lock(&mu_); 2171 if (condition()) { 2172 fatal(); 2173 return; 2174 } 2175} 2176 2177} // end namespace NoReturnTest 2178 2179 2180namespace TestMultiDecl { 2181 2182class Foo { 2183public: 2184 int GUARDED_BY(mu_) a; 2185 int GUARDED_BY(mu_) b, c; 2186 2187 void foo() { 2188 a = 0; // \ 2189 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2190 b = 0; // \ 2191 // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}} 2192 c = 0; // \ 2193 // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}} 2194 } 2195 2196private: 2197 Mutex mu_; 2198}; 2199 2200} // end namespace TestMultiDecl 2201 2202 2203namespace WarnNoDecl { 2204 2205class Foo { 2206 void foo(int a); __attribute__(( // \ 2207 // expected-warning {{declaration does not declare anything}} 2208 exclusive_locks_required(a))); // \ 2209 // expected-warning {{attribute exclusive_locks_required ignored}} 2210}; 2211 2212} // end namespace WarnNoDecl 2213 2214 2215 2216namespace MoreLockExpressions { 2217 2218class Foo { 2219public: 2220 Mutex mu_; 2221 int a GUARDED_BY(mu_); 2222}; 2223 2224class Bar { 2225public: 2226 int b; 2227 Foo* f; 2228 2229 Foo& getFoo() { return *f; } 2230 Foo& getFoo2(int c) { return *f; } 2231 Foo& getFoo3(int c, int d) { return *f; } 2232 2233 Foo& getFooey() { return *f; } 2234}; 2235 2236Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); } 2237 2238void test() { 2239 Foo foo; 2240 Foo *fooArray; 2241 Bar bar; 2242 int a; 2243 int b; 2244 int c; 2245 2246 bar.getFoo().mu_.Lock(); 2247 bar.getFoo().a = 0; 2248 bar.getFoo().mu_.Unlock(); 2249 2250 (bar.getFoo().mu_).Lock(); // test parenthesis 2251 bar.getFoo().a = 0; 2252 (bar.getFoo().mu_).Unlock(); 2253 2254 bar.getFoo2(a).mu_.Lock(); 2255 bar.getFoo2(a).a = 0; 2256 bar.getFoo2(a).mu_.Unlock(); 2257 2258 bar.getFoo3(a, b).mu_.Lock(); 2259 bar.getFoo3(a, b).a = 0; 2260 bar.getFoo3(a, b).mu_.Unlock(); 2261 2262 getBarFoo(bar, a).mu_.Lock(); 2263 getBarFoo(bar, a).a = 0; 2264 getBarFoo(bar, a).mu_.Unlock(); 2265 2266 bar.getFoo2(10).mu_.Lock(); 2267 bar.getFoo2(10).a = 0; 2268 bar.getFoo2(10).mu_.Unlock(); 2269 2270 bar.getFoo2(a + 1).mu_.Lock(); 2271 bar.getFoo2(a + 1).a = 0; 2272 bar.getFoo2(a + 1).mu_.Unlock(); 2273 2274 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock(); 2275 (a > 0 ? fooArray[1] : fooArray[b]).a = 0; 2276 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock(); 2277 2278 bar.getFoo().mu_.Lock(); 2279 bar.getFooey().a = 0; // \ 2280 // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \ 2281 // expected-note {{found near match 'bar.getFoo().mu_'}} 2282 bar.getFoo().mu_.Unlock(); 2283 2284 bar.getFoo2(a).mu_.Lock(); 2285 bar.getFoo2(b).a = 0; // \ 2286 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \ 2287 // expected-note {{found near match 'bar.getFoo2(a).mu_'}} 2288 bar.getFoo2(a).mu_.Unlock(); 2289 2290 bar.getFoo3(a, b).mu_.Lock(); 2291 bar.getFoo3(a, c).a = 0; // \ 2292 // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \ 2293 // expected-note {{'bar.getFoo3(a,b).mu_'}} 2294 bar.getFoo3(a, b).mu_.Unlock(); 2295 2296 getBarFoo(bar, a).mu_.Lock(); 2297 getBarFoo(bar, b).a = 0; // \ 2298 // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \ 2299 // expected-note {{'getBarFoo(bar,a).mu_'}} 2300 getBarFoo(bar, a).mu_.Unlock(); 2301 2302 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock(); 2303 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \ 2304 // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \ 2305 // expected-note {{'((a#_)#_#fooArray[_]).mu_'}} 2306 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock(); 2307} 2308 2309 2310} // end namespace MoreLockExpressions 2311 2312 2313namespace TrylockJoinPoint { 2314 2315class Foo { 2316 Mutex mu; 2317 bool c; 2318 2319 void foo() { 2320 if (c) { 2321 if (!mu.TryLock()) 2322 return; 2323 } else { 2324 mu.Lock(); 2325 } 2326 mu.Unlock(); 2327 } 2328}; 2329 2330} // end namespace TrylockJoinPoint 2331 2332 2333namespace LockReturned { 2334 2335class Foo { 2336public: 2337 int a GUARDED_BY(mu_); 2338 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_); 2339 void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_); 2340 2341 static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_); 2342 2343 Mutex* getMu() LOCK_RETURNED(mu_); 2344 2345 Mutex mu_; 2346 2347 static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_); 2348}; 2349 2350 2351// Calls getMu() directly to lock and unlock 2352void test1(Foo* f1, Foo* f2) { 2353 f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}} 2354 f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}} 2355 2356 f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \ 2357 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} 2358 Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}} 2359 2360 f1->getMu()->Lock(); 2361 2362 f1->a = 0; 2363 f1->foo(); 2364 f1->foo2(f2); // \ 2365 // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \ 2366 // expected-note {{found near match 'f1->mu_'}} 2367 2368 Foo::getMu(f2)->Lock(); 2369 f1->foo2(f2); 2370 Foo::getMu(f2)->Unlock(); 2371 2372 Foo::sfoo(f1); 2373 2374 f1->getMu()->Unlock(); 2375} 2376 2377 2378Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f)); 2379 2380class Bar : public Foo { 2381public: 2382 int b GUARDED_BY(getMu()); 2383 void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu()); 2384 void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu()); 2385 2386 static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu()); 2387 static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g)); 2388}; 2389 2390 2391 2392// Use getMu() within other attributes. 2393// This requires at lest levels of substitution, more in the case of 2394void test2(Bar* b1, Bar* b2) { 2395 b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}} 2396 b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}} 2397 b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \ 2398 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} 2399 Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}} 2400 Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}} 2401 2402 b1->getMu()->Lock(); 2403 2404 b1->b = 0; 2405 b1->bar(); 2406 b1->bar2(b2); // \ 2407 // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \ 2408 // // expected-note {{found near match 'b1->mu_'}} 2409 2410 b2->getMu()->Lock(); 2411 b1->bar2(b2); 2412 2413 b2->getMu()->Unlock(); 2414 2415 Bar::sbar(b1); 2416 Bar::sbar2(b1); 2417 2418 b1->getMu()->Unlock(); 2419} 2420 2421 2422// Sanity check -- lock the mutex directly, but use attributes that call getMu() 2423// Also lock the mutex using getFooMu, which calls a lock_returned function. 2424void test3(Bar* b1, Bar* b2) { 2425 b1->mu_.Lock(); 2426 b1->b = 0; 2427 b1->bar(); 2428 2429 getFooMu(b2)->Lock(); 2430 b1->bar2(b2); 2431 getFooMu(b2)->Unlock(); 2432 2433 Bar::sbar(b1); 2434 Bar::sbar2(b1); 2435 2436 b1->mu_.Unlock(); 2437} 2438 2439} // end namespace LockReturned 2440 2441 2442namespace ReleasableScopedLock { 2443 2444class Foo { 2445 Mutex mu_; 2446 bool c; 2447 int a GUARDED_BY(mu_); 2448 2449 void test1(); 2450 void test2(); 2451 void test3(); 2452 void test4(); 2453 void test5(); 2454}; 2455 2456 2457void Foo::test1() { 2458 ReleasableMutexLock rlock(&mu_); 2459 rlock.Release(); 2460} 2461 2462void Foo::test2() { 2463 ReleasableMutexLock rlock(&mu_); 2464 if (c) { // test join point -- held/not held during release 2465 rlock.Release(); 2466 } 2467} 2468 2469void Foo::test3() { 2470 ReleasableMutexLock rlock(&mu_); 2471 a = 0; 2472 rlock.Release(); 2473 a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2474} 2475 2476void Foo::test4() { 2477 ReleasableMutexLock rlock(&mu_); 2478 rlock.Release(); 2479 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}} 2480} 2481 2482void Foo::test5() { 2483 ReleasableMutexLock rlock(&mu_); 2484 if (c) { 2485 rlock.Release(); 2486 } 2487 // no warning on join point for managed lock. 2488 rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}} 2489} 2490 2491 2492} // end namespace ReleasableScopedLock 2493 2494 2495namespace TrylockFunctionTest { 2496 2497class Foo { 2498public: 2499 Mutex mu1_; 2500 Mutex mu2_; 2501 bool c; 2502 2503 bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_); 2504}; 2505 2506bool Foo::lockBoth() { 2507 if (!mu1_.TryLock()) 2508 return false; 2509 2510 mu2_.Lock(); 2511 if (!c) { 2512 mu1_.Unlock(); 2513 mu2_.Unlock(); 2514 return false; 2515 } 2516 2517 return true; 2518} 2519 2520 2521} // end namespace TrylockFunctionTest 2522 2523 2524 2525namespace DoubleLockBug { 2526 2527class Foo { 2528public: 2529 Mutex mu_; 2530 int a GUARDED_BY(mu_); 2531 2532 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 2533 int foo2() SHARED_LOCKS_REQUIRED(mu_); 2534}; 2535 2536 2537void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 2538 a = 0; 2539} 2540 2541int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) { 2542 return a; 2543} 2544 2545} 2546 2547 2548 2549namespace UnlockBug { 2550 2551class Foo { 2552public: 2553 Mutex mutex_; 2554 2555 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}} 2556 mutex_.Unlock(); 2557 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}} 2558 2559 2560 void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}} 2561 mutex_.Unlock(); 2562 } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}} 2563}; 2564 2565} // end namespace UnlockBug 2566 2567 2568 2569namespace FoolishScopedLockableBug { 2570 2571class SCOPED_LOCKABLE WTF_ScopedLockable { 2572public: 2573 WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu); 2574 2575 // have to call release() manually; 2576 ~WTF_ScopedLockable(); 2577 2578 void release() UNLOCK_FUNCTION(); 2579}; 2580 2581 2582class Foo { 2583 Mutex mu_; 2584 int a GUARDED_BY(mu_); 2585 bool c; 2586 2587 void doSomething(); 2588 2589 void test1() { 2590 WTF_ScopedLockable wtf(&mu_); 2591 wtf.release(); 2592 } 2593 2594 void test2() { 2595 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}} 2596 } // expected-warning {{mutex 'mu_' is still locked at the end of function}} 2597 2598 void test3() { 2599 if (c) { 2600 WTF_ScopedLockable wtf(&mu_); 2601 wtf.release(); 2602 } 2603 } 2604 2605 void test4() { 2606 if (c) { 2607 doSomething(); 2608 } 2609 else { 2610 WTF_ScopedLockable wtf(&mu_); 2611 wtf.release(); 2612 } 2613 } 2614 2615 void test5() { 2616 if (c) { 2617 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}} 2618 } 2619 } // expected-warning {{mutex 'mu_' is not locked on every path through here}} 2620 2621 void test6() { 2622 if (c) { 2623 doSomething(); 2624 } 2625 else { 2626 WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}} 2627 } 2628 } // expected-warning {{mutex 'mu_' is not locked on every path through here}} 2629}; 2630 2631 2632} // end namespace FoolishScopedLockableBug 2633 2634 2635 2636namespace TemporaryCleanupExpr { 2637 2638class Foo { 2639 int a GUARDED_BY(getMutexPtr().get()); 2640 2641 SmartPtr<Mutex> getMutexPtr(); 2642 2643 void test(); 2644}; 2645 2646 2647void Foo::test() { 2648 { 2649 ReaderMutexLock lock(getMutexPtr().get()); 2650 int b = a; 2651 } 2652 int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}} 2653} 2654 2655} // end namespace TemporaryCleanupExpr 2656 2657 2658 2659namespace SmartPointerTests { 2660 2661class Foo { 2662public: 2663 SmartPtr<Mutex> mu_; 2664 int a GUARDED_BY(mu_); 2665 int b GUARDED_BY(mu_.get()); 2666 int c GUARDED_BY(*mu_); 2667 2668 void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_); 2669 void Unlock() UNLOCK_FUNCTION(mu_); 2670 2671 void test0(); 2672 void test1(); 2673 void test2(); 2674 void test3(); 2675 void test4(); 2676 void test5(); 2677 void test6(); 2678 void test7(); 2679 void test8(); 2680}; 2681 2682void Foo::test0() { 2683 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2684 b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}} 2685 c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}} 2686} 2687 2688void Foo::test1() { 2689 mu_->Lock(); 2690 a = 0; 2691 b = 0; 2692 c = 0; 2693 mu_->Unlock(); 2694} 2695 2696void Foo::test2() { 2697 (*mu_).Lock(); 2698 a = 0; 2699 b = 0; 2700 c = 0; 2701 (*mu_).Unlock(); 2702} 2703 2704 2705void Foo::test3() { 2706 mu_.get()->Lock(); 2707 a = 0; 2708 b = 0; 2709 c = 0; 2710 mu_.get()->Unlock(); 2711} 2712 2713 2714void Foo::test4() { 2715 MutexLock lock(mu_.get()); 2716 a = 0; 2717 b = 0; 2718 c = 0; 2719} 2720 2721 2722void Foo::test5() { 2723 MutexLock lock(&(*mu_)); 2724 a = 0; 2725 b = 0; 2726 c = 0; 2727} 2728 2729 2730void Foo::test6() { 2731 Lock(); 2732 a = 0; 2733 b = 0; 2734 c = 0; 2735 Unlock(); 2736} 2737 2738 2739void Foo::test7() { 2740 { 2741 Lock(); 2742 mu_->Unlock(); 2743 } 2744 { 2745 mu_->Lock(); 2746 Unlock(); 2747 } 2748 { 2749 mu_.get()->Lock(); 2750 mu_->Unlock(); 2751 } 2752 { 2753 mu_->Lock(); 2754 mu_.get()->Unlock(); 2755 } 2756 { 2757 mu_.get()->Lock(); 2758 (*mu_).Unlock(); 2759 } 2760 { 2761 (*mu_).Lock(); 2762 mu_->Unlock(); 2763 } 2764} 2765 2766 2767void Foo::test8() { 2768 mu_->Lock(); 2769 mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}} 2770 (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}} 2771 mu_.get()->Unlock(); 2772 Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}} 2773} 2774 2775 2776class Bar { 2777 SmartPtr<Foo> foo; 2778 2779 void test0(); 2780 void test1(); 2781 void test2(); 2782 void test3(); 2783}; 2784 2785 2786void Bar::test0() { 2787 foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}} 2788 (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}} 2789 foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}} 2790} 2791 2792 2793void Bar::test1() { 2794 foo->mu_->Lock(); 2795 foo->a = 0; 2796 (*foo).b = 0; 2797 foo.get()->c = 0; 2798 foo->mu_->Unlock(); 2799} 2800 2801 2802void Bar::test2() { 2803 (*foo).mu_->Lock(); 2804 foo->a = 0; 2805 (*foo).b = 0; 2806 foo.get()->c = 0; 2807 foo.get()->mu_->Unlock(); 2808} 2809 2810 2811void Bar::test3() { 2812 MutexLock lock(foo->mu_.get()); 2813 foo->a = 0; 2814 (*foo).b = 0; 2815 foo.get()->c = 0; 2816} 2817 2818} // end namespace SmartPointerTests 2819 2820 2821 2822namespace DuplicateAttributeTest { 2823 2824class LOCKABLE Foo { 2825public: 2826 Mutex mu1_; 2827 Mutex mu2_; 2828 Mutex mu3_; 2829 int a GUARDED_BY(mu1_); 2830 int b GUARDED_BY(mu2_); 2831 int c GUARDED_BY(mu3_); 2832 2833 void lock() EXCLUSIVE_LOCK_FUNCTION(); 2834 void unlock() UNLOCK_FUNCTION(); 2835 2836 void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_); 2837 void slock1() SHARED_LOCK_FUNCTION(mu1_); 2838 void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_); 2839 void locklots() 2840 EXCLUSIVE_LOCK_FUNCTION(mu1_) 2841 EXCLUSIVE_LOCK_FUNCTION(mu2_) 2842 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_); 2843 2844 void unlock1() UNLOCK_FUNCTION(mu1_); 2845 void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_); 2846 void unlocklots() 2847 UNLOCK_FUNCTION(mu1_) 2848 UNLOCK_FUNCTION(mu2_) 2849 UNLOCK_FUNCTION(mu1_, mu2_, mu3_); 2850}; 2851 2852 2853void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { } 2854void Foo::unlock() UNLOCK_FUNCTION() { } 2855 2856void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) { 2857 mu1_.Lock(); 2858} 2859 2860void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) { 2861 mu1_.Lock(); 2862} 2863 2864void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) { 2865 mu1_.Lock(); 2866 mu2_.Lock(); 2867 mu3_.Lock(); 2868} 2869 2870void Foo::locklots() 2871 EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_) 2872 EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) { 2873 mu1_.Lock(); 2874 mu2_.Lock(); 2875 mu3_.Lock(); 2876} 2877 2878void Foo::unlock1() UNLOCK_FUNCTION(mu1_) { 2879 mu1_.Unlock(); 2880} 2881 2882void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) { 2883 mu1_.Unlock(); 2884 mu2_.Unlock(); 2885 mu3_.Unlock(); 2886} 2887 2888void Foo::unlocklots() 2889 UNLOCK_FUNCTION(mu1_, mu2_) 2890 UNLOCK_FUNCTION(mu2_, mu3_) { 2891 mu1_.Unlock(); 2892 mu2_.Unlock(); 2893 mu3_.Unlock(); 2894} 2895 2896 2897void test0() { 2898 Foo foo; 2899 foo.lock(); 2900 foo.unlock(); 2901 2902 foo.lock(); 2903 foo.lock(); // expected-warning {{locking 'foo' that is already locked}} 2904 foo.unlock(); 2905 foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}} 2906} 2907 2908 2909void test1() { 2910 Foo foo; 2911 foo.lock1(); 2912 foo.a = 0; 2913 foo.unlock1(); 2914 2915 foo.lock1(); 2916 foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}} 2917 foo.a = 0; 2918 foo.unlock1(); 2919 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}} 2920} 2921 2922 2923int test2() { 2924 Foo foo; 2925 foo.slock1(); 2926 int d1 = foo.a; 2927 foo.unlock1(); 2928 2929 foo.slock1(); 2930 foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}} 2931 int d2 = foo.a; 2932 foo.unlock1(); 2933 foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}} 2934 return d1 + d2; 2935} 2936 2937 2938void test3() { 2939 Foo foo; 2940 foo.lock3(); 2941 foo.a = 0; 2942 foo.b = 0; 2943 foo.c = 0; 2944 foo.unlock3(); 2945 2946 foo.lock3(); 2947 foo.lock3(); // \ 2948 // expected-warning {{locking 'foo.mu1_' that is already locked}} \ 2949 // expected-warning {{locking 'foo.mu2_' that is already locked}} \ 2950 // expected-warning {{locking 'foo.mu3_' that is already locked}} 2951 foo.a = 0; 2952 foo.b = 0; 2953 foo.c = 0; 2954 foo.unlock3(); 2955 foo.unlock3(); // \ 2956 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \ 2957 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \ 2958 // expected-warning {{unlocking 'foo.mu3_' that was not locked}} 2959} 2960 2961 2962void testlots() { 2963 Foo foo; 2964 foo.locklots(); 2965 foo.a = 0; 2966 foo.b = 0; 2967 foo.c = 0; 2968 foo.unlocklots(); 2969 2970 foo.locklots(); 2971 foo.locklots(); // \ 2972 // expected-warning {{locking 'foo.mu1_' that is already locked}} \ 2973 // expected-warning {{locking 'foo.mu2_' that is already locked}} \ 2974 // expected-warning {{locking 'foo.mu3_' that is already locked}} 2975 foo.a = 0; 2976 foo.b = 0; 2977 foo.c = 0; 2978 foo.unlocklots(); 2979 foo.unlocklots(); // \ 2980 // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \ 2981 // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \ 2982 // expected-warning {{unlocking 'foo.mu3_' that was not locked}} 2983} 2984 2985} // end namespace DuplicateAttributeTest 2986 2987 2988 2989namespace TryLockEqTest { 2990 2991class Foo { 2992 Mutex mu_; 2993 int a GUARDED_BY(mu_); 2994 bool c; 2995 2996 int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_); 2997 Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_); 2998 void unlock() UNLOCK_FUNCTION(mu_); 2999 3000 void test1(); 3001 void test2(); 3002}; 3003 3004 3005void Foo::test1() { 3006 if (tryLockMutexP() == 0) { 3007 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3008 return; 3009 } 3010 a = 0; 3011 unlock(); 3012 3013 if (tryLockMutexP() != 0) { 3014 a = 0; 3015 unlock(); 3016 } 3017 3018 if (0 != tryLockMutexP()) { 3019 a = 0; 3020 unlock(); 3021 } 3022 3023 if (!(tryLockMutexP() == 0)) { 3024 a = 0; 3025 unlock(); 3026 } 3027 3028 if (tryLockMutexI() == 0) { 3029 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3030 return; 3031 } 3032 a = 0; 3033 unlock(); 3034 3035 if (0 == tryLockMutexI()) { 3036 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3037 return; 3038 } 3039 a = 0; 3040 unlock(); 3041 3042 if (tryLockMutexI() == 1) { 3043 a = 0; 3044 unlock(); 3045 } 3046 3047 if (mu_.TryLock() == false) { 3048 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3049 return; 3050 } 3051 a = 0; 3052 unlock(); 3053 3054 if (mu_.TryLock() == true) { 3055 a = 0; 3056 unlock(); 3057 } 3058 else { 3059 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3060 } 3061 3062#if __has_feature(cxx_nullptr) 3063 if (tryLockMutexP() == nullptr) { 3064 a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3065 return; 3066 } 3067 a = 0; 3068 unlock(); 3069#endif 3070} 3071 3072 3073void Foo::test2() { 3074/* FIXME: these tests depend on changes to the CFG. 3075 * 3076 if (mu_.TryLock() && c) { 3077 a = 0; 3078 unlock(); 3079 } 3080 else return; 3081 3082 if (c && mu_.TryLock()) { 3083 a = 0; 3084 unlock(); 3085 } 3086 else return; 3087 3088 if (!(mu_.TryLock() && c)) 3089 return; 3090 a = 0; 3091 unlock(); 3092 3093 if (!(c && mu_.TryLock())) 3094 return; 3095 a = 0; 3096 unlock(); 3097 3098 if (!(mu_.TryLock() == 0) && c) { 3099 a = 0; 3100 unlock(); 3101 } 3102 3103 if (!mu_.TryLock() || c) 3104 return; 3105 a = 0; 3106 unlock(); 3107*/ 3108} 3109 3110} // end namespace TryLockEqTest 3111 3112 3113namespace ExistentialPatternMatching { 3114 3115class Graph { 3116public: 3117 Mutex mu_; 3118}; 3119 3120void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_); 3121void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_); 3122 3123class Node { 3124public: 3125 int a GUARDED_BY(&Graph::mu_); 3126 3127 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) { 3128 a = 0; 3129 } 3130 void foo2() LOCKS_EXCLUDED(&Graph::mu_); 3131}; 3132 3133void test() { 3134 Graph g1; 3135 Graph g2; 3136 Node n1; 3137 3138 n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}} 3139 n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}} 3140 n1.foo2(); 3141 3142 g1.mu_.Lock(); 3143 n1.a = 0; 3144 n1.foo(); 3145 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}} 3146 g1.mu_.Unlock(); 3147 3148 g2.mu_.Lock(); 3149 n1.a = 0; 3150 n1.foo(); 3151 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}} 3152 g2.mu_.Unlock(); 3153 3154 LockAllGraphs(); 3155 n1.a = 0; 3156 n1.foo(); 3157 n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}} 3158 UnlockAllGraphs(); 3159 3160 LockAllGraphs(); 3161 g1.mu_.Unlock(); 3162 3163 LockAllGraphs(); 3164 g2.mu_.Unlock(); 3165 3166 LockAllGraphs(); 3167 g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}} 3168 g1.mu_.Unlock(); 3169} 3170 3171} // end namespace ExistentialPatternMatching 3172 3173 3174namespace StringIgnoreTest { 3175 3176class Foo { 3177public: 3178 Mutex mu_; 3179 void lock() EXCLUSIVE_LOCK_FUNCTION(""); 3180 void unlock() UNLOCK_FUNCTION(""); 3181 void goober() EXCLUSIVE_LOCKS_REQUIRED(""); 3182 void roober() SHARED_LOCKS_REQUIRED(""); 3183}; 3184 3185 3186class Bar : public Foo { 3187public: 3188 void bar(Foo* f) { 3189 f->unlock(); 3190 f->goober(); 3191 f->roober(); 3192 f->lock(); 3193 }; 3194}; 3195 3196} // end namespace StringIgnoreTest 3197 3198 3199namespace LockReturnedScopeFix { 3200 3201class Base { 3202protected: 3203 struct Inner; 3204 bool c; 3205 3206 const Mutex& getLock(const Inner* i); 3207 3208 void lockInner (Inner* i) EXCLUSIVE_LOCK_FUNCTION(getLock(i)); 3209 void unlockInner(Inner* i) UNLOCK_FUNCTION(getLock(i)); 3210 void foo(Inner* i) EXCLUSIVE_LOCKS_REQUIRED(getLock(i)); 3211 3212 void bar(Inner* i); 3213}; 3214 3215 3216struct Base::Inner { 3217 Mutex lock_; 3218 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(lock_); 3219}; 3220 3221 3222const Mutex& Base::getLock(const Inner* i) LOCK_RETURNED(i->lock_) { 3223 return i->lock_; 3224} 3225 3226 3227void Base::foo(Inner* i) { 3228 i->doSomething(); 3229} 3230 3231void Base::bar(Inner* i) { 3232 if (c) { 3233 i->lock_.Lock(); 3234 unlockInner(i); 3235 } 3236 else { 3237 lockInner(i); 3238 i->lock_.Unlock(); 3239 } 3240} 3241 3242} // end namespace LockReturnedScopeFix 3243 3244 3245namespace TrylockWithCleanups { 3246 3247struct Foo { 3248 Mutex mu_; 3249 int a GUARDED_BY(mu_); 3250}; 3251 3252Foo* GetAndLockFoo(const MyString& s) 3253 EXCLUSIVE_TRYLOCK_FUNCTION(true, &Foo::mu_); 3254 3255static void test() { 3256 Foo* lt = GetAndLockFoo("foo"); 3257 if (!lt) return; 3258 int a = lt->a; 3259 lt->mu_.Unlock(); 3260} 3261 3262} // end namespace TrylockWithCleanups 3263 3264 3265namespace UniversalLock { 3266 3267class Foo { 3268 Mutex mu_; 3269 bool c; 3270 3271 int a GUARDED_BY(mu_); 3272 void r_foo() SHARED_LOCKS_REQUIRED(mu_); 3273 void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_); 3274 3275 void test1() { 3276 int b; 3277 3278 beginNoWarnOnReads(); 3279 b = a; 3280 r_foo(); 3281 endNoWarnOnReads(); 3282 3283 beginNoWarnOnWrites(); 3284 a = 0; 3285 w_foo(); 3286 endNoWarnOnWrites(); 3287 } 3288 3289 // don't warn on joins with universal lock 3290 void test2() { 3291 if (c) { 3292 beginNoWarnOnWrites(); 3293 } 3294 a = 0; // \ 3295 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 3296 endNoWarnOnWrites(); // \ 3297 // expected-warning {{unlocking '*' that was not locked}} 3298 } 3299 3300 3301 // make sure the universal lock joins properly 3302 void test3() { 3303 if (c) { 3304 mu_.Lock(); 3305 beginNoWarnOnWrites(); 3306 } 3307 else { 3308 beginNoWarnOnWrites(); 3309 mu_.Lock(); 3310 } 3311 a = 0; 3312 endNoWarnOnWrites(); 3313 mu_.Unlock(); 3314 } 3315 3316 3317 // combine universal lock with other locks 3318 void test4() { 3319 beginNoWarnOnWrites(); 3320 mu_.Lock(); 3321 mu_.Unlock(); 3322 endNoWarnOnWrites(); 3323 3324 mu_.Lock(); 3325 beginNoWarnOnWrites(); 3326 endNoWarnOnWrites(); 3327 mu_.Unlock(); 3328 3329 mu_.Lock(); 3330 beginNoWarnOnWrites(); 3331 mu_.Unlock(); 3332 endNoWarnOnWrites(); 3333 } 3334}; 3335 3336} // end namespace UniversalLock 3337 3338 3339namespace TemplateLockReturned { 3340 3341template<class T> 3342class BaseT { 3343public: 3344 virtual void baseMethod() = 0; 3345 Mutex* get_mutex() LOCK_RETURNED(mutex_) { return &mutex_; } 3346 3347 Mutex mutex_; 3348 int a GUARDED_BY(mutex_); 3349}; 3350 3351 3352class Derived : public BaseT<int> { 3353public: 3354 void baseMethod() EXCLUSIVE_LOCKS_REQUIRED(get_mutex()) { 3355 a = 0; 3356 } 3357}; 3358 3359} // end namespace TemplateLockReturned 3360 3361 3362namespace ExprMatchingBugFix { 3363 3364class Foo { 3365public: 3366 Mutex mu_; 3367}; 3368 3369 3370class Bar { 3371public: 3372 bool c; 3373 Foo* foo; 3374 Bar(Foo* f) : foo(f) { } 3375 3376 struct Nested { 3377 Foo* foo; 3378 Nested(Foo* f) : foo(f) { } 3379 3380 void unlockFoo() UNLOCK_FUNCTION(&Foo::mu_); 3381 }; 3382 3383 void test(); 3384}; 3385 3386 3387void Bar::test() { 3388 foo->mu_.Lock(); 3389 if (c) { 3390 Nested *n = new Nested(foo); 3391 n->unlockFoo(); 3392 } 3393 else { 3394 foo->mu_.Unlock(); 3395 } 3396} 3397 3398}; // end namespace ExprMatchingBugfix 3399 3400 3401namespace ComplexNameTest { 3402 3403class Foo { 3404public: 3405 static Mutex mu_; 3406 3407 Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 3408 ~Foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 3409 3410 int operator[](int i) EXCLUSIVE_LOCKS_REQUIRED(mu_) { return 0; } 3411}; 3412 3413class Bar { 3414public: 3415 static Mutex mu_; 3416 3417 Bar() LOCKS_EXCLUDED(mu_) { } 3418 ~Bar() LOCKS_EXCLUDED(mu_) { } 3419 3420 int operator[](int i) LOCKS_EXCLUDED(mu_) { return 0; } 3421}; 3422 3423 3424void test1() { 3425 Foo f; // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}} 3426 int a = f[0]; // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}} 3427} // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}} 3428 3429 3430void test2() { 3431 Bar::mu_.Lock(); 3432 { 3433 Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}} 3434 int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}} 3435 } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}} 3436 Bar::mu_.Unlock(); 3437} 3438 3439}; // end namespace ComplexNameTest 3440 3441 3442namespace UnreachableExitTest { 3443 3444class FemmeFatale { 3445public: 3446 FemmeFatale(); 3447 ~FemmeFatale() __attribute__((noreturn)); 3448}; 3449 3450void exitNow() __attribute__((noreturn)); 3451void exitDestruct(const MyString& ms) __attribute__((noreturn)); 3452 3453Mutex fatalmu_; 3454 3455void test1() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3456 exitNow(); 3457} 3458 3459void test2() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3460 FemmeFatale femme; 3461} 3462 3463bool c; 3464 3465void test3() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3466 if (c) { 3467 exitNow(); 3468 } 3469 else { 3470 FemmeFatale femme; 3471 } 3472} 3473 3474void test4() EXCLUSIVE_LOCKS_REQUIRED(fatalmu_) { 3475 exitDestruct("foo"); 3476} 3477 3478} // end namespace UnreachableExitTest 3479 3480 3481namespace VirtualMethodCanonicalizationTest { 3482 3483class Base { 3484public: 3485 virtual Mutex* getMutex() = 0; 3486}; 3487 3488class Base2 : public Base { 3489public: 3490 Mutex* getMutex(); 3491}; 3492 3493class Base3 : public Base2 { 3494public: 3495 Mutex* getMutex(); 3496}; 3497 3498class Derived : public Base3 { 3499public: 3500 Mutex* getMutex(); // overrides Base::getMutex() 3501}; 3502 3503void baseFun(Base *b) EXCLUSIVE_LOCKS_REQUIRED(b->getMutex()) { } 3504 3505void derivedFun(Derived *d) EXCLUSIVE_LOCKS_REQUIRED(d->getMutex()) { 3506 baseFun(d); 3507} 3508 3509} // end namespace VirtualMethodCanonicalizationTest 3510 3511 3512namespace TemplateFunctionParamRemapTest { 3513 3514template <class T> 3515struct Cell { 3516 T dummy_; 3517 Mutex* mu_; 3518}; 3519 3520class Foo { 3521public: 3522 template <class T> 3523 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_))); 3524 3525 void test(); 3526}; 3527 3528template<class T> 3529void Foo::elr(Cell<T>* c1) { } 3530 3531void Foo::test() { 3532 Cell<int> cell; 3533 elr(&cell); // \ 3534 // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}} 3535} 3536 3537 3538template<class T> 3539void globalELR(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_))); 3540 3541template<class T> 3542void globalELR(Cell<T>* c1) { } 3543 3544void globalTest() { 3545 Cell<int> cell; 3546 globalELR(&cell); // \ 3547 // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}} 3548} 3549 3550 3551template<class T> 3552void globalELR2(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_))); 3553 3554// second declaration 3555template<class T> 3556void globalELR2(Cell<T>* c2); 3557 3558template<class T> 3559void globalELR2(Cell<T>* c3) { } 3560 3561// re-declaration after definition 3562template<class T> 3563void globalELR2(Cell<T>* c4); 3564 3565void globalTest2() { 3566 Cell<int> cell; 3567 globalELR2(&cell); // \ 3568 // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}} 3569} 3570 3571 3572template<class T> 3573class FooT { 3574public: 3575 void elr(Cell<T>* c) __attribute__((exclusive_locks_required(c->mu_))); 3576}; 3577 3578template<class T> 3579void FooT<T>::elr(Cell<T>* c1) { } 3580 3581void testFooT() { 3582 Cell<int> cell; 3583 FooT<int> foo; 3584 foo.elr(&cell); // \ 3585 // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}} 3586} 3587 3588} // end namespace TemplateFunctionParamRemapTest 3589 3590 3591namespace SelfConstructorTest { 3592 3593class SelfLock { 3594public: 3595 SelfLock() EXCLUSIVE_LOCK_FUNCTION(mu_); 3596 ~SelfLock() UNLOCK_FUNCTION(mu_); 3597 3598 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_); 3599 3600 Mutex mu_; 3601}; 3602 3603class LOCKABLE SelfLock2 { 3604public: 3605 SelfLock2() EXCLUSIVE_LOCK_FUNCTION(); 3606 ~SelfLock2() UNLOCK_FUNCTION(); 3607 3608 void foo() EXCLUSIVE_LOCKS_REQUIRED(this); 3609}; 3610 3611 3612void test() { 3613 SelfLock s; 3614 s.foo(); 3615} 3616 3617void test2() { 3618 SelfLock2 s2; 3619 s2.foo(); 3620} 3621 3622} // end namespace SelfConstructorTest 3623 3624 3625namespace MultipleAttributeTest { 3626 3627class Foo { 3628 Mutex mu1_; 3629 Mutex mu2_; 3630 int a GUARDED_BY(mu1_); 3631 int b GUARDED_BY(mu2_); 3632 int c GUARDED_BY(mu1_) GUARDED_BY(mu2_); 3633 int* d PT_GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_); 3634 3635 void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu1_) 3636 EXCLUSIVE_LOCKS_REQUIRED(mu2_); 3637 void foo2() SHARED_LOCKS_REQUIRED(mu1_) 3638 SHARED_LOCKS_REQUIRED(mu2_); 3639 void foo3() LOCKS_EXCLUDED(mu1_) 3640 LOCKS_EXCLUDED(mu2_); 3641 void lock() EXCLUSIVE_LOCK_FUNCTION(mu1_) 3642 EXCLUSIVE_LOCK_FUNCTION(mu2_); 3643 void readerlock() EXCLUSIVE_LOCK_FUNCTION(mu1_) 3644 EXCLUSIVE_LOCK_FUNCTION(mu2_); 3645 void unlock() UNLOCK_FUNCTION(mu1_) 3646 UNLOCK_FUNCTION(mu2_); 3647 bool trylock() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_) 3648 EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_); 3649 bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_) 3650 SHARED_TRYLOCK_FUNCTION(true, mu2_); 3651 3652 void test(); 3653}; 3654 3655 3656void Foo::foo1() { 3657 a = 1; 3658 b = 2; 3659} 3660 3661void Foo::foo2() { 3662 int result = a + b; 3663} 3664 3665void Foo::foo3() { } 3666void Foo::lock() { } 3667void Foo::readerlock() { } 3668void Foo::unlock() { } 3669bool Foo::trylock() { return true; } 3670bool Foo::readertrylock() { return true; } 3671 3672 3673void Foo::test() { 3674 mu1_.Lock(); 3675 foo1(); // expected-warning {{}} 3676 c = 0; // expected-warning {{}} 3677 *d = 0; // expected-warning {{}} 3678 mu1_.Unlock(); 3679 3680 mu1_.ReaderLock(); 3681 foo2(); // expected-warning {{}} 3682 int x = c; // expected-warning {{}} 3683 int y = *d; // expected-warning {{}} 3684 mu1_.Unlock(); 3685 3686 mu2_.Lock(); 3687 foo3(); // expected-warning {{}} 3688 mu2_.Unlock(); 3689 3690 lock(); 3691 a = 0; 3692 b = 0; 3693 unlock(); 3694 3695 readerlock(); 3696 int z = a + b; 3697 unlock(); 3698 3699 if (trylock()) { 3700 a = 0; 3701 b = 0; 3702 unlock(); 3703 } 3704 3705 if (readertrylock()) { 3706 int zz = a + b; 3707 unlock(); 3708 } 3709} 3710 3711 3712} // end namespace MultipleAttributeTest 3713 3714 3715namespace GuardedNonPrimitiveTypeTest { 3716 3717 3718class Data { 3719public: 3720 Data(int i) : dat(i) { } 3721 3722 int getValue() const { return dat; } 3723 void setValue(int i) { dat = i; } 3724 3725 int operator[](int i) const { return dat; } 3726 int& operator[](int i) { return dat; } 3727 3728 void operator()() { } 3729 3730private: 3731 int dat; 3732}; 3733 3734 3735class DataCell { 3736public: 3737 DataCell(const Data& d) : dat(d) { } 3738 3739private: 3740 Data dat; 3741}; 3742 3743 3744void showDataCell(const DataCell& dc); 3745 3746 3747class Foo { 3748public: 3749 // method call tests 3750 void test() { 3751 data_.setValue(0); // FIXME -- should be writing \ 3752 // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3753 int a = data_.getValue(); // \ 3754 // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3755 3756 datap1_->setValue(0); // FIXME -- should be writing \ 3757 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} 3758 a = datap1_->getValue(); // \ 3759 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} 3760 3761 datap2_->setValue(0); // FIXME -- should be writing \ 3762 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3763 a = datap2_->getValue(); // \ 3764 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3765 3766 (*datap2_).setValue(0); // FIXME -- should be writing \ 3767 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3768 a = (*datap2_).getValue(); // \ 3769 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3770 3771 mu_.Lock(); 3772 data_.setValue(1); 3773 datap1_->setValue(1); 3774 datap2_->setValue(1); 3775 mu_.Unlock(); 3776 3777 mu_.ReaderLock(); 3778 a = data_.getValue(); 3779 datap1_->setValue(0); // reads datap1_, writes *datap1_ 3780 a = datap1_->getValue(); 3781 a = datap2_->getValue(); 3782 mu_.Unlock(); 3783 } 3784 3785 // operator tests 3786 void test2() { 3787 data_ = Data(1); // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} 3788 *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \ 3789 // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3790 *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \ 3791 // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3792 data_ = *datap1_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \ 3793 // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} 3794 data_ = *datap2_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \ 3795 // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3796 3797 data_[0] = 0; // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3798 (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3799 3800 data_(); // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3801 } 3802 3803 // const operator tests 3804 void test3() const { 3805 Data mydat(data_); // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3806 3807 //FIXME 3808 //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires locking 'mu_'}} 3809 //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}} 3810 3811 int a = data_[0]; // expected-warning {{reading variable 'data_' requires locking 'mu_'}} 3812 } 3813 3814private: 3815 Mutex mu_; 3816 Data data_ GUARDED_BY(mu_); 3817 Data* datap1_ GUARDED_BY(mu_); 3818 Data* datap2_ PT_GUARDED_BY(mu_); 3819}; 3820 3821} // end namespace GuardedNonPrimitiveTypeTest 3822 3823 3824namespace GuardedNonPrimitive_MemberAccess { 3825 3826class Cell { 3827public: 3828 Cell(int i); 3829 3830 void cellMethod(); 3831 3832 int a; 3833}; 3834 3835 3836class Foo { 3837public: 3838 int a; 3839 Cell c GUARDED_BY(cell_mu_); 3840 Cell* cp PT_GUARDED_BY(cell_mu_); 3841 3842 void myMethod(); 3843 3844 Mutex cell_mu_; 3845}; 3846 3847 3848class Bar { 3849private: 3850 Mutex mu_; 3851 Foo foo GUARDED_BY(mu_); 3852 Foo* foop PT_GUARDED_BY(mu_); 3853 3854 void test() { 3855 foo.myMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} 3856 3857 int fa = foo.a; // expected-warning {{reading variable 'foo' requires locking 'mu_'}} 3858 foo.a = fa; // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}} 3859 3860 fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} 3861 foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}} 3862 3863 fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} 3864 (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}} 3865 3866 foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \ 3867 // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}} 3868 foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \ 3869 // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}} 3870 3871 foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \ 3872 // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}} 3873 foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \ 3874 // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}} 3875 3876 (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \ 3877 // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}} 3878 (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \ 3879 // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}} 3880 }; 3881}; 3882 3883} // namespace GuardedNonPrimitive_MemberAccess 3884 3885 3886namespace TestThrowExpr { 3887 3888class Foo { 3889 Mutex mu_; 3890 3891 bool hasError(); 3892 3893 void test() { 3894 mu_.Lock(); 3895 if (hasError()) { 3896 throw "ugly"; 3897 } 3898 mu_.Unlock(); 3899 } 3900}; 3901 3902} // end namespace TestThrowExpr 3903 3904 3905namespace UnevaluatedContextTest { 3906 3907// parse attribute expressions in an unevaluated context. 3908 3909static inline Mutex* getMutex1(); 3910static inline Mutex* getMutex2(); 3911 3912void bar() EXCLUSIVE_LOCKS_REQUIRED(getMutex1()); 3913 3914void bar2() EXCLUSIVE_LOCKS_REQUIRED(getMutex1(), getMutex2()); 3915 3916} // end namespace UnevaluatedContextTest 3917 3918