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