1 // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s 2 3 #define LOCKABLE __attribute__ ((lockable)) 4 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) 5 #define GUARDED_BY(x) __attribute__ ((guarded_by(x))) 6 #define GUARDED_VAR __attribute__ ((guarded_var)) 7 #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) 8 #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) 9 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) 10 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) 11 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) 12 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) 13 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) 14 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) 15 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) 16 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 17 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 18 #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 19 __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 20 #define SHARED_LOCKS_REQUIRED(...) \ 21 __attribute__ ((shared_locks_required(__VA_ARGS__))) 22 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 23 24 25 class LOCKABLE Mutex { 26 public: 27 void Lock(); 28 }; 29 30 class UnlockableMu{ 31 }; 32 33 class MuWrapper { 34 public: 35 Mutex mu; 36 Mutex getMu() { 37 return mu; 38 } 39 Mutex * getMuPointer() { 40 return μ 41 } 42 }; 43 44 45 class MuDoubleWrapper { 46 public: 47 MuWrapper* muWrapper; 48 MuWrapper* getWrapper() { 49 return muWrapper; 50 } 51 }; 52 53 Mutex mu1; 54 UnlockableMu umu; 55 Mutex mu2; 56 MuWrapper muWrapper; 57 MuDoubleWrapper muDoubleWrapper; 58 Mutex* muPointer; 59 Mutex** muDoublePointer = & muPointer; 60 Mutex& muRef = mu1; 61 62 //---------------------------------------// 63 // Scoping tests 64 //--------------------------------------// 65 66 class Foo { 67 Mutex foomu; 68 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu); 69 }; 70 71 class Foo2 { 72 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu); 73 Mutex foomu; 74 }; 75 76 class 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 93 void noanal_fun() NO_THREAD_SAFETY_ANALYSIS; 94 95 void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \ 96 // expected-error {{attribute takes no arguments}} 97 98 int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS; 99 100 int 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 106 int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \ 107 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 108 109 class 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 116 class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \ 117 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 118 }; 119 120 void 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 132 int gv_var_noargs GUARDED_VAR; 133 134 int gv_var_args __attribute__((guarded_var(1))); // \ 135 // expected-error {{attribute takes no arguments}} 136 137 class 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 144 class GUARDED_VAR GV { // \ 145 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 146 }; 147 148 void gv_function() GUARDED_VAR; // \ 149 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 150 151 void gv_function_params(int gv_lvar GUARDED_VAR); // \ 152 // expected-warning {{'guarded_var' attribute only applies to fields and global variables}} 153 154 int 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 170 int *pgv_pt_var_noargs PT_GUARDED_VAR; 171 172 int pgv_var_noargs PT_GUARDED_VAR; // \ 173 // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}} 174 175 class 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 184 class PT_GUARDED_VAR PGV { // \ 185 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 186 }; 187 188 int *pgv_var_args __attribute__((pt_guarded_var(1))); // \ 189 // expected-error {{attribute takes no arguments}} 190 191 192 void pgv_function() PT_GUARDED_VAR; // \ 193 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 194 195 void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \ 196 // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}} 197 198 void 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 214 class LOCKABLE LTestClass { 215 }; 216 217 class __attribute__((lockable (1))) LTestClass_args { // \ 218 // expected-error {{attribute takes no arguments}} 219 }; 220 221 void l_test_function() LOCKABLE; // \ 222 // expected-warning {{'lockable' attribute only applies to classes}} 223 224 int l_testfn(int y) { 225 int x LOCKABLE = y; // \ 226 // expected-warning {{'lockable' attribute only applies to classes}} 227 return x; 228 } 229 230 int l_test_var LOCKABLE; // \ 231 // expected-warning {{'lockable' attribute only applies to classes}} 232 233 class 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 242 void 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 254 class SCOPED_LOCKABLE SLTestClass { 255 }; 256 257 class __attribute__((scoped_lockable (1))) SLTestClass_args { // \ 258 // expected-error {{attribute takes no arguments}} 259 }; 260 261 void sl_test_function() SCOPED_LOCKABLE; // \ 262 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 263 264 int 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 270 int sl_test_var SCOPED_LOCKABLE; // \ 271 // expected-warning {{'scoped_lockable' attribute only applies to classes}} 272 273 class 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 282 void 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 298 int gb_var_arg GUARDED_BY(mu1); 299 300 int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \ 301 // expected-error {{attribute takes one argument}} 302 303 int gb_var_noargs __attribute__((guarded_by)); // \ 304 // expected-error {{attribute takes one argument}} 305 306 class 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 313 class GUARDED_BY(mu1) GB { // \ 314 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 315 }; 316 317 void gb_function() GUARDED_BY(mu1); // \ 318 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 319 320 void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \ 321 // expected-warning {{'guarded_by' attribute only applies to fields and global variables}} 322 323 int 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 332 int gb_var_arg_1 GUARDED_BY(muWrapper.mu); 333 int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu); 334 int gb_var_arg_3 GUARDED_BY(muWrapper.getMu()); 335 int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer()); 336 int gb_var_arg_5 GUARDED_BY(&mu1); 337 int gb_var_arg_6 GUARDED_BY(muRef); 338 int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu()); 339 int gb_var_arg_8 GUARDED_BY(muPointer); 340 341 342 // illegal attribute arguments 343 int 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'}} 345 int gb_var_arg_bad_2 GUARDED_BY("mu"); // \ 346 // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}} 347 int 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 **'}} 349 int 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 366 int *pgb_var_noargs __attribute__((pt_guarded_by)); // \ 367 // expected-error {{attribute takes one argument}} 368 369 int *pgb_ptr_var_arg PT_GUARDED_BY(mu1); 370 371 int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \ 372 // expected-error {{attribute takes one argument}} 373 374 int pgb_var_args PT_GUARDED_BY(mu1); // \ 375 // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}} 376 377 class 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 384 class PT_GUARDED_BY(mu1) PGB { // \ 385 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 386 }; 387 388 void pgb_function() PT_GUARDED_BY(mu1); // \ 389 // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} 390 391 void 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 394 void 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 403 int * pgb_var_arg_1 PT_GUARDED_BY(muWrapper.mu); 404 int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu); 405 int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu()); 406 int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer()); 407 int * pgb_var_arg_5 PT_GUARDED_BY(&mu1); 408 int * pgb_var_arg_6 PT_GUARDED_BY(muRef); 409 int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu()); 410 int * pgb_var_arg_8 PT_GUARDED_BY(muPointer); 411 412 413 // illegal attribute arguments 414 int * 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}} 416 int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \ 417 // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}} 418 int * 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}} 420 int * 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 434 Mutex mu_aa ACQUIRED_AFTER(mu1); 435 436 Mutex aa_var_noargs __attribute__((acquired_after)); // \ 437 // expected-error {{attribute takes at least 1 argument}} 438 439 class 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 446 class ACQUIRED_AFTER(mu1) AA { // \ 447 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 448 }; 449 450 void aa_function() ACQUIRED_AFTER(mu1); // \ 451 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 452 453 void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \ 454 // expected-warning {{'acquired_after' attribute only applies to fields and global variables}} 455 456 void 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 464 Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu); 465 Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu); 466 Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu()); 467 Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer()); 468 Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1); 469 Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef); 470 Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu()); 471 Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer); 472 473 474 // illegal attribute arguments 475 Mutex 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}} 477 Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \ 478 // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}} 479 Mutex 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}} 481 Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \ 482 // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}} 483 UnlockableMu 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 494 Mutex mu_ab ACQUIRED_BEFORE(mu1); 495 496 Mutex ab_var_noargs __attribute__((acquired_before)); // \ 497 // expected-error {{attribute takes at least 1 argument}} 498 499 class 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 506 class ACQUIRED_BEFORE(mu1) AB { // \ 507 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 508 }; 509 510 void ab_function() ACQUIRED_BEFORE(mu1); // \ 511 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 512 513 void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \ 514 // expected-warning {{'acquired_before' attribute only applies to fields and global variables}} 515 516 void 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 527 Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu); 528 Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu); 529 Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu()); 530 Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer()); 531 Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1); 532 Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef); 533 Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu()); 534 Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer); 535 536 537 // illegal attribute arguments 538 Mutex 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}} 540 Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \ 541 // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}} 542 Mutex 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}} 544 Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \ 545 // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}} 546 UnlockableMu 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 560 void elf_function() EXCLUSIVE_LOCK_FUNCTION(); 561 562 void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2); 563 564 int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION(); 565 566 int 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 572 int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \ 573 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 574 575 class 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 582 class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \ 583 // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} 584 }; 585 586 void 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 592 int elf_function_1() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu); 593 int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 594 int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu()); 595 int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer()); 596 int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1); 597 int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef); 598 int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 599 int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer); 600 int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1); 601 int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2); 602 603 604 // illegal attribute arguments 605 int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \ 606 // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}} 607 int 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}} 609 int 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 612 int 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}} 614 int 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}} 616 int 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}} 618 int 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 632 void slf_function() SHARED_LOCK_FUNCTION(); 633 634 void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2); 635 636 int slf_testfn(int y) SHARED_LOCK_FUNCTION(); 637 638 int 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 644 int slf_test_var SHARED_LOCK_FUNCTION(); // \ 645 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 646 647 void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \ 648 // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} 649 650 class 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 657 class 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 664 int slf_function_1() SHARED_LOCK_FUNCTION(muWrapper.mu); 665 int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 666 int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu()); 667 int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer()); 668 int slf_function_5() SHARED_LOCK_FUNCTION(&mu1); 669 int slf_function_6() SHARED_LOCK_FUNCTION(muRef); 670 int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 671 int slf_function_8() SHARED_LOCK_FUNCTION(muPointer); 672 int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1); 673 int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2); 674 675 676 // illegal attribute arguments 677 int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \ 678 // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}} 679 int 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}} 681 int 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 684 int 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}} 686 int 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}} 688 int 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}} 690 int 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 705 void etf_function() __attribute__((exclusive_trylock_function)); // \ 706 // expected-error {{attribute takes at least 1 argument}} 707 708 void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2); 709 710 void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1); 711 712 int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1); 713 714 int 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 720 int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \ 721 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 722 723 class 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 730 class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \ 731 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} 732 }; 733 734 void 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 740 int etf_function_1() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu); 741 int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu); 742 int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu()); 743 int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer()); 744 int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1); 745 int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef); 746 int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu()); 747 int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer); 748 int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true); 749 750 751 // illegal attribute arguments 752 int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \ 753 // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}} 754 int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \ 755 // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}} 756 int 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 759 int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \ 760 // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}} 761 int 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}} 763 int 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 778 void stf_function() __attribute__((shared_trylock_function)); // \ 779 // expected-error {{attribute takes at least 1 argument}} 780 781 void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2); 782 783 void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1); 784 785 int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1); 786 787 int 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 793 int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \ 794 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 795 796 void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \ 797 // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} 798 799 800 class 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 807 class 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 814 int stf_function_1() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu); 815 int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu); 816 int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu()); 817 int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer()); 818 int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1); 819 int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef); 820 int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu()); 821 int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer); 822 int stf_function_9() SHARED_TRYLOCK_FUNCTION(true); 823 824 825 // illegal attribute arguments 826 int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \ 827 // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}} 828 int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \ 829 // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}} 830 int 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 833 int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \ 834 // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}} 835 int 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}} 837 int 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 851 void uf_function() UNLOCK_FUNCTION(); 852 853 void uf_function_args() UNLOCK_FUNCTION(mu1, mu2); 854 855 int uf_testfn(int y) UNLOCK_FUNCTION(); 856 857 int 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 863 int uf_test_var UNLOCK_FUNCTION(); // \ 864 // expected-warning {{'unlock_function' attribute only applies to functions and methods}} 865 866 class 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 873 class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \ 874 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} 875 }; 876 877 void 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 883 int uf_function_1() UNLOCK_FUNCTION(muWrapper.mu); 884 int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu); 885 int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu()); 886 int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer()); 887 int uf_function_5() UNLOCK_FUNCTION(&mu1); 888 int uf_function_6() UNLOCK_FUNCTION(muRef); 889 int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu()); 890 int uf_function_8() UNLOCK_FUNCTION(muPointer); 891 int uf_function_9(Mutex x) UNLOCK_FUNCTION(1); 892 int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2); 893 894 895 // illegal attribute arguments 896 int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \ 897 // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}} 898 int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \ 899 // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}} 900 int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \ 901 // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} 902 903 int uf_function_bad_1() UNLOCK_FUNCTION(1); // \ 904 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}} 905 int 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}} 907 int 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}} 909 int 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 923 void lr_function() __attribute__((lock_returned)); // \ 924 // expected-error {{attribute takes one argument}} 925 926 void lr_function_arg() LOCK_RETURNED(mu1); 927 928 void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \ 929 // expected-error {{attribute takes one argument}} 930 931 int lr_testfn(int y) LOCK_RETURNED(mu1); 932 933 int 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 939 int lr_test_var LOCK_RETURNED(mu1); // \ 940 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 941 942 void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \ 943 // expected-warning {{'lock_returned' attribute only applies to functions and methods}} 944 945 class 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 952 class 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 959 int lr_function_1() LOCK_RETURNED(muWrapper.mu); 960 int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu); 961 int lr_function_3() LOCK_RETURNED(muWrapper.getMu()); 962 int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer()); 963 int lr_function_5() LOCK_RETURNED(&mu1); 964 int lr_function_6() LOCK_RETURNED(muRef); 965 int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu()); 966 int lr_function_8() LOCK_RETURNED(muPointer); 967 968 969 // illegal attribute arguments 970 int lr_function_bad_1() LOCK_RETURNED(1); // \ 971 // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}} 972 int lr_function_bad_2() LOCK_RETURNED("mu"); // \ 973 // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}} 974 int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \ 975 // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}} 976 int 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 991 void le_function() __attribute__((locks_excluded)); // \ 992 // expected-error {{attribute takes at least 1 argument}} 993 994 void le_function_arg() LOCKS_EXCLUDED(mu1); 995 996 void le_function_args() LOCKS_EXCLUDED(mu1, mu2); 997 998 int le_testfn(int y) LOCKS_EXCLUDED(mu1); 999 1000 int 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 1006 int le_test_var LOCKS_EXCLUDED(mu1); // \ 1007 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1008 1009 void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \ 1010 // expected-warning {{'locks_excluded' attribute only applies to functions and methods}} 1011 1012 class 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 1019 class 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 1026 int le_function_1() LOCKS_EXCLUDED(muWrapper.mu); 1027 int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu); 1028 int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu()); 1029 int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer()); 1030 int le_function_5() LOCKS_EXCLUDED(&mu1); 1031 int le_function_6() LOCKS_EXCLUDED(muRef); 1032 int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu()); 1033 int le_function_8() LOCKS_EXCLUDED(muPointer); 1034 1035 1036 // illegal attribute arguments 1037 int le_function_bad_1() LOCKS_EXCLUDED(1); // \ 1038 // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}} 1039 int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \ 1040 // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}} 1041 int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \ 1042 // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}} 1043 int 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 1058 void elr_function() __attribute__((exclusive_locks_required)); // \ 1059 // expected-error {{attribute takes at least 1 argument}} 1060 1061 void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1); 1062 1063 void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2); 1064 1065 int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1); 1066 1067 int 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 1073 int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \ 1074 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1075 1076 void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \ 1077 // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} 1078 1079 class 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 1086 class 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 1093 int elr_function_1() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu); 1094 int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu); 1095 int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu()); 1096 int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer()); 1097 int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1); 1098 int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef); 1099 int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu()); 1100 int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer); 1101 1102 1103 // illegal attribute arguments 1104 int 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}} 1106 int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \ 1107 // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}} 1108 int 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}} 1110 int 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 1126 void slr_function() __attribute__((shared_locks_required)); // \ 1127 // expected-error {{attribute takes at least 1 argument}} 1128 1129 void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1); 1130 1131 void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2); 1132 1133 int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1); 1134 1135 int 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 1141 int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \ 1142 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1143 1144 void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \ 1145 // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} 1146 1147 class 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 1154 class 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 1161 int slr_function_1() SHARED_LOCKS_REQUIRED(muWrapper.mu); 1162 int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu); 1163 int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu()); 1164 int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer()); 1165 int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1); 1166 int slr_function_6() SHARED_LOCKS_REQUIRED(muRef); 1167 int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu()); 1168 int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer); 1169 1170 1171 // illegal attribute arguments 1172 int 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}} 1174 int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \ 1175 // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}} 1176 int 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}} 1178 int 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 1186 int 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 1193 class UnFoo { 1194 public: 1195 void foo(); 1196 }; 1197 1198 template<void (UnFoo::*methptr)()> 1199 class MCaller { 1200 public: 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 1208 void call_method_ptr_inst(UnFoo* f) { 1209 MCaller<&UnFoo::foo>::call_method_ptr(f); 1210 } 1211 1212 int temp; 1213 void 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 1221 struct Foomger { 1222 void operator++(); 1223 }; 1224 1225 struct 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 1243 Mutex gmu; 1244 1245 class StaticMu { 1246 static Mutex statmu; 1247 }; 1248 1249 class FooLate { 1250 public: 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 1277 class LOCKABLE EmptyArgListsTest { 1278 void lock() EXCLUSIVE_LOCK_FUNCTION() { } 1279 void unlock() UNLOCK_FUNCTION() { } 1280 }; 1281 1282 1283 namespace FunctionDefinitionParseTest { 1284 // Test parsing of attributes on function definitions. 1285 1286 class Foo { 1287 public: 1288 Mutex mu_; 1289 void foo1(); 1290 void foo2(Foo *f); 1291 }; 1292 1293 template <class T> 1294 class Bar { 1295 public: 1296 Mutex mu_; 1297 void bar(); 1298 }; 1299 1300 void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 1301 void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { } 1302 1303 template <class T> 1304 void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { } 1305 1306 void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { } 1307 1308 } // end namespace 1309 1310 1311 namespace TestMultiDecl { 1312 1313 class Foo { 1314 public: 1315 int GUARDED_BY(mu_) a; 1316 int GUARDED_BY(mu_) b, c; 1317 1318 private: 1319 Mutex mu_; 1320 }; 1321 1322 } // end namespace TestMultiDecl 1323 1324 1325 namespace NestedClassLateDecl { 1326 1327 class 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 1346 namespace PointerToMemberTest { 1347 1348 // Empty string should be ignored. 1349 int testEmptyAttribute GUARDED_BY(""); 1350 void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED(""); 1351 1352 class Graph { 1353 public: 1354 Mutex mu_; 1355 1356 static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_); 1357 }; 1358 1359 class Node { 1360 public: 1361 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_); 1362 int a GUARDED_BY(&Graph::mu_); 1363 }; 1364 1365 } 1366 1367 1368 namespace SmartPointerTest { 1369 1370 template<class T> 1371 class smart_ptr { 1372 public: 1373 T* operator->() { return ptr_; } 1374 T& operator*() { return ptr_; } 1375 1376 private: 1377 T* ptr_; 1378 }; 1379 1380 1381 Mutex gmu; 1382 smart_ptr<int> gdat PT_GUARDED_BY(gmu); 1383 1384 1385 class MyClass { 1386 public: 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 1398 namespace InheritanceTest { 1399 1400 class LOCKABLE Base { 1401 public: 1402 void lock() EXCLUSIVE_LOCK_FUNCTION(); 1403 void unlock() UNLOCK_FUNCTION(); 1404 }; 1405 1406 class Base2 { }; 1407 1408 class Derived1 : public Base { }; 1409 1410 class Derived2 : public Base2, public Derived1 { }; 1411 1412 class Derived3 : public Base2 { }; 1413 1414 class 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 1432 namespace InvalidDeclTest { 1433 1434 class Foo { }; 1435 namespace { 1436 void 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 1444 namespace StaticScopeTest { 1445 1446 class FooStream; 1447 1448 class 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 namespace FunctionAttributesInsideClass_ICE_Test { 1468 1469 class Foo { 1470 public: 1471 /* Originally found when parsing foo() as an ordinary method after the 1472 * the following: 1473 1474 template <class T> 1475 void syntaxErrorMethod(int i) { 1476 if (i) { 1477 foo( 1478 } 1479 } 1480 */ 1481 1482 void method() { 1483 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \ 1484 // expected-error {{use of undeclared identifier 'mu'}} 1485 } 1486 }; 1487 1488 } // end namespace FunctionAttributesInsideClass_ICE_Test 1489 1490