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