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