1 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s 2 3 #define LOCKABLE __attribute__ ((lockable)) 4 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) 5 #define GUARDED_BY(x) __attribute__ ((guarded_by(x))) 6 #define GUARDED_VAR __attribute__ ((guarded_var)) 7 #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) 8 #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) 9 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) 10 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) 11 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) 12 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) 13 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) 14 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) 15 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) 16 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 17 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 18 #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 19 __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 20 #define SHARED_LOCKS_REQUIRED(...) \ 21 __attribute__ ((shared_locks_required(__VA_ARGS__))) 22 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 23 24 //-----------------------------------------// 25 // Helper fields 26 //-----------------------------------------// 27 28 29 class __attribute__((lockable)) Mutex { 30 public: 31 void Lock() __attribute__((exclusive_lock_function)); 32 void ReaderLock() __attribute__((shared_lock_function)); 33 void Unlock() __attribute__((unlock_function)); 34 bool TryLock() __attribute__((exclusive_trylock_function(true))); 35 bool ReaderTryLock() __attribute__((shared_trylock_function(true))); 36 void LockWhen(const int &cond) __attribute__((exclusive_lock_function)); 37 }; 38 39 class __attribute__((scoped_lockable)) MutexLock { 40 public: 41 MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); 42 ~MutexLock() __attribute__((unlock_function)); 43 }; 44 45 class __attribute__((scoped_lockable)) ReaderMutexLock { 46 public: 47 ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); 48 ~ReaderMutexLock() __attribute__((unlock_function)); 49 }; 50 51 52 Mutex sls_mu; 53 54 Mutex sls_mu2 __attribute__((acquired_after(sls_mu))); 55 int sls_guard_var __attribute__((guarded_var)) = 0; 56 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0; 57 58 bool getBool(); 59 60 class MutexWrapper { 61 public: 62 Mutex mu; 63 int x __attribute__((guarded_by(mu))); 64 void MyLock() __attribute__((exclusive_lock_function(mu))); 65 }; 66 67 MutexWrapper sls_mw; 68 69 void sls_fun_0() { 70 sls_mw.mu.Lock(); 71 sls_mw.x = 5; 72 sls_mw.mu.Unlock(); 73 } 74 75 void sls_fun_2() { 76 sls_mu.Lock(); 77 int x = sls_guard_var; 78 sls_mu.Unlock(); 79 } 80 81 void sls_fun_3() { 82 sls_mu.Lock(); 83 sls_guard_var = 2; 84 sls_mu.Unlock(); 85 } 86 87 void sls_fun_4() { 88 sls_mu2.Lock(); 89 sls_guard_var = 2; 90 sls_mu2.Unlock(); 91 } 92 93 void sls_fun_5() { 94 sls_mu.Lock(); 95 int x = sls_guardby_var; 96 sls_mu.Unlock(); 97 } 98 99 void sls_fun_6() { 100 sls_mu.Lock(); 101 sls_guardby_var = 2; 102 sls_mu.Unlock(); 103 } 104 105 void sls_fun_7() { 106 sls_mu.Lock(); 107 sls_mu2.Lock(); 108 sls_mu2.Unlock(); 109 sls_mu.Unlock(); 110 } 111 112 void sls_fun_8() { 113 sls_mu.Lock(); 114 if (getBool()) 115 sls_mu.Unlock(); 116 else 117 sls_mu.Unlock(); 118 } 119 120 void sls_fun_9() { 121 if (getBool()) 122 sls_mu.Lock(); 123 else 124 sls_mu.Lock(); 125 sls_mu.Unlock(); 126 } 127 128 void sls_fun_good_6() { 129 if (getBool()) { 130 sls_mu.Lock(); 131 } else { 132 if (getBool()) { 133 getBool(); // EMPTY 134 } else { 135 getBool(); // EMPTY 136 } 137 sls_mu.Lock(); 138 } 139 sls_mu.Unlock(); 140 } 141 142 void sls_fun_good_7() { 143 sls_mu.Lock(); 144 while (getBool()) { 145 sls_mu.Unlock(); 146 if (getBool()) { 147 if (getBool()) { 148 sls_mu.Lock(); 149 continue; 150 } 151 } 152 sls_mu.Lock(); 153 } 154 sls_mu.Unlock(); 155 } 156 157 void sls_fun_good_8() { 158 sls_mw.MyLock(); 159 sls_mw.mu.Unlock(); 160 } 161 162 void sls_fun_bad_1() { 163 sls_mu.Unlock(); // \ 164 // expected-warning{{unlocking 'sls_mu' that was not locked}} 165 } 166 167 void sls_fun_bad_2() { 168 sls_mu.Lock(); 169 sls_mu.Lock(); // \ 170 // expected-warning{{locking 'sls_mu' that is already locked}} 171 sls_mu.Unlock(); 172 } 173 174 void sls_fun_bad_3() { 175 sls_mu.Lock(); // expected-note {{mutex acquired here}} 176 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} 177 178 void sls_fun_bad_4() { 179 if (getBool()) 180 sls_mu.Lock(); // \ 181 expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} \ 182 expected-note{{mutex acquired here}} 183 184 else 185 sls_mu2.Lock(); // \ 186 expected-note{{mutex acquired here}} 187 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} 188 189 void sls_fun_bad_5() { 190 sls_mu.Lock(); // expected-note {{mutex acquired here}} 191 if (getBool()) 192 sls_mu.Unlock(); 193 } // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} 194 195 void sls_fun_bad_6() { 196 if (getBool()) { 197 sls_mu.Lock(); // expected-note {{mutex acquired here}} 198 } else { 199 if (getBool()) { 200 getBool(); // EMPTY 201 } else { 202 getBool(); // EMPTY 203 } 204 } 205 sls_mu.Unlock(); // \ 206 expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\ 207 expected-warning{{unlocking 'sls_mu' that was not locked}} 208 } 209 210 void sls_fun_bad_7() { 211 sls_mu.Lock(); 212 while (getBool()) { 213 sls_mu.Unlock(); 214 if (getBool()) { 215 if (getBool()) { 216 continue; // \ 217 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 218 } 219 } 220 sls_mu.Lock(); // expected-note {{mutex acquired here}} 221 } 222 sls_mu.Unlock(); 223 } 224 225 void sls_fun_bad_8() { 226 sls_mu.Lock(); // expected-note{{mutex acquired here}} 227 228 // FIXME: TERRIBLE SOURCE LOCATION! 229 do { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 230 sls_mu.Unlock(); 231 } while (getBool()); 232 } 233 234 void sls_fun_bad_9() { 235 do { 236 sls_mu.Lock(); // \ 237 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \ 238 // expected-note{{mutex acquired here}} 239 } while (getBool()); 240 sls_mu.Unlock(); 241 } 242 243 void sls_fun_bad_10() { 244 sls_mu.Lock(); // expected-note 2{{mutex acquired here}} 245 while(getBool()) { 246 sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 247 } 248 } // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} 249 250 void sls_fun_bad_11() { 251 while (getBool()) { // \ 252 expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 253 sls_mu.Lock(); // expected-note {{mutex acquired here}} 254 } 255 sls_mu.Unlock(); // \ 256 // expected-warning{{unlocking 'sls_mu' that was not locked}} 257 } 258 259 void sls_fun_bad_12() { 260 sls_mu.Lock(); // expected-note {{mutex acquired here}} 261 while (getBool()) { 262 sls_mu.Unlock(); 263 if (getBool()) { 264 if (getBool()) { 265 break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} 266 } 267 } 268 sls_mu.Lock(); 269 } 270 sls_mu.Unlock(); 271 } 272 273 //-----------------------------------------// 274 // Handling lock expressions in attribute args 275 // -------------------------------------------// 276 277 Mutex aa_mu; 278 279 class GlobalLocker { 280 public: 281 void globalLock() __attribute__((exclusive_lock_function(aa_mu))); 282 void globalUnlock() __attribute__((unlock_function(aa_mu))); 283 }; 284 285 GlobalLocker glock; 286 287 void aa_fun_1() { 288 glock.globalLock(); 289 glock.globalUnlock(); 290 } 291 292 void aa_fun_bad_1() { 293 glock.globalUnlock(); // \ 294 // expected-warning{{unlocking 'aa_mu' that was not locked}} 295 } 296 297 void aa_fun_bad_2() { 298 glock.globalLock(); 299 glock.globalLock(); // \ 300 // expected-warning{{locking 'aa_mu' that is already locked}} 301 glock.globalUnlock(); 302 } 303 304 void aa_fun_bad_3() { 305 glock.globalLock(); // expected-note{{mutex acquired here}} 306 } // expected-warning{{mutex 'aa_mu' is still locked at the end of function}} 307 308 //--------------------------------------------------// 309 // Regression tests for unusual method names 310 //--------------------------------------------------// 311 312 Mutex wmu; 313 314 // Test diagnostics for other method names. 315 class WeirdMethods { 316 // FIXME: can't currently check inside constructors and destructors. 317 WeirdMethods() { 318 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}} 319 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}} 320 ~WeirdMethods() { 321 wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}} 322 } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}} 323 void operator++() { 324 wmu.Lock(); // expected-note {{mutex acquired here}} 325 } // expected-warning {{mutex 'wmu' is still locked at the end of function}} 326 operator int*() { 327 wmu.Lock(); // expected-note {{mutex acquired here}} 328 return 0; 329 } // expected-warning {{mutex 'wmu' is still locked at the end of function}} 330 }; 331 332 //-----------------------------------------------// 333 // Errors for guarded by or guarded var variables 334 // ----------------------------------------------// 335 336 int *pgb_gvar __attribute__((pt_guarded_var)); 337 int *pgb_var __attribute__((pt_guarded_by(sls_mu))); 338 339 class PGBFoo { 340 public: 341 int x; 342 int *pgb_field __attribute__((guarded_by(sls_mu2))) 343 __attribute__((pt_guarded_by(sls_mu))); 344 void testFoo() { 345 pgb_field = &x; // \ 346 // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}} 347 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 348 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 349 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 350 // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}} 351 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 352 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 353 } 354 }; 355 356 class GBFoo { 357 public: 358 int gb_field __attribute__((guarded_by(sls_mu))); 359 360 void testFoo() { 361 gb_field = 0; // \ 362 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}} 363 } 364 365 void testNoAnal() __attribute__((no_thread_safety_analysis)) { 366 gb_field = 0; 367 } 368 }; 369 370 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu))); 371 372 void gb_fun_0() { 373 sls_mu.Lock(); 374 int x = *pgb_var; 375 sls_mu.Unlock(); 376 } 377 378 void gb_fun_1() { 379 sls_mu.Lock(); 380 *pgb_var = 2; 381 sls_mu.Unlock(); 382 } 383 384 void gb_fun_2() { 385 int x; 386 pgb_var = &x; 387 } 388 389 void gb_fun_3() { 390 int *x = pgb_var; 391 } 392 393 void gb_bad_0() { 394 sls_guard_var = 1; // \ 395 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 396 } 397 398 void gb_bad_1() { 399 int x = sls_guard_var; // \ 400 // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}} 401 } 402 403 void gb_bad_2() { 404 sls_guardby_var = 1; // \ 405 // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}} 406 } 407 408 void gb_bad_3() { 409 int x = sls_guardby_var; // \ 410 // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}} 411 } 412 413 void gb_bad_4() { 414 *pgb_gvar = 1; // \ 415 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}} 416 } 417 418 void gb_bad_5() { 419 int x = *pgb_gvar; // \ 420 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}} 421 } 422 423 void gb_bad_6() { 424 *pgb_var = 1; // \ 425 // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}} 426 } 427 428 void gb_bad_7() { 429 int x = *pgb_var; // \ 430 // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}} 431 } 432 433 void gb_bad_8() { 434 GBFoo G; 435 G.gb_field = 0; // \ 436 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}} 437 } 438 439 void gb_bad_9() { 440 sls_guard_var++; // \ 441 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 442 sls_guard_var--; // \ 443 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 444 ++sls_guard_var; // \ 445 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 446 --sls_guard_var;// \ 447 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 448 } 449 450 //-----------------------------------------------// 451 // Warnings on variables with late parsed attributes 452 // ----------------------------------------------// 453 454 class LateFoo { 455 public: 456 int a __attribute__((guarded_by(mu))); 457 int b; 458 459 void foo() __attribute__((exclusive_locks_required(mu))) { } 460 461 void test() { 462 a = 0; // \ 463 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 464 b = a; // \ 465 // expected-warning {{reading variable 'a' requires locking 'mu'}} 466 c = 0; // \ 467 // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}} 468 } 469 470 int c __attribute__((guarded_by(mu))); 471 472 Mutex mu; 473 }; 474 475 class LateBar { 476 public: 477 int a_ __attribute__((guarded_by(mu1_))); 478 int b_; 479 int *q __attribute__((pt_guarded_by(mu))); 480 Mutex mu1_; 481 Mutex mu; 482 LateFoo Foo; 483 LateFoo Foo2; 484 LateFoo *FooPointer; 485 }; 486 487 LateBar b1, *b3; 488 489 void late_0() { 490 LateFoo FooA; 491 LateFoo FooB; 492 FooA.mu.Lock(); 493 FooA.a = 5; 494 FooA.mu.Unlock(); 495 } 496 497 void late_1() { 498 LateBar BarA; 499 BarA.FooPointer->mu.Lock(); 500 BarA.FooPointer->a = 2; 501 BarA.FooPointer->mu.Unlock(); 502 } 503 504 void late_bad_0() { 505 LateFoo fooA; 506 LateFoo fooB; 507 fooA.mu.Lock(); 508 fooB.a = 5; // \ 509 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 510 fooA.mu.Unlock(); 511 } 512 513 void late_bad_1() { 514 Mutex mu; 515 mu.Lock(); 516 b1.mu1_.Lock(); 517 int res = b1.a_ + b3->b_; 518 b3->b_ = *b1.q; // \ 519 // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}} 520 b1.mu1_.Unlock(); 521 b1.b_ = res; 522 mu.Unlock(); 523 } 524 525 void late_bad_2() { 526 LateBar BarA; 527 BarA.FooPointer->mu.Lock(); 528 BarA.Foo.a = 2; // \ 529 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 530 BarA.FooPointer->mu.Unlock(); 531 } 532 533 void late_bad_3() { 534 LateBar BarA; 535 BarA.Foo.mu.Lock(); 536 BarA.FooPointer->a = 2; // \ 537 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 538 BarA.Foo.mu.Unlock(); 539 } 540 541 void late_bad_4() { 542 LateBar BarA; 543 BarA.Foo.mu.Lock(); 544 BarA.Foo2.a = 2; // \ 545 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 546 BarA.Foo.mu.Unlock(); 547 } 548 549 //-----------------------------------------------// 550 // Extra warnings for shared vs. exclusive locks 551 // ----------------------------------------------// 552 553 void shared_fun_0() { 554 sls_mu.Lock(); 555 do { 556 sls_mu.Unlock(); 557 sls_mu.Lock(); 558 } while (getBool()); 559 sls_mu.Unlock(); 560 } 561 562 void shared_fun_1() { 563 sls_mu.ReaderLock(); // \ 564 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 565 do { 566 sls_mu.Unlock(); 567 sls_mu.Lock(); // \ 568 // expected-note {{the other lock of mutex 'sls_mu' is here}} 569 } while (getBool()); 570 sls_mu.Unlock(); 571 } 572 573 void shared_fun_3() { 574 if (getBool()) 575 sls_mu.Lock(); 576 else 577 sls_mu.Lock(); 578 *pgb_var = 1; 579 sls_mu.Unlock(); 580 } 581 582 void shared_fun_4() { 583 if (getBool()) 584 sls_mu.ReaderLock(); 585 else 586 sls_mu.ReaderLock(); 587 int x = sls_guardby_var; 588 sls_mu.Unlock(); 589 } 590 591 void shared_fun_8() { 592 if (getBool()) 593 sls_mu.Lock(); // \ 594 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 595 else 596 sls_mu.ReaderLock(); // \ 597 // expected-note {{the other lock of mutex 'sls_mu' is here}} 598 sls_mu.Unlock(); 599 } 600 601 void shared_bad_0() { 602 sls_mu.Lock(); // \ 603 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 604 do { 605 sls_mu.Unlock(); 606 sls_mu.ReaderLock(); // \ 607 // expected-note {{the other lock of mutex 'sls_mu' is here}} 608 } while (getBool()); 609 sls_mu.Unlock(); 610 } 611 612 void shared_bad_1() { 613 if (getBool()) 614 sls_mu.Lock(); // \ 615 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 616 else 617 sls_mu.ReaderLock(); // \ 618 // expected-note {{the other lock of mutex 'sls_mu' is here}} 619 *pgb_var = 1; 620 sls_mu.Unlock(); 621 } 622 623 void shared_bad_2() { 624 if (getBool()) 625 sls_mu.ReaderLock(); // \ 626 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 627 else 628 sls_mu.Lock(); // \ 629 // expected-note {{the other lock of mutex 'sls_mu' is here}} 630 *pgb_var = 1; 631 sls_mu.Unlock(); 632 } 633 634 // FIXME: Add support for functions (not only methods) 635 class LRBar { 636 public: 637 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu))); 638 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu))); 639 void le_fun() __attribute__((locks_excluded(sls_mu))); 640 }; 641 642 class LRFoo { 643 public: 644 void test() __attribute__((exclusive_locks_required(sls_mu))); 645 void testShared() __attribute__((shared_locks_required(sls_mu2))); 646 }; 647 648 void elr_fun() __attribute__((exclusive_locks_required(sls_mu))); 649 void elr_fun() {} 650 651 LRFoo MyLRFoo; 652 LRBar Bar; 653 654 void es_fun_0() { 655 aa_mu.Lock(); 656 Bar.aa_elr_fun(); 657 aa_mu.Unlock(); 658 } 659 660 void es_fun_1() { 661 aa_mu.Lock(); 662 Bar.aa_elr_fun_s(); 663 aa_mu.Unlock(); 664 } 665 666 void es_fun_2() { 667 aa_mu.ReaderLock(); 668 Bar.aa_elr_fun_s(); 669 aa_mu.Unlock(); 670 } 671 672 void es_fun_3() { 673 sls_mu.Lock(); 674 MyLRFoo.test(); 675 sls_mu.Unlock(); 676 } 677 678 void es_fun_4() { 679 sls_mu2.Lock(); 680 MyLRFoo.testShared(); 681 sls_mu2.Unlock(); 682 } 683 684 void es_fun_5() { 685 sls_mu2.ReaderLock(); 686 MyLRFoo.testShared(); 687 sls_mu2.Unlock(); 688 } 689 690 void es_fun_6() { 691 Bar.le_fun(); 692 } 693 694 void es_fun_7() { 695 sls_mu.Lock(); 696 elr_fun(); 697 sls_mu.Unlock(); 698 } 699 700 void es_fun_8() __attribute__((no_thread_safety_analysis)); 701 702 void es_fun_8() { 703 Bar.aa_elr_fun_s(); 704 } 705 706 void es_fun_9() __attribute__((shared_locks_required(aa_mu))); 707 void es_fun_9() { 708 Bar.aa_elr_fun_s(); 709 } 710 711 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu))); 712 void es_fun_10() { 713 Bar.aa_elr_fun_s(); 714 } 715 716 void es_bad_0() { 717 Bar.aa_elr_fun(); // \ 718 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 719 } 720 721 void es_bad_1() { 722 aa_mu.ReaderLock(); 723 Bar.aa_elr_fun(); // \ 724 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 725 aa_mu.Unlock(); 726 } 727 728 void es_bad_2() { 729 Bar.aa_elr_fun_s(); // \ 730 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}} 731 } 732 733 void es_bad_3() { 734 MyLRFoo.test(); // \ 735 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 736 } 737 738 void es_bad_4() { 739 MyLRFoo.testShared(); // \ 740 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}} 741 } 742 743 void es_bad_5() { 744 sls_mu.ReaderLock(); 745 MyLRFoo.test(); // \ 746 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 747 sls_mu.Unlock(); 748 } 749 750 void es_bad_6() { 751 sls_mu.Lock(); 752 Bar.le_fun(); // \ 753 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 754 sls_mu.Unlock(); 755 } 756 757 void es_bad_7() { 758 sls_mu.ReaderLock(); 759 Bar.le_fun(); // \ 760 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 761 sls_mu.Unlock(); 762 } 763 764 765 //-----------------------------------------------// 766 // Unparseable lock expressions 767 // ----------------------------------------------// 768 769 // FIXME -- derive new tests for unhandled expressions 770 771 772 //----------------------------------------------------------------------------// 773 // The following test cases are ported from the gcc thread safety implementation 774 // They are each wrapped inside a namespace with the test number of the gcc test 775 // 776 // FIXME: add all the gcc tests, once this analysis passes them. 777 //----------------------------------------------------------------------------// 778 779 //-----------------------------------------// 780 // Good testcases (no errors) 781 //-----------------------------------------// 782 783 namespace thread_annot_lock_20 { 784 class Bar { 785 public: 786 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_); 787 static int b_ GUARDED_BY(mu1_); 788 static Mutex mu1_; 789 static int a_ GUARDED_BY(mu1_); 790 }; 791 792 Bar b1; 793 794 int Bar::func1() 795 { 796 int res = 5; 797 798 if (a_ == 4) 799 res = b_; 800 return res; 801 } 802 } // end namespace thread_annot_lock_20 803 804 namespace thread_annot_lock_22 { 805 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 806 // uses in class definitions. 807 Mutex mu; 808 809 class Bar { 810 public: 811 int a_ GUARDED_BY(mu1_); 812 int b_; 813 int *q PT_GUARDED_BY(mu); 814 Mutex mu1_ ACQUIRED_AFTER(mu); 815 }; 816 817 Bar b1, *b3; 818 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 819 int res GUARDED_BY(mu) = 5; 820 821 int func(int i) 822 { 823 int x; 824 mu.Lock(); 825 b1.mu1_.Lock(); 826 res = b1.a_ + b3->b_; 827 *p = i; 828 b1.a_ = res + b3->b_; 829 b3->b_ = *b1.q; 830 b1.mu1_.Unlock(); 831 b1.b_ = res; 832 x = res; 833 mu.Unlock(); 834 return x; 835 } 836 } // end namespace thread_annot_lock_22 837 838 namespace thread_annot_lock_27_modified { 839 // test lock annotations applied to function definitions 840 // Modified: applied annotations only to function declarations 841 Mutex mu1; 842 Mutex mu2 ACQUIRED_AFTER(mu1); 843 844 class Foo { 845 public: 846 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1); 847 }; 848 849 int Foo::method1(int i) { 850 return i; 851 } 852 853 854 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1); 855 int foo(int i) { 856 return i; 857 } 858 859 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1); 860 static int bar(int i) { 861 return i; 862 } 863 864 void main() { 865 Foo a; 866 867 mu1.Lock(); 868 mu2.Lock(); 869 a.method1(1); 870 foo(2); 871 mu2.Unlock(); 872 bar(3); 873 mu1.Unlock(); 874 } 875 } // end namespace thread_annot_lock_27_modified 876 877 878 namespace thread_annot_lock_38 { 879 // Test the case where a template member function is annotated with lock 880 // attributes in a non-template class. 881 class Foo { 882 public: 883 void func1(int y) LOCKS_EXCLUDED(mu_); 884 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_); 885 private: 886 Mutex mu_; 887 }; 888 889 Foo *foo; 890 891 void main() 892 { 893 foo->func1(5); 894 foo->func2(5); 895 } 896 } // end namespace thread_annot_lock_38 897 898 namespace thread_annot_lock_43 { 899 // Tests lock canonicalization 900 class Foo { 901 public: 902 Mutex *mu_; 903 }; 904 905 class FooBar { 906 public: 907 Foo *foo_; 908 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; } 909 int a_ GUARDED_BY(foo_->mu_); 910 }; 911 912 FooBar *fb; 913 914 void main() 915 { 916 int x; 917 fb->foo_->mu_->Lock(); 918 x = fb->GetA(); 919 fb->foo_->mu_->Unlock(); 920 } 921 } // end namespace thread_annot_lock_43 922 923 namespace thread_annot_lock_49 { 924 // Test the support for use of lock expression in the annotations 925 class Foo { 926 public: 927 Mutex foo_mu_; 928 }; 929 930 class Bar { 931 private: 932 Foo *foo; 933 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_); 934 935 public: 936 void Test1() { 937 foo->foo_mu_.Lock(); 938 bar_mu_.Lock(); 939 bar_mu_.Unlock(); 940 foo->foo_mu_.Unlock(); 941 } 942 }; 943 944 void main() { 945 Bar bar; 946 bar.Test1(); 947 } 948 } // end namespace thread_annot_lock_49 949 950 namespace thread_annot_lock_61_modified { 951 // Modified to fix the compiler errors 952 // Test the fix for a bug introduced by the support of pass-by-reference 953 // paramters. 954 struct Foo { Foo &operator<< (bool) {return *this;} }; 955 Foo &getFoo(); 956 struct Bar { Foo &func () {return getFoo();} }; 957 struct Bas { void operator& (Foo &) {} }; 958 void mumble() 959 { 960 Bas() & Bar().func() << "" << ""; 961 Bas() & Bar().func() << ""; 962 } 963 } // end namespace thread_annot_lock_61_modified 964 965 966 namespace thread_annot_lock_65 { 967 // Test the fix for a bug in the support of allowing reader locks for 968 // non-const, non-modifying overload functions. (We didn't handle the builtin 969 // properly.) 970 enum MyFlags { 971 Zero, 972 One, 973 Two, 974 Three, 975 Four, 976 Five, 977 Six, 978 Seven, 979 Eight, 980 Nine 981 }; 982 983 inline MyFlags 984 operator|(MyFlags a, MyFlags b) 985 { 986 return MyFlags(static_cast<int>(a) | static_cast<int>(b)); 987 } 988 989 inline MyFlags& 990 operator|=(MyFlags& a, MyFlags b) 991 { 992 return a = a | b; 993 } 994 } // end namespace thread_annot_lock_65 995 996 namespace thread_annot_lock_66_modified { 997 // Modified: Moved annotation to function defn 998 // Test annotations on out-of-line definitions of member functions where the 999 // annotations refer to locks that are also data members in the class. 1000 Mutex mu; 1001 1002 class Foo { 1003 public: 1004 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2); 1005 int data GUARDED_BY(mu1); 1006 Mutex *mu1; 1007 Mutex *mu2; 1008 }; 1009 1010 int Foo::method1(int i) 1011 { 1012 return data + i; 1013 } 1014 1015 void main() 1016 { 1017 Foo a; 1018 1019 a.mu2->Lock(); 1020 a.mu1->Lock(); 1021 mu.Lock(); 1022 a.method1(1); 1023 mu.Unlock(); 1024 a.mu1->Unlock(); 1025 a.mu2->Unlock(); 1026 } 1027 } // end namespace thread_annot_lock_66_modified 1028 1029 namespace thread_annot_lock_68_modified { 1030 // Test a fix to a bug in the delayed name binding with nested template 1031 // instantiation. We use a stack to make sure a name is not resolved to an 1032 // inner context. 1033 template <typename T> 1034 class Bar { 1035 Mutex mu_; 1036 }; 1037 1038 template <typename T> 1039 class Foo { 1040 public: 1041 void func(T x) { 1042 mu_.Lock(); 1043 count_ = x; 1044 mu_.Unlock(); 1045 } 1046 1047 private: 1048 T count_ GUARDED_BY(mu_); 1049 Bar<T> bar_; 1050 Mutex mu_; 1051 }; 1052 1053 void main() 1054 { 1055 Foo<int> *foo; 1056 foo->func(5); 1057 } 1058 } // end namespace thread_annot_lock_68_modified 1059 1060 namespace thread_annot_lock_30_modified { 1061 // Test delay parsing of lock attribute arguments with nested classes. 1062 // Modified: trylocks replaced with exclusive_lock_fun 1063 int a = 0; 1064 1065 class Bar { 1066 struct Foo; 1067 1068 public: 1069 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu); 1070 1071 int func() { 1072 MyLock(); 1073 // if (foo == 0) { 1074 // return 0; 1075 // } 1076 a = 5; 1077 mu.Unlock(); 1078 return 1; 1079 } 1080 1081 class FooBar { 1082 int x; 1083 int y; 1084 }; 1085 1086 private: 1087 Mutex mu; 1088 }; 1089 1090 Bar *bar; 1091 1092 void main() 1093 { 1094 bar->func(); 1095 } 1096 } // end namespace thread_annot_lock_30_modified 1097 1098 namespace thread_annot_lock_47 { 1099 // Test the support for annotations on virtual functions. 1100 // This is a good test case. (i.e. There should be no warning emitted by the 1101 // compiler.) 1102 class Base { 1103 public: 1104 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1105 virtual void func2() LOCKS_EXCLUDED(mu_); 1106 Mutex mu_; 1107 }; 1108 1109 class Child : public Base { 1110 public: 1111 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1112 virtual void func2() LOCKS_EXCLUDED(mu_); 1113 }; 1114 1115 void main() { 1116 Child *c; 1117 Base *b = c; 1118 1119 b->mu_.Lock(); 1120 b->func1(); 1121 b->mu_.Unlock(); 1122 b->func2(); 1123 1124 c->mu_.Lock(); 1125 c->func1(); 1126 c->mu_.Unlock(); 1127 c->func2(); 1128 } 1129 } // end namespace thread_annot_lock_47 1130 1131 //-----------------------------------------// 1132 // Tests which produce errors 1133 //-----------------------------------------// 1134 1135 namespace thread_annot_lock_13 { 1136 Mutex mu1; 1137 Mutex mu2; 1138 1139 int g GUARDED_BY(mu1); 1140 int w GUARDED_BY(mu2); 1141 1142 class Foo { 1143 public: 1144 void bar() LOCKS_EXCLUDED(mu_, mu1); 1145 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2); 1146 1147 private: 1148 int a_ GUARDED_BY(mu_); 1149 public: 1150 Mutex mu_ ACQUIRED_AFTER(mu1); 1151 }; 1152 1153 int Foo::foo() 1154 { 1155 int res; 1156 w = 5; 1157 res = a_ + 5; 1158 return res; 1159 } 1160 1161 void Foo::bar() 1162 { 1163 int x; 1164 mu_.Lock(); 1165 x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}} 1166 a_ = x + 1; 1167 mu_.Unlock(); 1168 if (x > 5) { 1169 mu1.Lock(); 1170 g = 2; 1171 mu1.Unlock(); 1172 } 1173 } 1174 1175 void main() 1176 { 1177 Foo f1, *f2; 1178 f1.mu_.Lock(); 1179 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}} 1180 mu2.Lock(); 1181 f1.foo(); 1182 mu2.Unlock(); 1183 f1.mu_.Unlock(); 1184 f2->mu_.Lock(); 1185 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}} 1186 f2->mu_.Unlock(); 1187 mu2.Lock(); 1188 w = 2; 1189 mu2.Unlock(); 1190 } 1191 } // end namespace thread_annot_lock_13 1192 1193 namespace thread_annot_lock_18_modified { 1194 // Modified: Trylocks removed 1195 // Test the ability to distnguish between the same lock field of 1196 // different objects of a class. 1197 class Bar { 1198 public: 1199 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_); 1200 void MyUnlock() UNLOCK_FUNCTION(mu1_); 1201 int a_ GUARDED_BY(mu1_); 1202 1203 private: 1204 Mutex mu1_; 1205 }; 1206 1207 Bar *b1, *b2; 1208 1209 void func() 1210 { 1211 b1->MyLock(); 1212 b1->a_ = 5; 1213 b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}} 1214 b2->MyLock(); 1215 b2->MyUnlock(); 1216 b1->MyUnlock(); 1217 } 1218 } // end namespace thread_annot_lock_18_modified 1219 1220 namespace thread_annot_lock_21 { 1221 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 1222 // uses in class definitions. 1223 Mutex mu; 1224 1225 class Bar { 1226 public: 1227 int a_ GUARDED_BY(mu1_); 1228 int b_; 1229 int *q PT_GUARDED_BY(mu); 1230 Mutex mu1_ ACQUIRED_AFTER(mu); 1231 }; 1232 1233 Bar b1, *b3; 1234 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 1235 1236 int res GUARDED_BY(mu) = 5; 1237 1238 int func(int i) 1239 { 1240 int x; 1241 b3->mu1_.Lock(); 1242 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \ 1243 // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} 1244 *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \ 1245 // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}} 1246 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \ 1247 // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}} 1248 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}} 1249 b3->mu1_.Unlock(); 1250 b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1251 x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1252 return x; 1253 } 1254 } // end namespace thread_annot_lock_21 1255 1256 namespace thread_annot_lock_35_modified { 1257 // Test the analyzer's ability to distinguish the lock field of different 1258 // objects. 1259 class Foo { 1260 private: 1261 Mutex lock_; 1262 int a_ GUARDED_BY(lock_); 1263 1264 public: 1265 void Func(Foo* child) LOCKS_EXCLUDED(lock_) { 1266 Foo *new_foo = new Foo; 1267 1268 lock_.Lock(); 1269 1270 child->Func(new_foo); // There shouldn't be any warning here as the 1271 // acquired lock is not in child. 1272 child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}} 1273 child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}} 1274 lock_.Unlock(); 1275 } 1276 1277 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) { 1278 a_ = y; 1279 } 1280 }; 1281 1282 Foo *x; 1283 1284 void main() { 1285 Foo *child = new Foo; 1286 x->Func(child); 1287 } 1288 } // end namespace thread_annot_lock_35_modified 1289 1290 namespace thread_annot_lock_36_modified { 1291 // Modified to move the annotations to function defns. 1292 // Test the analyzer's ability to distinguish the lock field of different 1293 // objects 1294 class Foo { 1295 private: 1296 Mutex lock_; 1297 int a_ GUARDED_BY(lock_); 1298 1299 public: 1300 void Func(Foo* child) LOCKS_EXCLUDED(lock_); 1301 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_); 1302 }; 1303 1304 void Foo::Func(Foo* child) { 1305 Foo *new_foo = new Foo; 1306 1307 lock_.Lock(); 1308 1309 child->lock_.Lock(); 1310 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}} 1311 child->bar(7); 1312 child->a_ = 5; 1313 child->lock_.Unlock(); 1314 1315 lock_.Unlock(); 1316 } 1317 1318 void Foo::bar(int y) { 1319 a_ = y; 1320 } 1321 1322 1323 Foo *x; 1324 1325 void main() { 1326 Foo *child = new Foo; 1327 x->Func(child); 1328 } 1329 } // end namespace thread_annot_lock_36_modified 1330 1331 1332 namespace thread_annot_lock_42 { 1333 // Test support of multiple lock attributes of the same kind on a decl. 1334 class Foo { 1335 private: 1336 Mutex mu1, mu2, mu3; 1337 int x GUARDED_BY(mu1) GUARDED_BY(mu2); 1338 int y GUARDED_BY(mu2); 1339 1340 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) { 1341 mu2.Lock(); 1342 y = 2; 1343 mu2.Unlock(); 1344 } 1345 1346 public: 1347 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) { 1348 x = 5; 1349 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \ 1350 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}} 1351 } 1352 }; 1353 1354 Foo *foo; 1355 1356 void func() 1357 { 1358 foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \ 1359 // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}} 1360 } 1361 } // end namespace thread_annot_lock_42 1362 1363 namespace thread_annot_lock_46 { 1364 // Test the support for annotations on virtual functions. 1365 class Base { 1366 public: 1367 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1368 virtual void func2() LOCKS_EXCLUDED(mu_); 1369 Mutex mu_; 1370 }; 1371 1372 class Child : public Base { 1373 public: 1374 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1375 virtual void func2() LOCKS_EXCLUDED(mu_); 1376 }; 1377 1378 void main() { 1379 Child *c; 1380 Base *b = c; 1381 1382 b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}} 1383 b->mu_.Lock(); 1384 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}} 1385 b->mu_.Unlock(); 1386 1387 c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}} 1388 c->mu_.Lock(); 1389 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}} 1390 c->mu_.Unlock(); 1391 } 1392 } // end namespace thread_annot_lock_46 1393 1394 namespace thread_annot_lock_67_modified { 1395 // Modified: attributes on definitions moved to declarations 1396 // Test annotations on out-of-line definitions of member functions where the 1397 // annotations refer to locks that are also data members in the class. 1398 Mutex mu; 1399 Mutex mu3; 1400 1401 class Foo { 1402 public: 1403 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3); 1404 int data GUARDED_BY(mu1); 1405 Mutex *mu1; 1406 Mutex *mu2; 1407 }; 1408 1409 int Foo::method1(int i) { 1410 return data + i; 1411 } 1412 1413 void main() 1414 { 1415 Foo a; 1416 a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \ 1417 // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \ 1418 // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \ 1419 // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}} 1420 } 1421 } // end namespace thread_annot_lock_67_modified 1422 1423 1424 namespace substitution_test { 1425 class MyData { 1426 public: 1427 Mutex mu; 1428 1429 void lockData() __attribute__((exclusive_lock_function(mu))) { } 1430 void unlockData() __attribute__((unlock_function(mu))) { } 1431 1432 void doSomething() __attribute__((exclusive_locks_required(mu))) { } 1433 }; 1434 1435 1436 class DataLocker { 1437 public: 1438 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { } 1439 void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { } 1440 }; 1441 1442 1443 class Foo { 1444 public: 1445 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { } 1446 1447 void bar1(MyData* d) { 1448 d->lockData(); 1449 foo(d); 1450 d->unlockData(); 1451 } 1452 1453 void bar2(MyData* d) { 1454 DataLocker dlr; 1455 dlr.lockData(d); 1456 foo(d); 1457 dlr.unlockData(d); 1458 } 1459 1460 void bar3(MyData* d1, MyData* d2) { 1461 DataLocker dlr; 1462 dlr.lockData(d1); // expected-note {{mutex acquired here}} 1463 dlr.unlockData(d2); // \ 1464 // expected-warning {{unlocking 'mu' that was not locked}} 1465 } // expected-warning {{mutex 'mu' is still locked at the end of function}} 1466 1467 void bar4(MyData* d1, MyData* d2) { 1468 DataLocker dlr; 1469 dlr.lockData(d1); 1470 foo(d2); // \ 1471 // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}} 1472 dlr.unlockData(d1); 1473 } 1474 }; 1475 } // end namespace substituation_test 1476 1477 1478 1479 namespace constructor_destructor_tests { 1480 Mutex fooMu; 1481 int myVar GUARDED_BY(fooMu); 1482 1483 class Foo { 1484 public: 1485 Foo() __attribute__((exclusive_lock_function(fooMu))) { } 1486 ~Foo() __attribute__((unlock_function(fooMu))) { } 1487 }; 1488 1489 void fooTest() { 1490 Foo foo; 1491 myVar = 0; 1492 } 1493 } 1494 1495 1496 namespace invalid_lock_expression_test { 1497 1498 class LOCKABLE MyLockable { 1499 public: 1500 MyLockable() __attribute__((exclusive_lock_function)) { } 1501 ~MyLockable() { } 1502 }; 1503 1504 // create an empty lock expression 1505 void foo() { 1506 MyLockable lock; // \ 1507 // expected-warning {{cannot resolve lock expression}} 1508 } 1509 1510 } // end namespace invalid_lock_expression_test 1511 1512 namespace template_member_test { 1513 1514 struct S { int n; }; 1515 struct T { 1516 Mutex m; 1517 S *s GUARDED_BY(this->m); 1518 }; 1519 Mutex m; 1520 struct U { 1521 union { 1522 int n; 1523 }; 1524 } *u GUARDED_BY(m); 1525 1526 template<typename U> 1527 struct IndirectLock { 1528 int DoNaughtyThings(T *t) { 1529 u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}} 1530 return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}} 1531 } 1532 }; 1533 1534 template struct IndirectLock<int>; // expected-note {{here}} 1535 1536 struct V { 1537 void f(int); 1538 void f(double); 1539 1540 Mutex m; 1541 V *p GUARDED_BY(this->m); 1542 }; 1543 template<typename U> struct W { 1544 V v; 1545 void f(U u) { 1546 v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}} 1547 } 1548 }; 1549 template struct W<int>; // expected-note {{here}} 1550 1551 } 1552 1553 namespace test_scoped_lockable { 1554 1555 struct TestScopedLockable { 1556 Mutex mu1; 1557 Mutex mu2; 1558 int a __attribute__((guarded_by(mu1))); 1559 int b __attribute__((guarded_by(mu2))); 1560 1561 bool getBool(); 1562 1563 void foo1() { 1564 MutexLock mulock(&mu1); 1565 a = 5; 1566 } 1567 1568 void foo2() { 1569 ReaderMutexLock mulock1(&mu1); 1570 if (getBool()) { 1571 MutexLock mulock2a(&mu2); 1572 b = a + 1; 1573 } 1574 else { 1575 MutexLock mulock2b(&mu2); 1576 b = a + 2; 1577 } 1578 } 1579 1580 void foo3() { 1581 MutexLock mulock_a(&mu1); 1582 MutexLock mulock_b(&mu1); // \ 1583 // expected-warning {{locking 'mu1' that is already locked}} 1584 } // expected-warning {{unlocking 'mu1' that was not locked}} 1585 1586 void foo4() { 1587 MutexLock mulock1(&mu1), mulock2(&mu2); 1588 a = b+1; 1589 b = a+1; 1590 } 1591 }; 1592 1593 } // end namespace test_scoped_lockable 1594 1595 1596 namespace FunctionAttrTest { 1597 1598 class Foo { 1599 public: 1600 Mutex mu_; 1601 int a GUARDED_BY(mu_); 1602 }; 1603 1604 Foo fooObj; 1605 1606 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_); 1607 1608 void bar() { 1609 foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}} 1610 fooObj.mu_.Lock(); 1611 foo(); 1612 fooObj.mu_.Unlock(); 1613 } 1614 1615 }; // end namespace FunctionAttrTest 1616 1617 1618 struct TestTryLock { 1619 Mutex mu; 1620 int a GUARDED_BY(mu); 1621 bool cond; 1622 1623 void foo1() { 1624 if (mu.TryLock()) { 1625 a = 1; 1626 mu.Unlock(); 1627 } 1628 } 1629 1630 void foo2() { 1631 if (!mu.TryLock()) return; 1632 a = 2; 1633 mu.Unlock(); 1634 } 1635 1636 void foo3() { 1637 bool b = mu.TryLock(); 1638 if (b) { 1639 a = 3; 1640 mu.Unlock(); 1641 } 1642 } 1643 1644 void foo4() { 1645 bool b = mu.TryLock(); 1646 if (!b) return; 1647 a = 4; 1648 mu.Unlock(); 1649 } 1650 1651 void foo5() { 1652 while (mu.TryLock()) { 1653 a = a + 1; 1654 mu.Unlock(); 1655 } 1656 } 1657 1658 void foo6() { 1659 bool b = mu.TryLock(); 1660 b = !b; 1661 if (b) return; 1662 a = 6; 1663 mu.Unlock(); 1664 } 1665 1666 void foo7() { 1667 bool b1 = mu.TryLock(); 1668 bool b2 = !b1; 1669 bool b3 = !b2; 1670 if (b3) { 1671 a = 7; 1672 mu.Unlock(); 1673 } 1674 } 1675 1676 // Test use-def chains: join points 1677 void foo8() { 1678 bool b = mu.TryLock(); 1679 bool b2 = b; 1680 if (cond) 1681 b = true; 1682 if (b) { // b should be unknown at this point, becuase of the join point 1683 a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}} 1684 } 1685 if (b2) { // b2 should be known at this point. 1686 a = 8; 1687 mu.Unlock(); 1688 } 1689 } 1690 1691 // Test use-def-chains: back edges 1692 void foo9() { 1693 bool b = mu.TryLock(); 1694 1695 for (int i = 0; i < 10; ++i); 1696 1697 if (b) { // b is still known, because the loop doesn't alter it 1698 a = 9; 1699 mu.Unlock(); 1700 } 1701 } 1702 1703 // Test use-def chains: back edges 1704 void foo10() { 1705 bool b = mu.TryLock(); 1706 1707 while (cond) { 1708 if (b) { // b should be uknown at this point b/c of the loop 1709 a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}} 1710 } 1711 b = !b; 1712 } 1713 } 1714 }; // end TestTrylock 1715 1716 1717 namespace TestTemplateAttributeInstantiation { 1718 1719 class Foo1 { 1720 public: 1721 Mutex mu_; 1722 int a GUARDED_BY(mu_); 1723 }; 1724 1725 class Foo2 { 1726 public: 1727 int a GUARDED_BY(mu_); 1728 Mutex mu_; 1729 }; 1730 1731 1732 class Bar { 1733 public: 1734 // Test non-dependent expressions in attributes on template functions 1735 template <class T> 1736 void barND(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(foo->mu_) { 1737 foo->a = 0; 1738 } 1739 1740 // Test dependent expressions in attributes on template functions 1741 template <class T> 1742 void barD(Foo1 *foo, T *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooT->mu_) { 1743 fooT->a = 0; 1744 } 1745 }; 1746 1747 1748 template <class T> 1749 class BarT { 1750 public: 1751 Foo1 fooBase; 1752 T fooBaseT; 1753 1754 // Test non-dependent expression in ordinary method on template class 1755 void barND() EXCLUSIVE_LOCKS_REQUIRED(fooBase.mu_) { 1756 fooBase.a = 0; 1757 } 1758 1759 // Test dependent expressions in ordinary methods on template class 1760 void barD() EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_) { 1761 fooBaseT.a = 0; 1762 } 1763 1764 // Test dependent expressions in template method in template class 1765 template <class T2> 1766 void barTD(T2 *fooT) EXCLUSIVE_LOCKS_REQUIRED(fooBaseT.mu_, fooT->mu_) { 1767 fooBaseT.a = 0; 1768 fooT->a = 0; 1769 } 1770 }; 1771 1772 template <class T> 1773 class Cell { 1774 public: 1775 Mutex mu_; 1776 // Test dependent guarded_by 1777 T data GUARDED_BY(mu_); 1778 1779 void fooEx() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 1780 data = 0; 1781 } 1782 1783 void foo() { 1784 mu_.Lock(); 1785 data = 0; 1786 mu_.Unlock(); 1787 } 1788 }; 1789 1790 void test() { 1791 Bar b; 1792 BarT<Foo2> bt; 1793 Foo1 f1; 1794 Foo2 f2; 1795 1796 f1.mu_.Lock(); 1797 f2.mu_.Lock(); 1798 bt.fooBase.mu_.Lock(); 1799 bt.fooBaseT.mu_.Lock(); 1800 1801 b.barND(&f1, &f2); 1802 b.barD(&f1, &f2); 1803 bt.barND(); 1804 bt.barD(); 1805 bt.barTD(&f2); 1806 1807 f1.mu_.Unlock(); 1808 bt.barTD(&f1); // \ 1809 // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}} 1810 1811 bt.fooBase.mu_.Unlock(); 1812 bt.fooBaseT.mu_.Unlock(); 1813 f2.mu_.Unlock(); 1814 1815 Cell<int> cell; 1816 cell.data = 0; // \ 1817 // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}} 1818 cell.foo(); 1819 cell.mu_.Lock(); 1820 cell.fooEx(); 1821 cell.mu_.Unlock(); 1822 } 1823 1824 1825 template <class T> 1826 class CellDelayed { 1827 public: 1828 // Test dependent guarded_by 1829 T data GUARDED_BY(mu_); 1830 static T static_data GUARDED_BY(static_mu_); 1831 1832 void fooEx(CellDelayed<T> *other) EXCLUSIVE_LOCKS_REQUIRED(mu_, other->mu_) { 1833 this->data = other->data; 1834 } 1835 1836 template <class T2> 1837 void fooExT(CellDelayed<T2> *otherT) EXCLUSIVE_LOCKS_REQUIRED(mu_, otherT->mu_) { 1838 this->data = otherT->data; 1839 } 1840 1841 void foo() { 1842 mu_.Lock(); 1843 data = 0; 1844 mu_.Unlock(); 1845 } 1846 1847 Mutex mu_; 1848 static Mutex static_mu_; 1849 }; 1850 1851 void testDelayed() { 1852 CellDelayed<int> celld; 1853 CellDelayed<int> celld2; 1854 celld.foo(); 1855 celld.mu_.Lock(); 1856 celld2.mu_.Lock(); 1857 1858 celld.fooEx(&celld2); 1859 celld.fooExT(&celld2); 1860 1861 celld2.mu_.Unlock(); 1862 celld.mu_.Unlock(); 1863 } 1864 1865 }; // end namespace TestTemplateAttributeInstantiation 1866 1867 1868 namespace FunctionDeclDefTest { 1869 1870 class Foo { 1871 public: 1872 Mutex mu_; 1873 int a GUARDED_BY(mu_); 1874 1875 virtual void foo1(Foo *f_declared) EXCLUSIVE_LOCKS_REQUIRED(f_declared->mu_); 1876 }; 1877 1878 // EXCLUSIVE_LOCKS_REQUIRED should be applied, and rewritten to f_defined->mu_ 1879 void Foo::foo1(Foo *f_defined) { 1880 f_defined->a = 0; 1881 }; 1882 1883 void test() { 1884 Foo myfoo; 1885 myfoo.foo1(&myfoo); // \ 1886 // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}} 1887 myfoo.mu_.Lock(); 1888 myfoo.foo1(&myfoo); 1889 myfoo.mu_.Unlock(); 1890 } 1891 1892 }; 1893 1894 namespace GoingNative { 1895 1896 struct __attribute__((lockable)) mutex { 1897 void lock() __attribute__((exclusive_lock_function)); 1898 void unlock() __attribute__((unlock_function)); 1899 // ... 1900 }; 1901 bool foo(); 1902 bool bar(); 1903 mutex m; 1904 void test() { 1905 m.lock(); 1906 while (foo()) { 1907 m.unlock(); 1908 // ... 1909 if (bar()) { 1910 // ... 1911 if (foo()) 1912 continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}} 1913 //... 1914 } 1915 // ... 1916 m.lock(); // expected-note {{mutex acquired here}} 1917 } 1918 m.unlock(); 1919 } 1920 1921 } 1922 1923 1924 1925 namespace FunctionDefinitionTest { 1926 1927 class Foo { 1928 public: 1929 void foo1(); 1930 void foo2(); 1931 void foo3(Foo *other); 1932 1933 template<class T> 1934 void fooT1(const T& dummy1); 1935 1936 template<class T> 1937 void fooT2(const T& dummy2) EXCLUSIVE_LOCKS_REQUIRED(mu_); 1938 1939 Mutex mu_; 1940 int a GUARDED_BY(mu_); 1941 }; 1942 1943 template<class T> 1944 class FooT { 1945 public: 1946 void foo(); 1947 1948 Mutex mu_; 1949 T a GUARDED_BY(mu_); 1950 }; 1951 1952 1953 void Foo::foo1() NO_THREAD_SAFETY_ANALYSIS { 1954 a = 1; 1955 } 1956 1957 void Foo::foo2() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 1958 a = 2; 1959 } 1960 1961 void Foo::foo3(Foo *other) EXCLUSIVE_LOCKS_REQUIRED(other->mu_) { 1962 other->a = 3; 1963 } 1964 1965 template<class T> 1966 void Foo::fooT1(const T& dummy1) EXCLUSIVE_LOCKS_REQUIRED(mu_) { 1967 a = dummy1; 1968 } 1969 1970 /* TODO -- uncomment with template instantiation of attributes. 1971 template<class T> 1972 void Foo::fooT2(const T& dummy2) { 1973 a = dummy2; 1974 } 1975 */ 1976 1977 void fooF1(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { 1978 f->a = 1; 1979 } 1980 1981 void fooF2(Foo *f); 1982 void fooF2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { 1983 f->a = 2; 1984 } 1985 1986 void fooF3(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_); 1987 void fooF3(Foo *f) { 1988 f->a = 3; 1989 } 1990 1991 template<class T> 1992 void FooT<T>::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { 1993 a = 0; 1994 } 1995 1996 void test() { 1997 int dummy = 0; 1998 Foo myFoo; 1999 2000 myFoo.foo2(); // \ 2001 // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}} 2002 myFoo.foo3(&myFoo); // \ 2003 // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}} 2004 myFoo.fooT1(dummy); // \ 2005 // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}} 2006 2007 // FIXME: uncomment with template instantiation of attributes patch 2008 // myFoo.fooT2(dummy); // expected warning 2009 2010 fooF1(&myFoo); // \ 2011 // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}} 2012 fooF2(&myFoo); // \ 2013 // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}} 2014 fooF3(&myFoo); // \ 2015 // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}} 2016 2017 myFoo.mu_.Lock(); 2018 myFoo.foo2(); 2019 myFoo.foo3(&myFoo); 2020 myFoo.fooT1(dummy); 2021 2022 // FIXME: uncomment with template instantiation of attributes patch 2023 // myFoo.fooT2(dummy); 2024 2025 fooF1(&myFoo); 2026 fooF2(&myFoo); 2027 fooF3(&myFoo); 2028 myFoo.mu_.Unlock(); 2029 2030 FooT<int> myFooT; 2031 myFooT.foo(); // \ 2032 // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}} 2033 } 2034 2035 } // end namespace FunctionDefinitionTest 2036 2037 2038 namespace SelfLockingTest { 2039 2040 class LOCKABLE MyLock { 2041 public: 2042 int foo GUARDED_BY(this); 2043 2044 void lock() EXCLUSIVE_LOCK_FUNCTION(); 2045 void unlock() UNLOCK_FUNCTION(); 2046 2047 void doSomething() { 2048 this->lock(); // allow 'this' as a lock expression 2049 foo = 0; 2050 doSomethingElse(); 2051 this->unlock(); 2052 } 2053 2054 void doSomethingElse() EXCLUSIVE_LOCKS_REQUIRED(this) { 2055 foo = 1; 2056 }; 2057 2058 void test() { 2059 foo = 2; // \ 2060 // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}} 2061 } 2062 }; 2063 2064 2065 class LOCKABLE MyLock2 { 2066 public: 2067 Mutex mu_; 2068 int foo GUARDED_BY(this); 2069 2070 // don't check inside lock and unlock functions 2071 void lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); } 2072 void unlock() UNLOCK_FUNCTION() { mu_.Unlock(); } 2073 2074 // don't check inside constructors and destructors 2075 MyLock2() { foo = 1; } 2076 ~MyLock2() { foo = 0; } 2077 }; 2078 2079 2080 } // end namespace SelfLockingTest 2081 2082 2083 namespace InvalidNonstatic { 2084 2085 // Forward decl here causes bogus "invalid use of non-static data member" 2086 // on reference to mutex_ in guarded_by attribute. 2087 class Foo; 2088 2089 class Foo { 2090 Mutex* mutex_; 2091 2092 int foo __attribute__((guarded_by(mutex_))); 2093 }; 2094 2095 } // end namespace InvalidNonStatic 2096 2097 2098 namespace NoReturnTest { 2099 2100 bool condition(); 2101 void fatal() __attribute__((noreturn)); 2102 2103 Mutex mu_; 2104 2105 void test1() { 2106 MutexLock lock(&mu_); 2107 if (condition()) { 2108 fatal(); 2109 return; 2110 } 2111 } 2112 2113 } // end namespace NoReturnTest 2114 2115 2116 namespace TestMultiDecl { 2117 2118 class Foo { 2119 public: 2120 int GUARDED_BY(mu_) a; 2121 int GUARDED_BY(mu_) b, c; 2122 2123 void foo() { 2124 a = 0; // \ 2125 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2126 b = 0; // \ 2127 // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}} 2128 c = 0; // \ 2129 // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}} 2130 } 2131 2132 private: 2133 Mutex mu_; 2134 }; 2135 2136 } // end namespace TestMultiDecl 2137 2138 2139 namespace WarnNoDecl { 2140 2141 class Foo { 2142 void foo(int a); __attribute__(( // \ 2143 // expected-warning {{declaration does not declare anything}} 2144 exclusive_locks_required(a))); // \ 2145 // expected-warning {{attribute exclusive_locks_required ignored}} 2146 }; 2147 2148 } // end namespace WarnNoDecl 2149 2150 2151 2152 namespace MoreLockExpressions { 2153 2154 class Foo { 2155 public: 2156 Mutex mu_; 2157 int a GUARDED_BY(mu_); 2158 }; 2159 2160 class Bar { 2161 public: 2162 int b; 2163 Foo* f; 2164 2165 Foo& getFoo() { return *f; } 2166 Foo& getFoo2(int c) { return *f; } 2167 Foo& getFoo3(int c, int d) { return *f; } 2168 2169 Foo& getFooey() { return *f; } 2170 }; 2171 2172 Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); } 2173 2174 void test() { 2175 Foo foo; 2176 Foo *fooArray; 2177 Bar bar; 2178 int a; 2179 int b; 2180 int c; 2181 2182 bar.getFoo().mu_.Lock(); 2183 bar.getFoo().a = 0; 2184 bar.getFoo().mu_.Unlock(); 2185 2186 (bar.getFoo().mu_).Lock(); // test parenthesis 2187 bar.getFoo().a = 0; 2188 (bar.getFoo().mu_).Unlock(); 2189 2190 bar.getFoo2(a).mu_.Lock(); 2191 bar.getFoo2(a).a = 0; 2192 bar.getFoo2(a).mu_.Unlock(); 2193 2194 bar.getFoo3(a, b).mu_.Lock(); 2195 bar.getFoo3(a, b).a = 0; 2196 bar.getFoo3(a, b).mu_.Unlock(); 2197 2198 getBarFoo(bar, a).mu_.Lock(); 2199 getBarFoo(bar, a).a = 0; 2200 getBarFoo(bar, a).mu_.Unlock(); 2201 2202 bar.getFoo2(10).mu_.Lock(); 2203 bar.getFoo2(10).a = 0; 2204 bar.getFoo2(10).mu_.Unlock(); 2205 2206 bar.getFoo2(a + 1).mu_.Lock(); 2207 bar.getFoo2(a + 1).a = 0; 2208 bar.getFoo2(a + 1).mu_.Unlock(); 2209 2210 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock(); 2211 (a > 0 ? fooArray[1] : fooArray[b]).a = 0; 2212 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock(); 2213 2214 bar.getFoo().mu_.Lock(); 2215 bar.getFooey().a = 0; // \ 2216 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2217 bar.getFoo().mu_.Unlock(); 2218 2219 bar.getFoo2(a).mu_.Lock(); 2220 bar.getFoo2(b).a = 0; // \ 2221 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2222 bar.getFoo2(a).mu_.Unlock(); 2223 2224 bar.getFoo3(a, b).mu_.Lock(); 2225 bar.getFoo3(a, c).a = 0; // \ 2226 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2227 bar.getFoo3(a, b).mu_.Unlock(); 2228 2229 getBarFoo(bar, a).mu_.Lock(); 2230 getBarFoo(bar, b).a = 0; // \ 2231 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2232 getBarFoo(bar, a).mu_.Unlock(); 2233 2234 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock(); 2235 (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \ 2236 // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} 2237 (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock(); 2238 } 2239 2240 2241 } // end namespace 2242 2243 2244