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