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