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 ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__))) 14 #define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__))) 15 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) 16 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) 17 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) 18 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 19 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 20 #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 21 __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 22 #define SHARED_LOCKS_REQUIRED(...) \ 23 __attribute__ ((shared_locks_required(__VA_ARGS__))) 24 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 25 26 27 class LOCKABLE Mutex { 28 public: 29 void Lock() EXCLUSIVE_LOCK_FUNCTION(); 30 void ReaderLock() SHARED_LOCK_FUNCTION(); 31 void Unlock() UNLOCK_FUNCTION(); 32 33 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); 34 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); 35 36 void AssertHeld() ASSERT_EXCLUSIVE_LOCK(); 37 void AssertReaderHeld() ASSERT_SHARED_LOCK(); 38 }; 39 40 class UnlockableMu{ 41 }; 42 43 class MuWrapper { 44 public: 45 Mutex mu; 46 Mutex getMu() { 47 return mu; 48 } 49 Mutex * getMuPointer() { 50 return μ 51 } 52 }; 53 54 55 class MuDoubleWrapper { 56 public: 57 MuWrapper* muWrapper; 58 MuWrapper* getWrapper() { 59 return muWrapper; 60 } 61 }; 62 63 Mutex mu1; 64 UnlockableMu umu; 65 Mutex mu2; 66 MuWrapper muWrapper; 67 MuDoubleWrapper muDoubleWrapper; 68 Mutex* muPointer; 69 Mutex** muDoublePointer = & muPointer; 70 Mutex& muRef = mu1; 71 72 //---------------------------------------// 73 // Scoping tests 74 //--------------------------------------// 75 76 class Foo { 77 Mutex foomu; 78 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu); 79 }; 80 81 class Foo2 { 82 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu); 83 Mutex foomu; 84 }; 85 86 class Bar { 87 Mutex barmu; 88 Mutex barmu2 ACQUIRED_AFTER(barmu); 89 }; 90 91 92 //-----------------------------------------// 93 // No Thread Safety Analysis (noanal) // 94 //-----------------------------------------// 95 96 // FIXME: Right now we cannot parse attributes put on function definitions 97 // We would like to patch this at some point. 98 99 #if !__has_attribute(no_thread_safety_analysis) 100 #error "Should support no_thread_safety_analysis attribute" 101 #endif 102 103 void noanal_fun() NO_THREAD_SAFETY_ANALYSIS; 104 105 void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \ 106 // expected-error {{'no_thread_safety_analysis' attribute takes no arguments}} 107 108 int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS; 109 110 int noanal_testfn(int y) { 111 int x NO_THREAD_SAFETY_ANALYSIS = y; // \ 112 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 113 return x; 114 }; 115 116 int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \ 117 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 118 119 class NoanalFoo { 120 private: 121 int test_field NO_THREAD_SAFETY_ANALYSIS; // \ 122 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 123 void test_method() NO_THREAD_SAFETY_ANALYSIS; 124 }; 125 126 class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \ 127 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 128 }; 129 130 void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \ 131 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 132 133 134 //-----------------------------------------// 135 // Guarded Var Attribute (gv) 136 //-----------------------------------------// 137 138 #if !__has_attribute(guarded_var) 139 #error "Should support guarded_var attribute" 140 #endif 141 142 int gv_var_noargs GUARDED_VAR; 143 144 int gv_var_args __attribute__((guarded_var(1))); // \ 145 // expected-error {{'guarded_var' attribute takes no arguments}} 146 147 class GVFoo { 148 private: 149 int gv_field_noargs GUARDED_VAR; 150 int gv_field_args __attribute__((guarded_var(1))); // \ 151 // expected-error {{'guarded_var' attribute takes no arguments}} 152 }; 153 154 class GUARDED_VAR GV { // \ 155 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 156 }; 157 158 void gv_function() GUARDED_VAR; // \ 159 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 160 161 void gv_function_params(int gv_lvar GUARDED_VAR); // \ 162 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 163 164 int gv_testfn(int y){ 165 int x GUARDED_VAR = y; // \ 166 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 167 return x; 168 } 169 170 //-----------------------------------------// 171 // Pt Guarded Var Attribute (pgv) 172 //-----------------------------------------// 173 174 //FIXME: add support for boost::scoped_ptr<int> fancyptr and references 175 176 #if !__has_attribute(pt_guarded_var) 177 #error "Should support pt_guarded_var attribute" 178 #endif 179 180 int *pgv_pt_var_noargs PT_GUARDED_VAR; 181 182 int pgv_var_noargs PT_GUARDED_VAR; // \ 183 // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}} 184 185 class PGVFoo { 186 private: 187 int *pt_field_noargs PT_GUARDED_VAR; 188 int field_noargs PT_GUARDED_VAR; // \ 189 // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}} 190 int *gv_field_args __attribute__((pt_guarded_var(1))); // \ 191 // expected-error {{'pt_guarded_var' attribute takes no arguments}} 192 }; 193 194 class PT_GUARDED_VAR PGV { // \ 195 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 196 }; 197 198 int *pgv_var_args __attribute__((pt_guarded_var(1))); // \ 199 // expected-error {{'pt_guarded_var' attribute takes no arguments}} 200 201 202 void pgv_function() PT_GUARDED_VAR; // \ 203 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 204 205 void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \ 206 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 207 208 void pgv_testfn(int y){ 209 int *x PT_GUARDED_VAR = new int(0); // \ 210 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 211 delete x; 212 } 213 214 //-----------------------------------------// 215 // Lockable Attribute (l) 216 //-----------------------------------------// 217 218 //FIXME: In future we may want to add support for structs, ObjC classes, etc. 219 220 #if !__has_attribute(lockable) 221 #error "Should support lockable attribute" 222 #endif 223 224 class LOCKABLE LTestClass { 225 }; 226 227 class __attribute__((lockable (1))) LTestClass_args { // \ 228 // expected-error {{'lockable' attribute takes no arguments}} 229 }; 230 231 void l_test_function() LOCKABLE; // \ 232 // expected-warning {{'lockable' attribute only applies to classes}} 233 234 int l_testfn(int y) { 235 int x LOCKABLE = y; // \ 236 // expected-warning {{'lockable' attribute only applies to classes}} 237 return x; 238 } 239 240 int l_test_var LOCKABLE; // \ 241 // expected-warning {{'lockable' attribute only applies to classes}} 242 243 class LFoo { 244 private: 245 int test_field LOCKABLE; // \ 246 // expected-warning {{'lockable' attribute only applies to classes}} 247 void test_method() LOCKABLE; // \ 248 // expected-warning {{'lockable' attribute only applies to classes}} 249 }; 250 251 252 void l_function_params(int lvar LOCKABLE); // \ 253 // expected-warning {{'lockable' attribute only applies to classes}} 254 255 256 //-----------------------------------------// 257 // Scoped Lockable Attribute (sl) 258 //-----------------------------------------// 259 260 #if !__has_attribute(scoped_lockable) 261 #error "Should support scoped_lockable attribute" 262 #endif 263 264 class SCOPED_LOCKABLE SLTestClass { 265 }; 266 267 class __attribute__((scoped_lockable (1))) SLTestClass_args { // \ 268 // expected-error {{'scoped_lockable' attribute takes no arguments}} 269 }; 270 271 void sl_test_function() SCOPED_LOCKABLE; // \ 272 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 273 274 int sl_testfn(int y) { 275 int x SCOPED_LOCKABLE = y; // \ 276 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 277 return x; 278 } 279 280 int sl_test_var SCOPED_LOCKABLE; // \ 281 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 282 283 class SLFoo { 284 private: 285 int test_field SCOPED_LOCKABLE; // \ 286 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 287 void test_method() SCOPED_LOCKABLE; // \ 288 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 289 }; 290 291 292 void sl_function_params(int lvar SCOPED_LOCKABLE); // \ 293 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 294 295 296 //-----------------------------------------// 297 // Guarded By Attribute (gb) 298 //-----------------------------------------// 299 300 // FIXME: Eventually, would we like this attribute to take more than 1 arg? 301 302 #if !__has_attribute(guarded_by) 303 #error "Should support guarded_by attribute" 304 #endif 305 306 //1. Check applied to the right types & argument number 307 308 int gb_var_arg GUARDED_BY(mu1); 309 310 int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \ 311 // expected-error {{'guarded_by' attribute takes one argument}} 312 313 int gb_var_noargs __attribute__((guarded_by)); // \ 314 // expected-error {{'guarded_by' attribute takes one argument}} 315 316 class GBFoo { 317 private: 318 int gb_field_noargs __attribute__((guarded_by)); // \ 319 // expected-error {{'guarded_by' attribute takes one argument}} 320 int gb_field_args GUARDED_BY(mu1); 321 }; 322 323 class GUARDED_BY(mu1) GB { // \ 324 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 325 }; 326 327 void gb_function() GUARDED_BY(mu1); // \ 328 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 329 330 void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \ 331 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 332 333 int gb_testfn(int y){ 334 int x GUARDED_BY(mu1) = y; // \ 335 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 336 return x; 337 } 338 339 //2. Check argument parsing. 340 341 // legal attribute arguments 342 int gb_var_arg_1 GUARDED_BY(muWrapper.mu); 343 int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu); 344 int gb_var_arg_3 GUARDED_BY(muWrapper.getMu()); 345 int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer()); 346 int gb_var_arg_5 GUARDED_BY(&mu1); 347 int gb_var_arg_6 GUARDED_BY(muRef); 348 int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu()); 349 int gb_var_arg_8 GUARDED_BY(muPointer); 350 351 352 // illegal attribute arguments 353 int gb_var_arg_bad_1 GUARDED_BY(1); // \ 354 // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}} 355 int gb_var_arg_bad_2 GUARDED_BY("mu"); // \ 356 // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}} 357 int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \ 358 // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}} 359 int gb_var_arg_bad_4 GUARDED_BY(umu); // \ 360 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}} 361 362 //3. 363 // Thread Safety analysis tests 364 365 366 //-----------------------------------------// 367 // Pt Guarded By Attribute (pgb) 368 //-----------------------------------------// 369 370 #if !__has_attribute(pt_guarded_by) 371 #error "Should support pt_guarded_by attribute" 372 #endif 373 374 //1. Check applied to the right types & argument number 375 376 int *pgb_var_noargs __attribute__((pt_guarded_by)); // \ 377 // expected-error {{'pt_guarded_by' attribute takes one argument}} 378 379 int *pgb_ptr_var_arg PT_GUARDED_BY(mu1); 380 381 int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \ 382 // expected-error {{'pt_guarded_by' attribute takes one argument}} 383 384 int pgb_var_args PT_GUARDED_BY(mu1); // \ 385 // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}} 386 387 class PGBFoo { 388 private: 389 int *pgb_field_noargs __attribute__((pt_guarded_by)); // \ 390 // expected-error {{'pt_guarded_by' attribute takes one argument}} 391 int *pgb_field_args PT_GUARDED_BY(mu1); 392 }; 393 394 class PT_GUARDED_BY(mu1) PGB { // \ 395 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 396 }; 397 398 void pgb_function() PT_GUARDED_BY(mu1); // \ 399 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 400 401 void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \ 402 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 403 404 void pgb_testfn(int y){ 405 int *x PT_GUARDED_BY(mu1) = new int(0); // \ 406 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 407 delete x; 408 } 409 410 //2. Check argument parsing. 411 412 // legal attribute arguments 413 int * pgb_var_arg_1 PT_GUARDED_BY(muWrapper.mu); 414 int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu); 415 int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu()); 416 int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer()); 417 int * pgb_var_arg_5 PT_GUARDED_BY(&mu1); 418 int * pgb_var_arg_6 PT_GUARDED_BY(muRef); 419 int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu()); 420 int * pgb_var_arg_8 PT_GUARDED_BY(muPointer); 421 422 423 // illegal attribute arguments 424 int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \ 425 // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}} 426 int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \ 427 // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}} 428 int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \ 429 // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}} 430 int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \ 431 // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}} 432 433 434 //-----------------------------------------// 435 // Acquired After (aa) 436 //-----------------------------------------// 437 438 // FIXME: Would we like this attribute to take more than 1 arg? 439 440 #if !__has_attribute(acquired_after) 441 #error "Should support acquired_after attribute" 442 #endif 443 444 Mutex mu_aa ACQUIRED_AFTER(mu1); 445 446 Mutex aa_var_noargs __attribute__((acquired_after)); // \ 447 // expected-error {{attribute takes at least 1 argument}} 448 449 class AAFoo { 450 private: 451 Mutex aa_field_noargs __attribute__((acquired_after)); // \ 452 // expected-error {{attribute takes at least 1 argument}} 453 Mutex aa_field_args ACQUIRED_AFTER(mu1); 454 }; 455 456 class ACQUIRED_AFTER(mu1) AA { // \ 457 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 458 }; 459 460 void aa_function() ACQUIRED_AFTER(mu1); // \ 461 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 462 463 void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \ 464 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 465 466 void aa_testfn(int y){ 467 Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \ 468 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 469 } 470 471 //Check argument parsing. 472 473 // legal attribute arguments 474 Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu); 475 Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu); 476 Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu()); 477 Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer()); 478 Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1); 479 Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef); 480 Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu()); 481 Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer); 482 483 484 // illegal attribute arguments 485 Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \ 486 // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}} 487 Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \ 488 // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}} 489 Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \ 490 // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}} 491 Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \ 492 // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}} 493 UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \ 494 // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}} 495 496 //-----------------------------------------// 497 // Acquired Before (ab) 498 //-----------------------------------------// 499 500 #if !__has_attribute(acquired_before) 501 #error "Should support acquired_before attribute" 502 #endif 503 504 Mutex mu_ab ACQUIRED_BEFORE(mu1); 505 506 Mutex ab_var_noargs __attribute__((acquired_before)); // \ 507 // expected-error {{attribute takes at least 1 argument}} 508 509 class ABFoo { 510 private: 511 Mutex ab_field_noargs __attribute__((acquired_before)); // \ 512 // expected-error {{attribute takes at least 1 argument}} 513 Mutex ab_field_args ACQUIRED_BEFORE(mu1); 514 }; 515 516 class ACQUIRED_BEFORE(mu1) AB { // \ 517 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 518 }; 519 520 void ab_function() ACQUIRED_BEFORE(mu1); // \ 521 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 522 523 void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \ 524 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 525 526 void ab_testfn(int y){ 527 Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \ 528 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 529 } 530 531 // Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will 532 // be taken care of by warnings that ab__int is not lockable. 533 534 //Check argument parsing. 535 536 // legal attribute arguments 537 Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu); 538 Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu); 539 Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu()); 540 Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer()); 541 Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1); 542 Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef); 543 Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu()); 544 Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer); 545 546 547 // illegal attribute arguments 548 Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \ 549 // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}} 550 Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \ 551 // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}} 552 Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \ 553 // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}} 554 Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \ 555 // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}} 556 UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \ 557 // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}} 558 559 560 //-----------------------------------------// 561 // Exclusive Lock Function (elf) 562 //-----------------------------------------// 563 564 #if !__has_attribute(exclusive_lock_function) 565 #error "Should support exclusive_lock_function attribute" 566 #endif 567 568 // takes zero or more arguments, all locks (vars/fields) 569 570 void elf_function() EXCLUSIVE_LOCK_FUNCTION(); 571 572 void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2); 573 574 int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION(); 575 576 int elf_testfn(int y) { 577 int x EXCLUSIVE_LOCK_FUNCTION() = y; // \ 578 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 579 return x; 580 }; 581 582 int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \ 583 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 584 585 class ElfFoo { 586 private: 587 int test_field EXCLUSIVE_LOCK_FUNCTION(); // \ 588 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 589 void test_method() EXCLUSIVE_LOCK_FUNCTION(); 590 }; 591 592 class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \ 593 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 594 }; 595 596 void elf_fun_params(int lvar EXCLUSIVE_LOCK_FUNCTION()); // \ 597 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 598 599 // Check argument parsing. 600 601 // legal attribute arguments 602 int elf_function_1() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu); 603 int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 604 int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu()); 605 int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer()); 606 int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1); 607 int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef); 608 int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 609 int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer); 610 int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1); 611 int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2); 612 613 614 // illegal attribute arguments 615 int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \ 616 // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}} 617 int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \ 618 // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}} 619 int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \ 620 // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 621 622 int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \ 623 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 624 int elf_function_bad_5(Mutex x) EXCLUSIVE_LOCK_FUNCTION(0); // \ 625 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}} 626 int elf_function_bad_6(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(0); // \ 627 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}} 628 int elf_function_bad_7() EXCLUSIVE_LOCK_FUNCTION(0); // \ 629 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 630 631 632 //-----------------------------------------// 633 // Shared Lock Function (slf) 634 //-----------------------------------------// 635 636 #if !__has_attribute(shared_lock_function) 637 #error "Should support shared_lock_function attribute" 638 #endif 639 640 // takes zero or more arguments, all locks (vars/fields) 641 642 void slf_function() SHARED_LOCK_FUNCTION(); 643 644 void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2); 645 646 int slf_testfn(int y) SHARED_LOCK_FUNCTION(); 647 648 int slf_testfn(int y) { 649 int x SHARED_LOCK_FUNCTION() = y; // \ 650 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 651 return x; 652 }; 653 654 int slf_test_var SHARED_LOCK_FUNCTION(); // \ 655 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 656 657 void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \ 658 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 659 660 class SlfFoo { 661 private: 662 int test_field SHARED_LOCK_FUNCTION(); // \ 663 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 664 void test_method() SHARED_LOCK_FUNCTION(); 665 }; 666 667 class SHARED_LOCK_FUNCTION() SlfTestClass { // \ 668 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 669 }; 670 671 // Check argument parsing. 672 673 // legal attribute arguments 674 int slf_function_1() SHARED_LOCK_FUNCTION(muWrapper.mu); 675 int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 676 int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu()); 677 int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer()); 678 int slf_function_5() SHARED_LOCK_FUNCTION(&mu1); 679 int slf_function_6() SHARED_LOCK_FUNCTION(muRef); 680 int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 681 int slf_function_8() SHARED_LOCK_FUNCTION(muPointer); 682 int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1); 683 int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2); 684 685 686 // illegal attribute arguments 687 int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \ 688 // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}} 689 int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \ 690 // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}} 691 int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \ 692 // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 693 694 int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \ 695 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 696 int slf_function_bad_5(Mutex x) SHARED_LOCK_FUNCTION(0); // \ 697 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}} 698 int slf_function_bad_6(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(0); // \ 699 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}} 700 int slf_function_bad_7() SHARED_LOCK_FUNCTION(0); // \ 701 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 702 703 704 //-----------------------------------------// 705 // Exclusive TryLock Function (etf) 706 //-----------------------------------------// 707 708 #if !__has_attribute(exclusive_trylock_function) 709 #error "Should support exclusive_trylock_function attribute" 710 #endif 711 712 // takes a mandatory boolean or integer argument specifying the retval 713 // plus an optional list of locks (vars/fields) 714 715 void etf_function() __attribute__((exclusive_trylock_function)); // \ 716 // expected-error {{attribute takes at least 1 argument}} 717 718 void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2); 719 720 void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1); 721 722 int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1); 723 724 int etf_testfn(int y) { 725 int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \ 726 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 727 return x; 728 }; 729 730 int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ 731 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 732 733 class EtfFoo { 734 private: 735 int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ 736 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 737 void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1); 738 }; 739 740 class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \ 741 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 742 }; 743 744 void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \ 745 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 746 747 // Check argument parsing. 748 749 // legal attribute arguments 750 int etf_function_1() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu); 751 int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu); 752 int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu()); 753 int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer()); 754 int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1); 755 int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef); 756 int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu()); 757 int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer); 758 int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true); 759 760 761 // illegal attribute arguments 762 int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \ 763 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}} 764 int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \ 765 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}} 766 int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \ 767 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}} 768 769 int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \ 770 // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}} 771 int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \ 772 // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}} 773 int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \ 774 // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 775 776 777 //-----------------------------------------// 778 // Shared TryLock Function (stf) 779 //-----------------------------------------// 780 781 #if !__has_attribute(shared_trylock_function) 782 #error "Should support shared_trylock_function attribute" 783 #endif 784 785 // takes a mandatory boolean or integer argument specifying the retval 786 // plus an optional list of locks (vars/fields) 787 788 void stf_function() __attribute__((shared_trylock_function)); // \ 789 // expected-error {{attribute takes at least 1 argument}} 790 791 void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2); 792 793 void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1); 794 795 int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1); 796 797 int stf_testfn(int y) { 798 int x SHARED_TRYLOCK_FUNCTION(1) = y; // \ 799 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 800 return x; 801 }; 802 803 int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \ 804 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 805 806 void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \ 807 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 808 809 810 class StfFoo { 811 private: 812 int test_field SHARED_TRYLOCK_FUNCTION(1); // \ 813 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 814 void test_method() SHARED_TRYLOCK_FUNCTION(1); 815 }; 816 817 class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \ 818 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 819 }; 820 821 // Check argument parsing. 822 823 // legal attribute arguments 824 int stf_function_1() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu); 825 int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu); 826 int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu()); 827 int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer()); 828 int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1); 829 int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef); 830 int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu()); 831 int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer); 832 int stf_function_9() SHARED_TRYLOCK_FUNCTION(true); 833 834 835 // illegal attribute arguments 836 int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \ 837 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}} 838 int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \ 839 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}} 840 int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \ 841 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}} 842 843 int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \ 844 // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}} 845 int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \ 846 // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}} 847 int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \ 848 // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 849 850 851 //-----------------------------------------// 852 // Unlock Function (uf) 853 //-----------------------------------------// 854 855 #if !__has_attribute(unlock_function) 856 #error "Should support unlock_function attribute" 857 #endif 858 859 // takes zero or more arguments, all locks (vars/fields) 860 861 void uf_function() UNLOCK_FUNCTION(); 862 863 void uf_function_args() UNLOCK_FUNCTION(mu1, mu2); 864 865 int uf_testfn(int y) UNLOCK_FUNCTION(); 866 867 int uf_testfn(int y) { 868 int x UNLOCK_FUNCTION() = y; // \ 869 // expected-warning {{'unlock_function' attribute only applies to functions and methods}} 870 return x; 871 }; 872 873 int uf_test_var UNLOCK_FUNCTION(); // \ 874 // expected-warning {{'unlock_function' attribute only applies to functions and methods}} 875 876 class UfFoo { 877 private: 878 int test_field UNLOCK_FUNCTION(); // \ 879 // expected-warning {{'unlock_function' attribute only applies to functions and methods}} 880 void test_method() UNLOCK_FUNCTION(); 881 }; 882 883 class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \ 884 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 885 }; 886 887 void uf_fun_params(int lvar UNLOCK_FUNCTION()); // \ 888 // expected-warning {{'unlock_function' attribute only applies to functions and methods}} 889 890 // Check argument parsing. 891 892 // legal attribute arguments 893 int uf_function_1() UNLOCK_FUNCTION(muWrapper.mu); 894 int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 895 int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu()); 896 int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer()); 897 int uf_function_5() UNLOCK_FUNCTION(&mu1); 898 int uf_function_6() UNLOCK_FUNCTION(muRef); 899 int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 900 int uf_function_8() UNLOCK_FUNCTION(muPointer); 901 int uf_function_9(Mutex x) UNLOCK_FUNCTION(1); 902 int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2); 903 904 905 // illegal attribute arguments 906 int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \ 907 // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}} 908 int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \ 909 // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}} 910 int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \ 911 // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 912 913 int uf_function_bad_1() UNLOCK_FUNCTION(1); // \ 914 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 915 int uf_function_bad_5(Mutex x) UNLOCK_FUNCTION(0); // \ 916 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}} 917 int uf_function_bad_6(Mutex x, Mutex y) UNLOCK_FUNCTION(0); // \ 918 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}} 919 int uf_function_bad_7() UNLOCK_FUNCTION(0); // \ 920 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 921 922 923 //-----------------------------------------// 924 // Lock Returned (lr) 925 //-----------------------------------------// 926 927 #if !__has_attribute(lock_returned) 928 #error "Should support lock_returned attribute" 929 #endif 930 931 // Takes exactly one argument, a var/field 932 933 void lr_function() __attribute__((lock_returned)); // \ 934 // expected-error {{'lock_returned' attribute takes one argument}} 935 936 void lr_function_arg() LOCK_RETURNED(mu1); 937 938 void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \ 939 // expected-error {{'lock_returned' attribute takes one argument}} 940 941 int lr_testfn(int y) LOCK_RETURNED(mu1); 942 943 int lr_testfn(int y) { 944 int x LOCK_RETURNED(mu1) = y; // \ 945 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 946 return x; 947 }; 948 949 int lr_test_var LOCK_RETURNED(mu1); // \ 950 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 951 952 void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \ 953 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 954 955 class LrFoo { 956 private: 957 int test_field LOCK_RETURNED(mu1); // \ 958 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 959 void test_method() LOCK_RETURNED(mu1); 960 }; 961 962 class LOCK_RETURNED(mu1) LrTestClass { // \ 963 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 964 }; 965 966 // Check argument parsing. 967 968 // legal attribute arguments 969 int lr_function_1() LOCK_RETURNED(muWrapper.mu); 970 int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu); 971 int lr_function_3() LOCK_RETURNED(muWrapper.getMu()); 972 int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer()); 973 int lr_function_5() LOCK_RETURNED(&mu1); 974 int lr_function_6() LOCK_RETURNED(muRef); 975 int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu()); 976 int lr_function_8() LOCK_RETURNED(muPointer); 977 978 979 // illegal attribute arguments 980 int lr_function_bad_1() LOCK_RETURNED(1); // \ 981 // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}} 982 int lr_function_bad_2() LOCK_RETURNED("mu"); // \ 983 // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}} 984 int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \ 985 // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}} 986 int lr_function_bad_4() LOCK_RETURNED(umu); // \ 987 // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}} 988 989 990 991 //-----------------------------------------// 992 // Locks Excluded (le) 993 //-----------------------------------------// 994 995 #if !__has_attribute(locks_excluded) 996 #error "Should support locks_excluded attribute" 997 #endif 998 999 // takes one or more arguments, all locks (vars/fields) 1000 1001 void le_function() __attribute__((locks_excluded)); // \ 1002 // expected-error {{attribute takes at least 1 argument}} 1003 1004 void le_function_arg() LOCKS_EXCLUDED(mu1); 1005 1006 void le_function_args() LOCKS_EXCLUDED(mu1, mu2); 1007 1008 int le_testfn(int y) LOCKS_EXCLUDED(mu1); 1009 1010 int le_testfn(int y) { 1011 int x LOCKS_EXCLUDED(mu1) = y; // \ 1012 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1013 return x; 1014 }; 1015 1016 int le_test_var LOCKS_EXCLUDED(mu1); // \ 1017 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1018 1019 void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \ 1020 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1021 1022 class LeFoo { 1023 private: 1024 int test_field LOCKS_EXCLUDED(mu1); // \ 1025 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1026 void test_method() LOCKS_EXCLUDED(mu1); 1027 }; 1028 1029 class LOCKS_EXCLUDED(mu1) LeTestClass { // \ 1030 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1031 }; 1032 1033 // Check argument parsing. 1034 1035 // legal attribute arguments 1036 int le_function_1() LOCKS_EXCLUDED(muWrapper.mu); 1037 int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu); 1038 int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu()); 1039 int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer()); 1040 int le_function_5() LOCKS_EXCLUDED(&mu1); 1041 int le_function_6() LOCKS_EXCLUDED(muRef); 1042 int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu()); 1043 int le_function_8() LOCKS_EXCLUDED(muPointer); 1044 1045 1046 // illegal attribute arguments 1047 int le_function_bad_1() LOCKS_EXCLUDED(1); // \ 1048 // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}} 1049 int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \ 1050 // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}} 1051 int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \ 1052 // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}} 1053 int le_function_bad_4() LOCKS_EXCLUDED(umu); // \ 1054 // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}} 1055 1056 1057 1058 //-----------------------------------------// 1059 // Exclusive Locks Required (elr) 1060 //-----------------------------------------// 1061 1062 #if !__has_attribute(exclusive_locks_required) 1063 #error "Should support exclusive_locks_required attribute" 1064 #endif 1065 1066 // takes one or more arguments, all locks (vars/fields) 1067 1068 void elr_function() __attribute__((exclusive_locks_required)); // \ 1069 // expected-error {{attribute takes at least 1 argument}} 1070 1071 void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1); 1072 1073 void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2); 1074 1075 int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1); 1076 1077 int elr_testfn(int y) { 1078 int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \ 1079 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1080 return x; 1081 }; 1082 1083 int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \ 1084 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1085 1086 void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \ 1087 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1088 1089 class ElrFoo { 1090 private: 1091 int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \ 1092 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1093 void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1); 1094 }; 1095 1096 class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \ 1097 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1098 }; 1099 1100 // Check argument parsing. 1101 1102 // legal attribute arguments 1103 int elr_function_1() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu); 1104 int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu); 1105 int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu()); 1106 int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer()); 1107 int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1); 1108 int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef); 1109 int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu()); 1110 int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer); 1111 1112 1113 // illegal attribute arguments 1114 int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \ 1115 // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}} 1116 int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \ 1117 // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}} 1118 int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \ 1119 // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}} 1120 int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \ 1121 // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}} 1122 1123 1124 1125 1126 //-----------------------------------------// 1127 // Shared Locks Required (slr) 1128 //-----------------------------------------// 1129 1130 #if !__has_attribute(shared_locks_required) 1131 #error "Should support shared_locks_required attribute" 1132 #endif 1133 1134 // takes one or more arguments, all locks (vars/fields) 1135 1136 void slr_function() __attribute__((shared_locks_required)); // \ 1137 // expected-error {{attribute takes at least 1 argument}} 1138 1139 void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1); 1140 1141 void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2); 1142 1143 int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1); 1144 1145 int slr_testfn(int y) { 1146 int x SHARED_LOCKS_REQUIRED(mu1) = y; // \ 1147 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1148 return x; 1149 }; 1150 1151 int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \ 1152 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1153 1154 void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \ 1155 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1156 1157 class SlrFoo { 1158 private: 1159 int test_field SHARED_LOCKS_REQUIRED(mu1); // \ 1160 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1161 void test_method() SHARED_LOCKS_REQUIRED(mu1); 1162 }; 1163 1164 class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \ 1165 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1166 }; 1167 1168 // Check argument parsing. 1169 1170 // legal attribute arguments 1171 int slr_function_1() SHARED_LOCKS_REQUIRED(muWrapper.mu); 1172 int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu); 1173 int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu()); 1174 int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer()); 1175 int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1); 1176 int slr_function_6() SHARED_LOCKS_REQUIRED(muRef); 1177 int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu()); 1178 int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer); 1179 1180 1181 // illegal attribute arguments 1182 int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \ 1183 // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}} 1184 int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \ 1185 // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}} 1186 int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \ 1187 // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}} 1188 int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \ 1189 // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}} 1190 1191 1192 //-----------------------------------------// 1193 // Regression tests for unusual cases. 1194 //-----------------------------------------// 1195 1196 int trivially_false_edges(bool b) { 1197 // Create NULL (never taken) edges in CFG 1198 if (false) return 1; 1199 else return 2; 1200 } 1201 1202 // Possible Clang bug -- method pointer in template parameter 1203 class UnFoo { 1204 public: 1205 void foo(); 1206 }; 1207 1208 template<void (UnFoo::*methptr)()> 1209 class MCaller { 1210 public: 1211 static void call_method_ptr(UnFoo *f) { 1212 // FIXME: Possible Clang bug: 1213 // getCalleeDecl() returns NULL in the following case: 1214 (f->*methptr)(); 1215 } 1216 }; 1217 1218 void call_method_ptr_inst(UnFoo* f) { 1219 MCaller<&UnFoo::foo>::call_method_ptr(f); 1220 } 1221 1222 int temp; 1223 void empty_back_edge() { 1224 // Create a back edge to a block with with no statements 1225 for (;;) { 1226 ++temp; 1227 if (temp > 10) break; 1228 } 1229 } 1230 1231 struct Foomger { 1232 void operator++(); 1233 }; 1234 1235 struct Foomgoper { 1236 Foomger f; 1237 1238 bool done(); 1239 void invalid_back_edge() { 1240 do { 1241 // FIXME: Possible Clang bug: 1242 // The first statement in this basic block has no source location 1243 ++f; 1244 } while (!done()); 1245 } 1246 }; 1247 1248 1249 //----------------------------------------------------- 1250 // Parsing of member variables and function parameters 1251 //------------------------------------------------------ 1252 1253 Mutex gmu; 1254 1255 class StaticMu { 1256 static Mutex statmu; 1257 }; 1258 1259 class FooLate { 1260 public: 1261 void foo1() EXCLUSIVE_LOCKS_REQUIRED(gmu) { } 1262 void foo2() EXCLUSIVE_LOCKS_REQUIRED(mu) { } 1263 void foo3(Mutex *m) EXCLUSIVE_LOCKS_REQUIRED(m) { } 1264 void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { } 1265 void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu); 1266 1267 static void foo5() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ 1268 // expected-error {{invalid use of member 'mu' in static member function}} 1269 1270 template <class T> 1271 void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { } 1272 1273 template <class T> 1274 void foo7(T* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { } 1275 1276 int a GUARDED_BY(gmu); 1277 int b GUARDED_BY(mu); 1278 int c GUARDED_BY(this->mu); 1279 1280 Mutex mu; 1281 }; 1282 1283 //------------------------- 1284 // Empty argument lists 1285 //------------------------- 1286 1287 class LOCKABLE EmptyArgListsTest { 1288 void lock() EXCLUSIVE_LOCK_FUNCTION() { } 1289 void unlock() UNLOCK_FUNCTION() { } 1290 }; 1291 1292 1293 namespace FunctionDefinitionParseTest { 1294 // Test parsing of attributes on function definitions. 1295 1296 class Foo { 1297 public: 1298 Mutex mu_; 1299 void foo1(); 1300 void foo2(Foo *f); 1301 }; 1302 1303 template <class T> 1304 class Bar { 1305 public: 1306 Mutex mu_; 1307 void bar(); 1308 }; 1309 1310 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 1311 void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { } 1312 1313 template <class T> 1314 void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 1315 1316 void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { } 1317 1318 } // end namespace 1319 1320 1321 namespace TestMultiDecl { 1322 1323 class Foo { 1324 public: 1325 int GUARDED_BY(mu_) a; 1326 int GUARDED_BY(mu_) b, c; 1327 1328 private: 1329 Mutex mu_; 1330 }; 1331 1332 } // end namespace TestMultiDecl 1333 1334 1335 namespace NestedClassLateDecl { 1336 1337 class Foo { 1338 class Bar { 1339 int a GUARDED_BY(mu); 1340 int b GUARDED_BY(fooMuStatic); 1341 1342 void bar() EXCLUSIVE_LOCKS_REQUIRED(mu) { a = 0; } 1343 void bar2(Bar* b) EXCLUSIVE_LOCKS_REQUIRED(b->mu) { b->a = 0; } 1344 void bar3(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->fooMu) { f->a = 0; } 1345 1346 Mutex mu; 1347 }; 1348 1349 int a GUARDED_BY(fooMu); 1350 Mutex fooMu; 1351 static Mutex fooMuStatic; 1352 }; 1353 1354 } 1355 1356 namespace PointerToMemberTest { 1357 1358 // Empty string should be ignored. 1359 int testEmptyAttribute GUARDED_BY(""); 1360 void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED(""); 1361 1362 class Graph { 1363 public: 1364 Mutex mu_; 1365 1366 static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_); 1367 }; 1368 1369 class Node { 1370 public: 1371 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_); 1372 int a GUARDED_BY(&Graph::mu_); 1373 }; 1374 1375 } 1376 1377 1378 namespace SmartPointerTest { 1379 1380 template<class T> 1381 class smart_ptr { 1382 public: 1383 T* operator->() { return ptr_; } 1384 T& operator*() { return ptr_; } 1385 1386 private: 1387 T* ptr_; 1388 }; 1389 1390 1391 Mutex gmu; 1392 smart_ptr<int> gdat PT_GUARDED_BY(gmu); 1393 1394 1395 class MyClass { 1396 public: 1397 Mutex mu_; 1398 smart_ptr<Mutex> smu_; 1399 1400 1401 smart_ptr<int> a PT_GUARDED_BY(mu_); 1402 int b GUARDED_BY(smu_); 1403 }; 1404 1405 } 1406 1407 1408 namespace InheritanceTest { 1409 1410 class LOCKABLE Base { 1411 public: 1412 void lock() EXCLUSIVE_LOCK_FUNCTION(); 1413 void unlock() UNLOCK_FUNCTION(); 1414 }; 1415 1416 class Base2 { }; 1417 1418 class Derived1 : public Base { }; 1419 1420 class Derived2 : public Base2, public Derived1 { }; 1421 1422 class Derived3 : public Base2 { }; 1423 1424 class Foo { 1425 Derived1 mu1_; 1426 Derived2 mu2_; 1427 Derived3 mu3_; 1428 int a GUARDED_BY(mu1_); 1429 int b GUARDED_BY(mu2_); 1430 int c GUARDED_BY(mu3_); // \ 1431 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}} 1432 1433 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) { 1434 a = 0; 1435 b = 0; 1436 } 1437 }; 1438 1439 } 1440 1441 1442 namespace InvalidDeclTest { 1443 1444 class Foo { }; 1445 namespace { 1446 void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \ 1447 // expected-error {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \ 1448 // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}} 1449 } 1450 1451 } // end namespace InvalidDeclTest 1452 1453 1454 namespace StaticScopeTest { 1455 1456 class FooStream; 1457 1458 class Foo { 1459 mutable Mutex mu; 1460 int a GUARDED_BY(mu); 1461 1462 static int si GUARDED_BY(mu); // \ 1463 // expected-error {{invalid use of non-static data member 'mu'}} 1464 1465 static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ 1466 // expected-error {{invalid use of member 'mu' in static member function}} 1467 1468 friend FooStream& operator<<(FooStream& s, const Foo& f) 1469 EXCLUSIVE_LOCKS_REQUIRED(mu); // \ 1470 // expected-error {{invalid use of non-static data member 'mu'}} 1471 }; 1472 1473 1474 } // end namespace StaticScopeTest 1475 1476 1477 namespace FunctionAttributesInsideClass_ICE_Test { 1478 1479 class Foo { 1480 public: 1481 /* Originally found when parsing foo() as an ordinary method after the 1482 * the following: 1483 1484 template <class T> 1485 void syntaxErrorMethod(int i) { 1486 if (i) { 1487 foo( 1488 } 1489 } 1490 */ 1491 1492 void method() { 1493 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ 1494 // expected-error {{use of undeclared identifier 'mu'}} 1495 } 1496 }; 1497 1498 } // end namespace FunctionAttributesInsideClass_ICE_Test 1499 1500