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 40 Mutex sls_mu; 41 42 Mutex sls_mu2 __attribute__((acquired_after(sls_mu))); 43 int sls_guard_var __attribute__((guarded_var)) = 0; 44 int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0; 45 46 bool getBool(); 47 48 class MutexWrapper { 49 public: 50 Mutex mu; 51 int x __attribute__((guarded_by(mu))); 52 void MyLock() __attribute__((exclusive_lock_function(mu))); 53 }; 54 55 MutexWrapper sls_mw; 56 57 void sls_fun_0() { 58 sls_mw.mu.Lock(); 59 sls_mw.x = 5; 60 sls_mw.mu.Unlock(); 61 } 62 63 void sls_fun_2() { 64 sls_mu.Lock(); 65 int x = sls_guard_var; 66 sls_mu.Unlock(); 67 } 68 69 void sls_fun_3() { 70 sls_mu.Lock(); 71 sls_guard_var = 2; 72 sls_mu.Unlock(); 73 } 74 75 void sls_fun_4() { 76 sls_mu2.Lock(); 77 sls_guard_var = 2; 78 sls_mu2.Unlock(); 79 } 80 81 void sls_fun_5() { 82 sls_mu.Lock(); 83 int x = sls_guardby_var; 84 sls_mu.Unlock(); 85 } 86 87 void sls_fun_6() { 88 sls_mu.Lock(); 89 sls_guardby_var = 2; 90 sls_mu.Unlock(); 91 } 92 93 void sls_fun_7() { 94 sls_mu.Lock(); 95 sls_mu2.Lock(); 96 sls_mu2.Unlock(); 97 sls_mu.Unlock(); 98 } 99 100 void sls_fun_8() { 101 sls_mu.Lock(); 102 if (getBool()) 103 sls_mu.Unlock(); 104 else 105 sls_mu.Unlock(); 106 } 107 108 void sls_fun_9() { 109 if (getBool()) 110 sls_mu.Lock(); 111 else 112 sls_mu.Lock(); 113 sls_mu.Unlock(); 114 } 115 116 void sls_fun_good_6() { 117 if (getBool()) { 118 sls_mu.Lock(); 119 } else { 120 if (getBool()) { 121 getBool(); // EMPTY 122 } else { 123 getBool(); // EMPTY 124 } 125 sls_mu.Lock(); 126 } 127 sls_mu.Unlock(); 128 } 129 130 void sls_fun_good_7() { 131 sls_mu.Lock(); 132 while (getBool()) { 133 sls_mu.Unlock(); 134 if (getBool()) { 135 if (getBool()) { 136 sls_mu.Lock(); 137 continue; 138 } 139 } 140 sls_mu.Lock(); 141 } 142 sls_mu.Unlock(); 143 } 144 145 void sls_fun_good_8() { 146 sls_mw.MyLock(); 147 sls_mw.mu.Unlock(); 148 } 149 150 void sls_fun_bad_1() { 151 sls_mu.Unlock(); // \ 152 // expected-warning{{unlocking 'sls_mu' that was not locked}} 153 } 154 155 void sls_fun_bad_2() { 156 sls_mu.Lock(); 157 sls_mu.Lock(); // \ 158 // expected-warning{{locking 'sls_mu' that is already locked}} 159 sls_mu.Unlock(); 160 } 161 162 void sls_fun_bad_3() { 163 sls_mu.Lock(); // \ 164 // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_3'}} 165 } 166 167 void sls_fun_bad_4() { 168 if (getBool()) 169 sls_mu.Lock(); // \ 170 // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}} 171 else 172 sls_mu2.Lock(); // \ 173 // expected-warning{{mutex 'sls_mu2' is still locked at the end of its scope}} 174 } 175 176 void sls_fun_bad_5() { 177 sls_mu.Lock(); // \ 178 // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}} 179 if (getBool()) 180 sls_mu.Unlock(); 181 } 182 183 void sls_fun_bad_6() { 184 if (getBool()) { 185 sls_mu.Lock(); // \ 186 // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}} 187 } else { 188 if (getBool()) { 189 getBool(); // EMPTY 190 } else { 191 getBool(); // EMPTY 192 } 193 } 194 sls_mu.Unlock(); // \ 195 // expected-warning{{unlocking 'sls_mu' that was not locked}} 196 } 197 198 void sls_fun_bad_7() { 199 sls_mu.Lock(); // \ 200 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 201 while (getBool()) { 202 sls_mu.Unlock(); 203 if (getBool()) { 204 if (getBool()) { 205 continue; 206 } 207 } 208 sls_mu.Lock(); // \ 209 // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}} 210 } 211 sls_mu.Unlock(); 212 } 213 214 void sls_fun_bad_8() { 215 sls_mu.Lock(); // \ 216 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 217 do { 218 sls_mu.Unlock(); 219 } while (getBool()); 220 } 221 222 void sls_fun_bad_9() { 223 do { 224 sls_mu.Lock(); // \ 225 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 226 } while (getBool()); 227 sls_mu.Unlock(); 228 } 229 230 void sls_fun_bad_10() { 231 sls_mu.Lock(); // \ 232 // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_10'}} \ 233 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 234 while(getBool()) { 235 sls_mu.Unlock(); 236 } 237 } 238 239 void sls_fun_bad_11() { 240 while (getBool()) { 241 sls_mu.Lock(); // \ 242 // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} 243 } 244 sls_mu.Unlock(); // \ 245 // expected-warning{{unlocking 'sls_mu' that was not locked}} 246 } 247 248 //-----------------------------------------// 249 // Handling lock expressions in attribute args 250 // -------------------------------------------// 251 252 Mutex aa_mu; 253 254 class GlobalLocker { 255 public: 256 void globalLock() __attribute__((exclusive_lock_function(aa_mu))); 257 void globalUnlock() __attribute__((unlock_function(aa_mu))); 258 }; 259 260 GlobalLocker glock; 261 262 void aa_fun_1() { 263 glock.globalLock(); 264 glock.globalUnlock(); 265 } 266 267 void aa_fun_bad_1() { 268 glock.globalUnlock(); // \ 269 // expected-warning{{unlocking 'aa_mu' that was not locked}} 270 } 271 272 void aa_fun_bad_2() { 273 glock.globalLock(); 274 glock.globalLock(); // \ 275 // expected-warning{{locking 'aa_mu' that is already locked}} 276 glock.globalUnlock(); 277 } 278 279 void aa_fun_bad_3() { 280 glock.globalLock(); // \ 281 // expected-warning{{mutex 'aa_mu' is still locked at the end of function 'aa_fun_bad_3'}} 282 } 283 284 //--------------------------------------------------// 285 // Regression tests for unusual method names 286 //--------------------------------------------------// 287 288 Mutex wmu; 289 290 // Test diagnostics for other method names. 291 class WeirdMethods { 292 WeirdMethods() { 293 wmu.Lock(); // \ 294 // expected-warning {{mutex 'wmu' is still locked at the end of function 'WeirdMethods'}} 295 } 296 ~WeirdMethods() { 297 wmu.Lock(); // \ 298 // expected-warning {{mutex 'wmu' is still locked at the end of function '~WeirdMethods'}} 299 } 300 void operator++() { 301 wmu.Lock(); // \ 302 // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator++'}} 303 } 304 operator int*() { 305 wmu.Lock(); // \ 306 // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator int *'}} 307 return 0; 308 } 309 }; 310 311 //-----------------------------------------------// 312 // Errors for guarded by or guarded var variables 313 // ----------------------------------------------// 314 315 int *pgb_gvar __attribute__((pt_guarded_var)); 316 int *pgb_var __attribute__((pt_guarded_by(sls_mu))); 317 318 class PGBFoo { 319 public: 320 int x; 321 int *pgb_field __attribute__((guarded_by(sls_mu2))) 322 __attribute__((pt_guarded_by(sls_mu))); 323 void testFoo() { 324 pgb_field = &x; // \ 325 // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}} 326 *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 327 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 328 x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 329 // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}} 330 (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \ 331 // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}} 332 } 333 }; 334 335 class GBFoo { 336 public: 337 int gb_field __attribute__((guarded_by(sls_mu))); 338 339 void testFoo() { 340 gb_field = 0; // \ 341 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}} 342 } 343 344 void testNoAnal() __attribute__((no_thread_safety_analysis)) { 345 gb_field = 0; 346 } 347 }; 348 349 GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu))); 350 351 void gb_fun_0() { 352 sls_mu.Lock(); 353 int x = *pgb_var; 354 sls_mu.Unlock(); 355 } 356 357 void gb_fun_1() { 358 sls_mu.Lock(); 359 *pgb_var = 2; 360 sls_mu.Unlock(); 361 } 362 363 void gb_fun_2() { 364 int x; 365 pgb_var = &x; 366 } 367 368 void gb_fun_3() { 369 int *x = pgb_var; 370 } 371 372 void gb_bad_0() { 373 sls_guard_var = 1; // \ 374 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 375 } 376 377 void gb_bad_1() { 378 int x = sls_guard_var; // \ 379 // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}} 380 } 381 382 void gb_bad_2() { 383 sls_guardby_var = 1; // \ 384 // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}} 385 } 386 387 void gb_bad_3() { 388 int x = sls_guardby_var; // \ 389 // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}} 390 } 391 392 void gb_bad_4() { 393 *pgb_gvar = 1; // \ 394 // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}} 395 } 396 397 void gb_bad_5() { 398 int x = *pgb_gvar; // \ 399 // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}} 400 } 401 402 void gb_bad_6() { 403 *pgb_var = 1; // \ 404 // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}} 405 } 406 407 void gb_bad_7() { 408 int x = *pgb_var; // \ 409 // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}} 410 } 411 412 void gb_bad_8() { 413 GBFoo G; 414 G.gb_field = 0; // \ 415 // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}} 416 } 417 418 void gb_bad_9() { 419 sls_guard_var++; // \ 420 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 421 sls_guard_var--; // \ 422 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 423 ++sls_guard_var; // \ 424 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 425 --sls_guard_var;// \ 426 // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}} 427 } 428 429 //-----------------------------------------------// 430 // Warnings on variables with late parsed attributes 431 // ----------------------------------------------// 432 433 class LateFoo { 434 public: 435 int a __attribute__((guarded_by(mu))); 436 int b; 437 438 void foo() __attribute__((exclusive_locks_required(mu))) { } 439 440 void test() { 441 a = 0; // \ 442 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 443 b = a; // \ 444 // expected-warning {{reading variable 'a' requires locking 'mu'}} 445 c = 0; // \ 446 // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}} 447 } 448 449 int c __attribute__((guarded_by(mu))); 450 451 Mutex mu; 452 }; 453 454 class LateBar { 455 public: 456 int a_ __attribute__((guarded_by(mu1_))); 457 int b_; 458 int *q __attribute__((pt_guarded_by(mu))); 459 Mutex mu1_; 460 Mutex mu; 461 LateFoo Foo; 462 LateFoo Foo2; 463 LateFoo *FooPointer; 464 }; 465 466 LateBar b1, *b3; 467 468 void late_0() { 469 LateFoo FooA; 470 LateFoo FooB; 471 FooA.mu.Lock(); 472 FooA.a = 5; 473 FooA.mu.Unlock(); 474 } 475 476 void late_1() { 477 LateBar BarA; 478 BarA.FooPointer->mu.Lock(); 479 BarA.FooPointer->a = 2; 480 BarA.FooPointer->mu.Unlock(); 481 } 482 483 void late_bad_0() { 484 LateFoo fooA; 485 LateFoo fooB; 486 fooA.mu.Lock(); 487 fooB.a = 5; // \ 488 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 489 fooA.mu.Unlock(); 490 } 491 492 void late_bad_1() { 493 Mutex mu; 494 mu.Lock(); 495 b1.mu1_.Lock(); 496 int res = b1.a_ + b3->b_; 497 b3->b_ = *b1.q; // \ 498 // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}} 499 b1.mu1_.Unlock(); 500 b1.b_ = res; 501 mu.Unlock(); 502 } 503 504 void late_bad_2() { 505 LateBar BarA; 506 BarA.FooPointer->mu.Lock(); 507 BarA.Foo.a = 2; // \ 508 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 509 BarA.FooPointer->mu.Unlock(); 510 } 511 512 void late_bad_3() { 513 LateBar BarA; 514 BarA.Foo.mu.Lock(); 515 BarA.FooPointer->a = 2; // \ 516 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 517 BarA.Foo.mu.Unlock(); 518 } 519 520 void late_bad_4() { 521 LateBar BarA; 522 BarA.Foo.mu.Lock(); 523 BarA.Foo2.a = 2; // \ 524 // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}} 525 BarA.Foo.mu.Unlock(); 526 } 527 528 //-----------------------------------------------// 529 // Extra warnings for shared vs. exclusive locks 530 // ----------------------------------------------// 531 532 void shared_fun_0() { 533 sls_mu.Lock(); 534 do { 535 sls_mu.Unlock(); 536 sls_mu.Lock(); 537 } while (getBool()); 538 sls_mu.Unlock(); 539 } 540 541 void shared_fun_1() { 542 sls_mu.ReaderLock(); // \ 543 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 544 do { 545 sls_mu.Unlock(); 546 sls_mu.Lock(); // \ 547 // expected-note {{the other lock of mutex 'sls_mu' is here}} 548 } while (getBool()); 549 sls_mu.Unlock(); 550 } 551 552 void shared_fun_3() { 553 if (getBool()) 554 sls_mu.Lock(); 555 else 556 sls_mu.Lock(); 557 *pgb_var = 1; 558 sls_mu.Unlock(); 559 } 560 561 void shared_fun_4() { 562 if (getBool()) 563 sls_mu.ReaderLock(); 564 else 565 sls_mu.ReaderLock(); 566 int x = sls_guardby_var; 567 sls_mu.Unlock(); 568 } 569 570 void shared_fun_8() { 571 if (getBool()) 572 sls_mu.Lock(); // \ 573 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 574 else 575 sls_mu.ReaderLock(); // \ 576 // expected-note {{the other lock of mutex 'sls_mu' is here}} 577 sls_mu.Unlock(); 578 } 579 580 void shared_bad_0() { 581 sls_mu.Lock(); // \ 582 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 583 do { 584 sls_mu.Unlock(); 585 sls_mu.ReaderLock(); // \ 586 // expected-note {{the other lock of mutex 'sls_mu' is here}} 587 } while (getBool()); 588 sls_mu.Unlock(); 589 } 590 591 void shared_bad_1() { 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 *pgb_var = 1; 599 sls_mu.Unlock(); 600 } 601 602 void shared_bad_2() { 603 if (getBool()) 604 sls_mu.ReaderLock(); // \ 605 // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}} 606 else 607 sls_mu.Lock(); // \ 608 // expected-note {{the other lock of mutex 'sls_mu' is here}} 609 *pgb_var = 1; 610 sls_mu.Unlock(); 611 } 612 613 // FIXME: Add support for functions (not only methods) 614 class LRBar { 615 public: 616 void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu))); 617 void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu))); 618 void le_fun() __attribute__((locks_excluded(sls_mu))); 619 }; 620 621 class LRFoo { 622 public: 623 void test() __attribute__((exclusive_locks_required(sls_mu))); 624 void testShared() __attribute__((shared_locks_required(sls_mu2))); 625 }; 626 627 void elr_fun() __attribute__((exclusive_locks_required(sls_mu))); 628 void elr_fun() {} 629 630 LRFoo MyLRFoo; 631 LRBar Bar; 632 633 void es_fun_0() { 634 aa_mu.Lock(); 635 Bar.aa_elr_fun(); 636 aa_mu.Unlock(); 637 } 638 639 void es_fun_1() { 640 aa_mu.Lock(); 641 Bar.aa_elr_fun_s(); 642 aa_mu.Unlock(); 643 } 644 645 void es_fun_2() { 646 aa_mu.ReaderLock(); 647 Bar.aa_elr_fun_s(); 648 aa_mu.Unlock(); 649 } 650 651 void es_fun_3() { 652 sls_mu.Lock(); 653 MyLRFoo.test(); 654 sls_mu.Unlock(); 655 } 656 657 void es_fun_4() { 658 sls_mu2.Lock(); 659 MyLRFoo.testShared(); 660 sls_mu2.Unlock(); 661 } 662 663 void es_fun_5() { 664 sls_mu2.ReaderLock(); 665 MyLRFoo.testShared(); 666 sls_mu2.Unlock(); 667 } 668 669 void es_fun_6() { 670 Bar.le_fun(); 671 } 672 673 void es_fun_7() { 674 sls_mu.Lock(); 675 elr_fun(); 676 sls_mu.Unlock(); 677 } 678 679 void es_fun_8() __attribute__((no_thread_safety_analysis)); 680 681 void es_fun_8() { 682 Bar.aa_elr_fun_s(); 683 } 684 685 void es_fun_9() __attribute__((shared_locks_required(aa_mu))); 686 void es_fun_9() { 687 Bar.aa_elr_fun_s(); 688 } 689 690 void es_fun_10() __attribute__((exclusive_locks_required(aa_mu))); 691 void es_fun_10() { 692 Bar.aa_elr_fun_s(); 693 } 694 695 void es_bad_0() { 696 Bar.aa_elr_fun(); // \ 697 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 698 } 699 700 void es_bad_1() { 701 aa_mu.ReaderLock(); 702 Bar.aa_elr_fun(); // \ 703 // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}} 704 aa_mu.Unlock(); 705 } 706 707 void es_bad_2() { 708 Bar.aa_elr_fun_s(); // \ 709 // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}} 710 } 711 712 void es_bad_3() { 713 MyLRFoo.test(); // \ 714 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 715 } 716 717 void es_bad_4() { 718 MyLRFoo.testShared(); // \ 719 // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}} 720 } 721 722 void es_bad_5() { 723 sls_mu.ReaderLock(); 724 MyLRFoo.test(); // \ 725 // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}} 726 sls_mu.Unlock(); 727 } 728 729 void es_bad_6() { 730 sls_mu.Lock(); 731 Bar.le_fun(); // \ 732 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 733 sls_mu.Unlock(); 734 } 735 736 void es_bad_7() { 737 sls_mu.ReaderLock(); 738 Bar.le_fun(); // \ 739 // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}} 740 sls_mu.Unlock(); 741 } 742 743 744 //-----------------------------------------------// 745 // Unparseable lock expressions 746 // ----------------------------------------------// 747 748 Mutex UPmu; 749 // FIXME: add support for lock expressions involving arrays. 750 Mutex mua[5]; 751 752 int x __attribute__((guarded_by(UPmu = sls_mu))); 753 int y __attribute__((guarded_by(mua[0]))); 754 755 756 void testUnparse() { 757 x = 5; // \ 758 // expected-warning{{cannot resolve lock expression}} 759 y = 5; // \ 760 // expected-warning{{cannot resolve lock expression}} 761 } 762 763 void testUnparse2() { 764 mua[0].Lock(); // \ 765 // expected-warning{{cannot resolve lock expression}} 766 (&(mua[0]) + 4)->Lock(); // \ 767 // expected-warning{{cannot resolve lock expression}} 768 } 769 770 771 //----------------------------------------------------------------------------// 772 // The following test cases are ported from the gcc thread safety implementation 773 // They are each wrapped inside a namespace with the test number of the gcc test 774 // 775 // FIXME: add all the gcc tests, once this analysis passes them. 776 //----------------------------------------------------------------------------// 777 778 //-----------------------------------------// 779 // Good testcases (no errors) 780 //-----------------------------------------// 781 782 namespace thread_annot_lock_20 { 783 class Bar { 784 public: 785 static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_); 786 static int b_ GUARDED_BY(mu1_); 787 static Mutex mu1_; 788 static int a_ GUARDED_BY(mu1_); 789 }; 790 791 Bar b1; 792 793 int Bar::func1() 794 { 795 int res = 5; 796 797 if (a_ == 4) 798 res = b_; 799 return res; 800 } 801 } // end namespace thread_annot_lock_20 802 803 namespace thread_annot_lock_22 { 804 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 805 // uses in class definitions. 806 Mutex mu; 807 808 class Bar { 809 public: 810 int a_ GUARDED_BY(mu1_); 811 int b_; 812 int *q PT_GUARDED_BY(mu); 813 Mutex mu1_ ACQUIRED_AFTER(mu); 814 }; 815 816 Bar b1, *b3; 817 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 818 int res GUARDED_BY(mu) = 5; 819 820 int func(int i) 821 { 822 int x; 823 mu.Lock(); 824 b1.mu1_.Lock(); 825 res = b1.a_ + b3->b_; 826 *p = i; 827 b1.a_ = res + b3->b_; 828 b3->b_ = *b1.q; 829 b1.mu1_.Unlock(); 830 b1.b_ = res; 831 x = res; 832 mu.Unlock(); 833 return x; 834 } 835 } // end namespace thread_annot_lock_22 836 837 namespace thread_annot_lock_27_modified { 838 // test lock annotations applied to function definitions 839 // Modified: applied annotations only to function declarations 840 Mutex mu1; 841 Mutex mu2 ACQUIRED_AFTER(mu1); 842 843 class Foo { 844 public: 845 int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1); 846 }; 847 848 int Foo::method1(int i) { 849 return i; 850 } 851 852 853 int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1); 854 int foo(int i) { 855 return i; 856 } 857 858 static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1); 859 static int bar(int i) { 860 return i; 861 } 862 863 void main() { 864 Foo a; 865 866 mu1.Lock(); 867 mu2.Lock(); 868 a.method1(1); 869 foo(2); 870 mu2.Unlock(); 871 bar(3); 872 mu1.Unlock(); 873 } 874 } // end namespace thread_annot_lock_27_modified 875 876 877 namespace thread_annot_lock_38 { 878 // Test the case where a template member function is annotated with lock 879 // attributes in a non-template class. 880 class Foo { 881 public: 882 void func1(int y) LOCKS_EXCLUDED(mu_); 883 template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_); 884 private: 885 Mutex mu_; 886 }; 887 888 Foo *foo; 889 890 void main() 891 { 892 foo->func1(5); 893 foo->func2(5); 894 } 895 } // end namespace thread_annot_lock_38 896 897 namespace thread_annot_lock_43 { 898 // Tests lock canonicalization 899 class Foo { 900 public: 901 Mutex *mu_; 902 }; 903 904 class FooBar { 905 public: 906 Foo *foo_; 907 int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; } 908 int a_ GUARDED_BY(foo_->mu_); 909 }; 910 911 FooBar *fb; 912 913 void main() 914 { 915 int x; 916 fb->foo_->mu_->Lock(); 917 x = fb->GetA(); 918 fb->foo_->mu_->Unlock(); 919 } 920 } // end namespace thread_annot_lock_43 921 922 namespace thread_annot_lock_49 { 923 // Test the support for use of lock expression in the annotations 924 class Foo { 925 public: 926 Mutex foo_mu_; 927 }; 928 929 class Bar { 930 private: 931 Foo *foo; 932 Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_); 933 934 public: 935 void Test1() { 936 foo->foo_mu_.Lock(); 937 bar_mu_.Lock(); 938 bar_mu_.Unlock(); 939 foo->foo_mu_.Unlock(); 940 } 941 }; 942 943 void main() { 944 Bar bar; 945 bar.Test1(); 946 } 947 } // end namespace thread_annot_lock_49 948 949 namespace thread_annot_lock_61_modified { 950 // Modified to fix the compiler errors 951 // Test the fix for a bug introduced by the support of pass-by-reference 952 // paramters. 953 struct Foo { Foo &operator<< (bool) {return *this;} }; 954 Foo &getFoo(); 955 struct Bar { Foo &func () {return getFoo();} }; 956 struct Bas { void operator& (Foo &) {} }; 957 void mumble() 958 { 959 Bas() & Bar().func() << "" << ""; 960 Bas() & Bar().func() << ""; 961 } 962 } // end namespace thread_annot_lock_61_modified 963 964 965 namespace thread_annot_lock_65 { 966 // Test the fix for a bug in the support of allowing reader locks for 967 // non-const, non-modifying overload functions. (We didn't handle the builtin 968 // properly.) 969 enum MyFlags { 970 Zero, 971 One, 972 Two, 973 Three, 974 Four, 975 Five, 976 Six, 977 Seven, 978 Eight, 979 Nine 980 }; 981 982 inline MyFlags 983 operator|(MyFlags a, MyFlags b) 984 { 985 return MyFlags(static_cast<int>(a) | static_cast<int>(b)); 986 } 987 988 inline MyFlags& 989 operator|=(MyFlags& a, MyFlags b) 990 { 991 return a = a | b; 992 } 993 } // end namespace thread_annot_lock_65 994 995 namespace thread_annot_lock_66_modified { 996 // Modified: Moved annotation to function defn 997 // Test annotations on out-of-line definitions of member functions where the 998 // annotations refer to locks that are also data members in the class. 999 Mutex mu; 1000 1001 class Foo { 1002 public: 1003 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2); 1004 int data GUARDED_BY(mu1); 1005 Mutex *mu1; 1006 Mutex *mu2; 1007 }; 1008 1009 int Foo::method1(int i) 1010 { 1011 return data + i; 1012 } 1013 1014 void main() 1015 { 1016 Foo a; 1017 1018 a.mu2->Lock(); 1019 a.mu1->Lock(); 1020 mu.Lock(); 1021 a.method1(1); 1022 mu.Unlock(); 1023 a.mu1->Unlock(); 1024 a.mu2->Unlock(); 1025 } 1026 } // end namespace thread_annot_lock_66_modified 1027 1028 namespace thread_annot_lock_68_modified { 1029 // Test a fix to a bug in the delayed name binding with nested template 1030 // instantiation. We use a stack to make sure a name is not resolved to an 1031 // inner context. 1032 template <typename T> 1033 class Bar { 1034 Mutex mu_; 1035 }; 1036 1037 template <typename T> 1038 class Foo { 1039 public: 1040 void func(T x) { 1041 mu_.Lock(); 1042 count_ = x; 1043 mu_.Unlock(); 1044 } 1045 1046 private: 1047 T count_ GUARDED_BY(mu_); 1048 Bar<T> bar_; 1049 Mutex mu_; 1050 }; 1051 1052 void main() 1053 { 1054 Foo<int> *foo; 1055 foo->func(5); 1056 } 1057 } // end namespace thread_annot_lock_68_modified 1058 1059 namespace thread_annot_lock_30_modified { 1060 // Test delay parsing of lock attribute arguments with nested classes. 1061 // Modified: trylocks replaced with exclusive_lock_fun 1062 int a = 0; 1063 1064 class Bar { 1065 struct Foo; 1066 1067 public: 1068 void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu); 1069 1070 int func() { 1071 MyLock(); 1072 // if (foo == 0) { 1073 // return 0; 1074 // } 1075 a = 5; 1076 mu.Unlock(); 1077 return 1; 1078 } 1079 1080 class FooBar { 1081 int x; 1082 int y; 1083 }; 1084 1085 private: 1086 Mutex mu; 1087 }; 1088 1089 Bar *bar; 1090 1091 void main() 1092 { 1093 bar->func(); 1094 } 1095 } // end namespace thread_annot_lock_30_modified 1096 1097 namespace thread_annot_lock_47 { 1098 // Test the support for annotations on virtual functions. 1099 // This is a good test case. (i.e. There should be no warning emitted by the 1100 // compiler.) 1101 class Base { 1102 public: 1103 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1104 virtual void func2() LOCKS_EXCLUDED(mu_); 1105 Mutex mu_; 1106 }; 1107 1108 class Child : public Base { 1109 public: 1110 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1111 virtual void func2() LOCKS_EXCLUDED(mu_); 1112 }; 1113 1114 void main() { 1115 Child *c; 1116 Base *b = c; 1117 1118 b->mu_.Lock(); 1119 b->func1(); 1120 b->mu_.Unlock(); 1121 b->func2(); 1122 1123 c->mu_.Lock(); 1124 c->func1(); 1125 c->mu_.Unlock(); 1126 c->func2(); 1127 } 1128 } // end namespace thread_annot_lock_47 1129 1130 //-----------------------------------------// 1131 // Tests which produce errors 1132 //-----------------------------------------// 1133 1134 namespace thread_annot_lock_13 { 1135 Mutex mu1; 1136 Mutex mu2; 1137 1138 int g GUARDED_BY(mu1); 1139 int w GUARDED_BY(mu2); 1140 1141 class Foo { 1142 public: 1143 void bar() LOCKS_EXCLUDED(mu_, mu1); 1144 int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2); 1145 1146 private: 1147 int a_ GUARDED_BY(mu_); 1148 public: 1149 Mutex mu_ ACQUIRED_AFTER(mu1); 1150 }; 1151 1152 int Foo::foo() 1153 { 1154 int res; 1155 w = 5.2; 1156 res = a_ + 5; 1157 return res; 1158 } 1159 1160 void Foo::bar() 1161 { 1162 int x; 1163 mu_.Lock(); 1164 x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}} 1165 a_ = x + 1; 1166 mu_.Unlock(); 1167 if (x > 5) { 1168 mu1.Lock(); 1169 g = 2.3; 1170 mu1.Unlock(); 1171 } 1172 } 1173 1174 void main() 1175 { 1176 Foo f1, *f2; 1177 f1.mu_.Lock(); 1178 f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}} 1179 mu2.Lock(); 1180 f1.foo(); 1181 mu2.Unlock(); 1182 f1.mu_.Unlock(); 1183 f2->mu_.Lock(); 1184 f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}} 1185 f2->mu_.Unlock(); 1186 mu2.Lock(); 1187 w = 2.5; 1188 mu2.Unlock(); 1189 } 1190 } // end namespace thread_annot_lock_13 1191 1192 namespace thread_annot_lock_18_modified { 1193 // Modified: Trylocks removed 1194 // Test the ability to distnguish between the same lock field of 1195 // different objects of a class. 1196 class Bar { 1197 public: 1198 bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_); 1199 void MyUnlock() UNLOCK_FUNCTION(mu1_); 1200 int a_ GUARDED_BY(mu1_); 1201 1202 private: 1203 Mutex mu1_; 1204 }; 1205 1206 Bar *b1, *b2; 1207 1208 void func() 1209 { 1210 b1->MyLock(); 1211 b1->a_ = 5; 1212 b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}} 1213 b2->MyLock(); 1214 b2->MyUnlock(); 1215 b1->MyUnlock(); 1216 } 1217 } // end namespace thread_annot_lock_18_modified 1218 1219 namespace thread_annot_lock_21 { 1220 // Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially 1221 // uses in class definitions. 1222 Mutex mu; 1223 1224 class Bar { 1225 public: 1226 int a_ GUARDED_BY(mu1_); 1227 int b_; 1228 int *q PT_GUARDED_BY(mu); 1229 Mutex mu1_ ACQUIRED_AFTER(mu); 1230 }; 1231 1232 Bar b1, *b3; 1233 int *p GUARDED_BY(mu) PT_GUARDED_BY(mu); 1234 1235 int res GUARDED_BY(mu) = 5; 1236 1237 int func(int i) 1238 { 1239 int x; 1240 b3->mu1_.Lock(); 1241 res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \ 1242 // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} 1243 *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \ 1244 // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}} 1245 b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \ 1246 // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}} 1247 b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}} 1248 b3->mu1_.Unlock(); 1249 b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1250 x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}} 1251 return x; 1252 } 1253 } // end namespace thread_annot_lock_21 1254 1255 namespace thread_annot_lock_35_modified { 1256 // Test the analyzer's ability to distinguish the lock field of different 1257 // objects. 1258 class Foo { 1259 private: 1260 Mutex lock_; 1261 int a_ GUARDED_BY(lock_); 1262 1263 public: 1264 void Func(Foo* child) LOCKS_EXCLUDED(lock_) { 1265 Foo *new_foo = new Foo; 1266 1267 lock_.Lock(); 1268 1269 child->Func(new_foo); // There shouldn't be any warning here as the 1270 // acquired lock is not in child. 1271 child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}} 1272 child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}} 1273 lock_.Unlock(); 1274 } 1275 1276 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) { 1277 a_ = y; 1278 } 1279 }; 1280 1281 Foo *x; 1282 1283 void main() { 1284 Foo *child = new Foo; 1285 x->Func(child); 1286 } 1287 } // end namespace thread_annot_lock_35_modified 1288 1289 namespace thread_annot_lock_36_modified { 1290 // Modified to move the annotations to function defns. 1291 // Test the analyzer's ability to distinguish the lock field of different 1292 // objects 1293 class Foo { 1294 private: 1295 Mutex lock_; 1296 int a_ GUARDED_BY(lock_); 1297 1298 public: 1299 void Func(Foo* child) LOCKS_EXCLUDED(lock_); 1300 void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_); 1301 }; 1302 1303 void Foo::Func(Foo* child) { 1304 Foo *new_foo = new Foo; 1305 1306 lock_.Lock(); 1307 1308 child->lock_.Lock(); 1309 child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}} 1310 child->bar(7); 1311 child->a_ = 5; 1312 child->lock_.Unlock(); 1313 1314 lock_.Unlock(); 1315 } 1316 1317 void Foo::bar(int y) { 1318 a_ = y; 1319 } 1320 1321 1322 Foo *x; 1323 1324 void main() { 1325 Foo *child = new Foo; 1326 x->Func(child); 1327 } 1328 } // end namespace thread_annot_lock_36_modified 1329 1330 1331 namespace thread_annot_lock_42 { 1332 // Test support of multiple lock attributes of the same kind on a decl. 1333 class Foo { 1334 private: 1335 Mutex mu1, mu2, mu3; 1336 int x GUARDED_BY(mu1) GUARDED_BY(mu2); 1337 int y GUARDED_BY(mu2); 1338 1339 void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) { 1340 mu2.Lock(); 1341 y = 2; 1342 mu2.Unlock(); 1343 } 1344 1345 public: 1346 void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) { 1347 x = 5; 1348 f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \ 1349 // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}} 1350 } 1351 }; 1352 1353 Foo *foo; 1354 1355 void func() 1356 { 1357 foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \ 1358 // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}} 1359 } 1360 } // end namespace thread_annot_lock_42 1361 1362 namespace thread_annot_lock_46 { 1363 // Test the support for annotations on virtual functions. 1364 class Base { 1365 public: 1366 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1367 virtual void func2() LOCKS_EXCLUDED(mu_); 1368 Mutex mu_; 1369 }; 1370 1371 class Child : public Base { 1372 public: 1373 virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_); 1374 virtual void func2() LOCKS_EXCLUDED(mu_); 1375 }; 1376 1377 void main() { 1378 Child *c; 1379 Base *b = c; 1380 1381 b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}} 1382 b->mu_.Lock(); 1383 b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}} 1384 b->mu_.Unlock(); 1385 1386 c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}} 1387 c->mu_.Lock(); 1388 c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}} 1389 c->mu_.Unlock(); 1390 } 1391 } // end namespace thread_annot_lock_46 1392 1393 namespace thread_annot_lock_67_modified { 1394 // Modified: attributes on definitions moved to declarations 1395 // Test annotations on out-of-line definitions of member functions where the 1396 // annotations refer to locks that are also data members in the class. 1397 Mutex mu; 1398 Mutex mu3; 1399 1400 class Foo { 1401 public: 1402 int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3); 1403 int data GUARDED_BY(mu1); 1404 Mutex *mu1; 1405 Mutex *mu2; 1406 }; 1407 1408 int Foo::method1(int i) { 1409 return data + i; 1410 } 1411 1412 void main() 1413 { 1414 Foo a; 1415 a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \ 1416 // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \ 1417 // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \ 1418 // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}} 1419 } 1420 } // end namespace thread_annot_lock_67_modified 1421 1422 1423 namespace substitution_test { 1424 class MyData { 1425 public: 1426 Mutex mu; 1427 1428 void lockData() __attribute__((exclusive_lock_function(mu))) { } 1429 void unlockData() __attribute__((unlock_function(mu))) { } 1430 1431 void doSomething() __attribute__((exclusive_locks_required(mu))) { } 1432 }; 1433 1434 1435 class DataLocker { 1436 public: 1437 void lockData (MyData *d) __attribute__((exclusive_lock_function(d->mu))) { } 1438 void unlockData(MyData *d) __attribute__((unlock_function(d->mu))) { } 1439 }; 1440 1441 1442 class Foo { 1443 public: 1444 void foo(MyData* d) __attribute__((exclusive_locks_required(d->mu))) { } 1445 1446 void bar1(MyData* d) { 1447 d->lockData(); 1448 foo(d); 1449 d->unlockData(); 1450 } 1451 1452 void bar2(MyData* d) { 1453 DataLocker dlr; 1454 dlr.lockData(d); 1455 foo(d); 1456 dlr.unlockData(d); 1457 } 1458 1459 void bar3(MyData* d1, MyData* d2) { 1460 DataLocker dlr; 1461 dlr.lockData(d1); // \ 1462 // expected-warning {{mutex 'mu' is still locked at the end of function}} 1463 dlr.unlockData(d2); // \ 1464 // expected-warning {{unlocking 'mu' that was not locked}} 1465 } 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