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