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