1751 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s2// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s4 5#define LOCKABLE __attribute__ ((lockable))6#define REENTRANT_CAPABILITY __attribute__ ((reentrant_capability))7#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))8#define GUARDED_BY(x) __attribute__ ((guarded_by(x)))9#define GUARDED_VAR __attribute__ ((guarded_var))10#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))11#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))12#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))13#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))14#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))15#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))16#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))17#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__)))18#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))19#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))20#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))21#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))22#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))23#define EXCLUSIVE_LOCKS_REQUIRED(...) \24 __attribute__ ((exclusive_locks_required(__VA_ARGS__)))25#define SHARED_LOCKS_REQUIRED(...) \26 __attribute__ ((shared_locks_required(__VA_ARGS__)))27#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))28 29 30class LOCKABLE Mutex {31 public:32 void Lock() EXCLUSIVE_LOCK_FUNCTION();33 void ReaderLock() SHARED_LOCK_FUNCTION();34 void Unlock() UNLOCK_FUNCTION();35 36 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);37 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);38 39 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();40 void AssertReaderHeld() ASSERT_SHARED_LOCK();41};42 43class UnlockableMu{44};45 46class MuWrapper {47 public:48 Mutex mu;49 Mutex getMu() {50 return mu;51 }52 Mutex * getMuPointer() {53 return μ54 }55};56 57 58class MuDoubleWrapper {59 public:60 MuWrapper* muWrapper;61 MuWrapper* getWrapper() {62 return muWrapper;63 }64};65 66class SCOPED_LOCKABLE MutexLock {67 public:68 MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);69 ~MutexLock() UNLOCK_FUNCTION();70};71 72Mutex mu1;73UnlockableMu umu;74Mutex mu2;75MuWrapper muWrapper;76MuDoubleWrapper muDoubleWrapper;77Mutex* muPointer;78Mutex** muDoublePointer = & muPointer;79Mutex& muRef = mu1;80 81//---------------------------------------//82// Scoping tests83//--------------------------------------//84 85class Foo {86 Mutex foomu;87 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);88};89 90class Foo2 {91 void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);92 Mutex foomu;93};94 95class Bar {96 Mutex barmu;97 Mutex barmu2 ACQUIRED_AFTER(barmu);98};99 100 101//-----------------------------------------//102// No Thread Safety Analysis (noanal) //103//-----------------------------------------//104 105// FIXME: Right now we cannot parse attributes put on function definitions106// We would like to patch this at some point.107 108#if !__has_attribute(no_thread_safety_analysis)109#error "Should support no_thread_safety_analysis attribute"110#endif111 112void noanal_fun() NO_THREAD_SAFETY_ANALYSIS;113 114void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \115 // expected-error {{'no_thread_safety_analysis' attribute takes no arguments}}116 117int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS;118 119int noanal_testfn(int y) {120 int x NO_THREAD_SAFETY_ANALYSIS = y; // \121 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}122 return x;123};124 125int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \126 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}127 128class NoanalFoo {129 private:130 int test_field NO_THREAD_SAFETY_ANALYSIS; // \131 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}132 void test_method() NO_THREAD_SAFETY_ANALYSIS;133};134 135class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \136 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}137};138 139void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \140 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}141 142 143//-----------------------------------------//144// Guarded Var Attribute (gv)145//-----------------------------------------//146 147#if !__has_attribute(guarded_var)148#error "Should support guarded_var attribute"149#endif150 151int gv_var_noargs GUARDED_VAR;152 153int gv_var_args __attribute__((guarded_var(1))); // \154 // expected-error {{'guarded_var' attribute takes no arguments}}155 156class GVFoo {157 private:158 int gv_field_noargs GUARDED_VAR;159 int gv_field_args __attribute__((guarded_var(1))); // \160 // expected-error {{'guarded_var' attribute takes no arguments}}161};162 163class GUARDED_VAR GV { // \164 // expected-warning {{'guarded_var' attribute only applies to non-static data members and global variables}}165};166 167void gv_function() GUARDED_VAR; // \168 // expected-warning {{'guarded_var' attribute only applies to}}169 170void gv_function_params(int gv_lvar GUARDED_VAR); // \171 // expected-warning {{'guarded_var' attribute only applies to}}172 173int gv_testfn(int y){174 int x GUARDED_VAR = y; // \175 // expected-warning {{'guarded_var' attribute only applies to}}176 return x;177}178 179//-----------------------------------------//180// Pt Guarded Var Attribute (pgv)181//-----------------------------------------//182 183//FIXME: add support for boost::scoped_ptr<int> fancyptr and references184 185#if !__has_attribute(pt_guarded_var)186#error "Should support pt_guarded_var attribute"187#endif188 189int *pgv_pt_var_noargs PT_GUARDED_VAR;190 191int pgv_var_noargs PT_GUARDED_VAR; // \192 // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}193 194class PGVFoo {195 private:196 int *pt_field_noargs PT_GUARDED_VAR;197 int field_noargs PT_GUARDED_VAR; // \198 // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}199 int *gv_field_args __attribute__((pt_guarded_var(1))); // \200 // expected-error {{'pt_guarded_var' attribute takes no arguments}}201};202 203class PT_GUARDED_VAR PGV { // \204 // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}205};206 207int *pgv_var_args __attribute__((pt_guarded_var(1))); // \208 // expected-error {{'pt_guarded_var' attribute takes no arguments}}209 210 211void pgv_function() PT_GUARDED_VAR; // \212 // expected-warning {{'pt_guarded_var' attribute only applies to}}213 214void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \215 // expected-warning {{'pt_guarded_var' attribute only applies to}}216 217void pgv_testfn(int y){218 int *x PT_GUARDED_VAR = new int(0); // \219 // expected-warning {{'pt_guarded_var' attribute only applies to}}220 delete x;221}222 223//-----------------------------------------//224// Lockable Attribute (l)225//-----------------------------------------//226 227//FIXME: In future we may want to add support for structs, ObjC classes, etc.228 229#if !__has_attribute(lockable)230#error "Should support lockable attribute"231#endif232 233class LOCKABLE LTestClass {234};235 236class __attribute__((lockable (1))) LTestClass_args { // \237 // expected-error {{'lockable' attribute takes no arguments}}238};239 240void l_test_function() LOCKABLE; // \241 // expected-warning {{'lockable' attribute only applies to structs, unions, and classes}}242 243int l_testfn(int y) {244 int x LOCKABLE = y; // \245 // expected-warning {{'lockable' attribute only applies to}}246 return x;247}248 249int l_test_var LOCKABLE; // \250 // expected-warning {{'lockable' attribute only applies to}}251 252class LFoo {253 private:254 int test_field LOCKABLE; // \255 // expected-warning {{'lockable' attribute only applies to}}256 void test_method() LOCKABLE; // \257 // expected-warning {{'lockable' attribute only applies to}}258};259 260 261void l_function_params(int lvar LOCKABLE); // \262 // expected-warning {{'lockable' attribute only applies to}}263 264class LOCKABLE REENTRANT_CAPABILITY LTestReentrant {265};266 267// Attribute order does matter.268class REENTRANT_CAPABILITY LOCKABLE LTestReentrantWrongOrder { // \269 // expected-warning {{'reentrant_capability' attribute on 'LTestReentrantWrongOrder' must be preceded by 'capability' attribute}}270};271 272class REENTRANT_CAPABILITY LTestReentrantOnly { // \273 // expected-warning {{'reentrant_capability' attribute on 'LTestReentrantOnly' must be preceded by 'capability' attribute}}274};275 276//-----------------------------------------//277// Scoped Lockable Attribute (sl)278//-----------------------------------------//279 280#if !__has_attribute(scoped_lockable)281#error "Should support scoped_lockable attribute"282#endif283 284class SCOPED_LOCKABLE SLTestClass {285};286 287class __attribute__((scoped_lockable (1))) SLTestClass_args { // \288 // expected-error {{'scoped_lockable' attribute takes no arguments}}289};290 291void sl_test_function() SCOPED_LOCKABLE; // \292 // expected-warning {{'scoped_lockable' attribute only applies to structs, unions, and classes}}293 294int sl_testfn(int y) {295 int x SCOPED_LOCKABLE = y; // \296 // expected-warning {{'scoped_lockable' attribute only applies to}}297 return x;298}299 300int sl_test_var SCOPED_LOCKABLE; // \301 // expected-warning {{'scoped_lockable' attribute only applies to}}302 303class SLFoo {304 private:305 int test_field SCOPED_LOCKABLE; // \306 // expected-warning {{'scoped_lockable' attribute only applies to}}307 void test_method() SCOPED_LOCKABLE; // \308 // expected-warning {{'scoped_lockable' attribute only applies to}}309};310 311 312void sl_function_params(int lvar SCOPED_LOCKABLE); // \313 // expected-warning {{'scoped_lockable' attribute only applies to}}314 315 316//-----------------------------------------//317// Guarded By Attribute (gb)318//-----------------------------------------//319 320// FIXME: Eventually, would we like this attribute to take more than 1 arg?321 322#if !__has_attribute(guarded_by)323#error "Should support guarded_by attribute"324#endif325 326//1. Check applied to the right types & argument number327 328int gb_var_arg GUARDED_BY(mu1);329 330int gb_non_ascii GUARDED_BY(L"wide"); // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}331 332int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \333 // expected-error {{'guarded_by' attribute takes one argument}}334 335int gb_var_noargs __attribute__((guarded_by)); // \336 // expected-error {{'guarded_by' attribute takes one argument}}337 338class GBFoo {339 private:340 int gb_field_noargs __attribute__((guarded_by)); // \341 // expected-error {{'guarded_by' attribute takes one argument}}342 int gb_field_args GUARDED_BY(mu1);343};344 345class GUARDED_BY(mu1) GB { // \346 // expected-warning {{'guarded_by' attribute only applies to non-static data members and global variables}}347};348 349void gb_function() GUARDED_BY(mu1); // \350 // expected-warning {{'guarded_by' attribute only applies to}}351 352void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \353 // expected-warning {{'guarded_by' attribute only applies to}}354 355int gb_testfn(int y){356 int x GUARDED_BY(mu1) = y; // \357 // expected-warning {{'guarded_by' attribute only applies to}}358 return x;359}360 361//2. Check argument parsing.362 363// legal attribute arguments364int gb_var_arg_1 GUARDED_BY(muWrapper.mu);365int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu);366int gb_var_arg_3 GUARDED_BY(muWrapper.getMu());367int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer());368int gb_var_arg_5 GUARDED_BY(&mu1);369int gb_var_arg_6 GUARDED_BY(muRef);370int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());371int gb_var_arg_8 GUARDED_BY(muPointer);372int gb_var_arg_9 GUARDED_BY(!&mu1);373int gb_var_arg_10 GUARDED_BY(!&*&mu1);374 375// illegal attribute arguments376int gb_var_arg_bad_1 GUARDED_BY(1); // \377 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}378int gb_var_arg_bad_2 GUARDED_BY("mu"); // \379 // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}380int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \381 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}382int gb_var_arg_bad_4 GUARDED_BY(umu); // \383 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}}384 385//3.386// Thread Safety analysis tests387 388 389//-----------------------------------------//390// Pt Guarded By Attribute (pgb)391//-----------------------------------------//392 393#if !__has_attribute(pt_guarded_by)394#error "Should support pt_guarded_by attribute"395#endif396 397//1. Check applied to the right types & argument number398 399int *pgb_var_noargs __attribute__((pt_guarded_by)); // \400 // expected-error {{'pt_guarded_by' attribute takes one argument}}401 402int *pgb_ptr_var_arg PT_GUARDED_BY(mu1);403 404int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \405 // expected-error {{'pt_guarded_by' attribute takes one argument}}406 407int pgb_var_args PT_GUARDED_BY(mu1); // \408 // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}409 410class PGBFoo {411 private:412 int *pgb_field_noargs __attribute__((pt_guarded_by)); // \413 // expected-error {{'pt_guarded_by' attribute takes one argument}}414 int *pgb_field_args PT_GUARDED_BY(mu1);415};416 417class PT_GUARDED_BY(mu1) PGB { // \418 // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}419};420 421void pgb_function() PT_GUARDED_BY(mu1); // \422 // expected-warning {{'pt_guarded_by' attribute only applies to}}423 424void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \425 // expected-warning {{'pt_guarded_by' attribute only applies to}}426 427void pgb_testfn(int y){428 int *x PT_GUARDED_BY(mu1) = new int(0); // \429 // expected-warning {{'pt_guarded_by' attribute only applies to}}430 delete x;431}432 433//2. Check argument parsing.434 435// legal attribute arguments436int * pgb_var_arg_1 PT_GUARDED_BY(muWrapper.mu);437int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu);438int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu());439int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer());440int * pgb_var_arg_5 PT_GUARDED_BY(&mu1);441int * pgb_var_arg_6 PT_GUARDED_BY(muRef);442int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());443int * pgb_var_arg_8 PT_GUARDED_BY(muPointer);444 445 446// illegal attribute arguments447int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \448 // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}449int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \450 // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}451int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \452 // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}453int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \454 // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}}455 456 457//-----------------------------------------//458// Acquired After (aa)459//-----------------------------------------//460 461// FIXME: Would we like this attribute to take more than 1 arg?462 463#if !__has_attribute(acquired_after)464#error "Should support acquired_after attribute"465#endif466 467Mutex mu_aa ACQUIRED_AFTER(mu1);468 469Mutex aa_var_noargs __attribute__((acquired_after)); // \470 // expected-error {{'acquired_after' attribute takes at least 1 argument}}471 472class AAFoo {473 private:474 Mutex aa_field_noargs __attribute__((acquired_after)); // \475 // expected-error {{'acquired_after' attribute takes at least 1 argument}}476 Mutex aa_field_args ACQUIRED_AFTER(mu1);477};478 479class ACQUIRED_AFTER(mu1) AA { // \480 // expected-warning {{'acquired_after' attribute only applies to non-static data members and global variables}}481};482 483void aa_function() ACQUIRED_AFTER(mu1); // \484 // expected-warning {{'acquired_after' attribute only applies to}}485 486void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \487 // expected-warning {{'acquired_after' attribute only applies to}}488 489void aa_testfn(int y){490 Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \491 // expected-warning {{'acquired_after' attribute only applies to}}492}493 494//Check argument parsing.495 496// legal attribute arguments497Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu);498Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu);499Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu());500Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer());501Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1);502Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef);503Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu());504Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer);505 506 507// illegal attribute arguments508Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \509 // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}510Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \511 // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}512Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \513 // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}514Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \515 // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}}516UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \517 // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'capability' attribute}}518 519//-----------------------------------------//520// Acquired Before (ab)521//-----------------------------------------//522 523#if !__has_attribute(acquired_before)524#error "Should support acquired_before attribute"525#endif526 527Mutex mu_ab ACQUIRED_BEFORE(mu1);528 529Mutex ab_var_noargs __attribute__((acquired_before)); // \530 // expected-error {{'acquired_before' attribute takes at least 1 argument}}531 532class ABFoo {533 private:534 Mutex ab_field_noargs __attribute__((acquired_before)); // \535 // expected-error {{'acquired_before' attribute takes at least 1 argument}}536 Mutex ab_field_args ACQUIRED_BEFORE(mu1);537};538 539class ACQUIRED_BEFORE(mu1) AB { // \540 // expected-warning {{'acquired_before' attribute only applies to non-static data members and global variables}}541};542 543void ab_function() ACQUIRED_BEFORE(mu1); // \544 // expected-warning {{'acquired_before' attribute only applies to}}545 546void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \547 // expected-warning {{'acquired_before' attribute only applies to}}548 549void ab_testfn(int y){550 Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \551 // expected-warning {{'acquired_before' attribute only applies to}}552}553 554// Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will555// be taken care of by warnings that ab__int is not lockable.556 557//Check argument parsing.558 559// legal attribute arguments560Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu);561Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu);562Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu());563Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer());564Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1);565Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef);566Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu());567Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer);568 569 570// illegal attribute arguments571Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \572 // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}573Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \574 // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}575Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \576 // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}577Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \578 // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}}579UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \580 // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'capability' attribute}}581 582 583//-----------------------------------------//584// Exclusive Lock Function (elf)585//-----------------------------------------//586 587#if !__has_attribute(exclusive_lock_function)588#error "Should support exclusive_lock_function attribute"589#endif590 591// takes zero or more arguments, all locks (vars/fields)592 593void elf_function() EXCLUSIVE_LOCK_FUNCTION(); // expected-warning {{'exclusive_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}594 595void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);596 597int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION(); // expected-warning {{'exclusive_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}598 599int elf_testfn(int y) {600 int x EXCLUSIVE_LOCK_FUNCTION() = y; // \601 // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}602 return x;603};604 605int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \606 // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}607 608class ElfFoo {609 private:610 int test_field EXCLUSIVE_LOCK_FUNCTION(); // \611 // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}612 void test_method() EXCLUSIVE_LOCK_FUNCTION(); // \613 // expected-warning {{'exclusive_lock_function' attribute without capability arguments refers to 'this', but 'ElfFoo' isn't annotated with 'capability' or 'scoped_lockable' attribute}}614};615 616class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \617 // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}618};619 620void elf_fun_params1(MutexLock& scope EXCLUSIVE_LOCK_FUNCTION(mu1));621void elf_fun_params2(int lvar EXCLUSIVE_LOCK_FUNCTION(mu1)); // \622 // expected-warning{{'exclusive_lock_function' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}623void elf_fun_params3(MutexLock& scope EXCLUSIVE_LOCK_FUNCTION()); // \624 // expected-warning{{'exclusive_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}625 626// Check argument parsing.627 628// legal attribute arguments629int elf_function_1() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu);630int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);631int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu());632int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer());633int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1);634int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef);635int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());636int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer);637int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1);638int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2);639 640 641// illegal attribute arguments642int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \643 // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}644int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \645 // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}646int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \647 // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}648 649int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \650 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}651int elf_function_bad_5(Mutex x) EXCLUSIVE_LOCK_FUNCTION(0); // \652 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}653int elf_function_bad_6(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(0); // \654 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}655int elf_function_bad_7() EXCLUSIVE_LOCK_FUNCTION(0); // \656 // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}657 658template<typename Mu>659int elf_template(Mu& mu) EXCLUSIVE_LOCK_FUNCTION(mu) {}660 661template int elf_template<Mutex>(Mutex&);662// FIXME: warn on template instantiation.663template int elf_template<UnlockableMu>(UnlockableMu&);664 665#if __cplusplus >= 201103666 667template<typename... Mus>668int elf_variadic_template(Mus&... mus) EXCLUSIVE_LOCK_FUNCTION(mus...) {}669 670template int elf_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);671// FIXME: warn on template instantiation.672template int elf_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);673 674#endif675 676 677//-----------------------------------------//678// Shared Lock Function (slf)679//-----------------------------------------//680 681#if !__has_attribute(shared_lock_function)682#error "Should support shared_lock_function attribute"683#endif684 685// takes zero or more arguments, all locks (vars/fields)686 687void slf_function() SHARED_LOCK_FUNCTION(); // expected-warning {{'shared_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}688 689void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2);690 691int slf_testfn(int y) SHARED_LOCK_FUNCTION(); // expected-warning {{'shared_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}692 693int slf_testfn(int y) {694 int x SHARED_LOCK_FUNCTION() = y; // \695 // expected-warning {{'shared_lock_function' attribute only applies to functions}}696 return x;697};698 699int slf_test_var SHARED_LOCK_FUNCTION(); // \700 // expected-warning {{'shared_lock_function' attribute only applies to functions}}701 702void slf_fun_params1(MutexLock& scope SHARED_LOCK_FUNCTION(mu1));703void slf_fun_params2(int lvar SHARED_LOCK_FUNCTION(mu1)); // \704 // expected-warning {{'shared_lock_function' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}705void slf_fun_params3(MutexLock& scope SHARED_LOCK_FUNCTION()); // \706 // expected-warning {{'shared_lock_function' attribute without capability arguments can only be applied to non-static methods of a class}}707 708class SlfFoo {709 private:710 int test_field SHARED_LOCK_FUNCTION(); // \711 // expected-warning {{'shared_lock_function' attribute only applies to functions}}712 void test_method() SHARED_LOCK_FUNCTION(); // \713 // expected-warning {{'shared_lock_function' attribute without capability arguments refers to 'this', but 'SlfFoo' isn't annotated with 'capability' or 'scoped_lockable' attribute}}714};715 716class SHARED_LOCK_FUNCTION() SlfTestClass { // \717 // expected-warning {{'shared_lock_function' attribute only applies to functions}}718};719 720// Check argument parsing.721 722// legal attribute arguments723int slf_function_1() SHARED_LOCK_FUNCTION(muWrapper.mu);724int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);725int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu());726int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer());727int slf_function_5() SHARED_LOCK_FUNCTION(&mu1);728int slf_function_6() SHARED_LOCK_FUNCTION(muRef);729int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());730int slf_function_8() SHARED_LOCK_FUNCTION(muPointer);731int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1);732int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2);733 734 735// illegal attribute arguments736int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \737 // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}738int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \739 // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}740int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \741 // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}742 743int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \744 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}745int slf_function_bad_5(Mutex x) SHARED_LOCK_FUNCTION(0); // \746 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}747int slf_function_bad_6(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(0); // \748 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}749int slf_function_bad_7() SHARED_LOCK_FUNCTION(0); // \750 // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}751 752template<typename Mu>753int slf_template(Mu& mu) SHARED_LOCK_FUNCTION(mu) {}754 755template int slf_template<Mutex>(Mutex&);756// FIXME: warn on template instantiation.757template int slf_template<UnlockableMu>(UnlockableMu&);758 759#if __cplusplus >= 201103760 761template<typename... Mus>762int slf_variadic_template(Mus&... mus) SHARED_LOCK_FUNCTION(mus...) {}763 764template int slf_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);765// FIXME: warn on template instantiation.766template int slf_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);767 768#endif769 770 771//-----------------------------------------//772// Exclusive TryLock Function (etf)773//-----------------------------------------//774 775#if !__has_attribute(exclusive_trylock_function)776#error "Should support exclusive_trylock_function attribute"777#endif778 779// takes a mandatory boolean or integer argument specifying the retval780// plus an optional list of locks (vars/fields)781 782void etf_function() __attribute__((exclusive_trylock_function)); // \783 // expected-error {{'exclusive_trylock_function' attribute takes at least 1 argument}}784 785void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);786 787void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1); // \788 // expected-warning {{'exclusive_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}789 790int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1); // \791 // expected-warning {{'exclusive_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}792 793int etf_testfn(int y) {794 int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \795 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}796 return x;797};798 799int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \800 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}801 802class EtfFoo {803 private:804 int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \805 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}806 void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1); // \807 // expected-warning {{'exclusive_trylock_function' attribute without capability arguments refers to 'this', but 'EtfFoo' isn't annotated with 'capability' or 'scoped_lockable' attribute}}808};809 810class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \811 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}812};813 814void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \815 // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}816 817// Check argument parsing.818 819// legal attribute arguments820int etf_function_1() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu);821int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);822int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu());823int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());824int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1);825int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef);826int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());827int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer);828int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true); // \829 // expected-warning {{'exclusive_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}830 831 832// illegal attribute arguments833int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \834 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}835int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \836 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}837int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \838 // expected-error {{'exclusive_trylock_function' attribute requires parameter 1 to be int or bool}}839 840int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \841 // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}842int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \843 // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}844int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \845 // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}846 847template<typename Mu>848int etf_template(Mu& mu) EXCLUSIVE_TRYLOCK_FUNCTION(1, mu) {}849 850template int etf_template<Mutex>(Mutex&);851// FIXME: warn on template instantiation.852template int etf_template<UnlockableMu>(UnlockableMu&);853 854#if __cplusplus >= 201103855 856template<typename... Mus>857int etf_variadic_template(Mus&... mus) EXCLUSIVE_TRYLOCK_FUNCTION(1, mus...) {}858 859template int etf_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);860// FIXME: warn on template instantiation.861template int etf_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);862 863#endif864 865 866//-----------------------------------------//867// Shared TryLock Function (stf)868//-----------------------------------------//869 870#if !__has_attribute(shared_trylock_function)871#error "Should support shared_trylock_function attribute"872#endif873 874// takes a mandatory boolean or integer argument specifying the retval875// plus an optional list of locks (vars/fields)876 877void stf_function() __attribute__((shared_trylock_function)); // \878 // expected-error {{'shared_trylock_function' attribute takes at least 1 argument}}879 880void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);881 882void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1); // \883 // expected-warning {{'shared_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}884 885int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1); // \886 // expected-warning {{'shared_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}887 888int stf_testfn(int y) {889 int x SHARED_TRYLOCK_FUNCTION(1) = y; // \890 // expected-warning {{'shared_trylock_function' attribute only applies to functions}}891 return x;892};893 894int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \895 // expected-warning {{'shared_trylock_function' attribute only applies to functions}}896 897void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \898 // expected-warning {{'shared_trylock_function' attribute only applies to functions}}899 900 901class StfFoo {902 private:903 int test_field SHARED_TRYLOCK_FUNCTION(1); // \904 // expected-warning {{'shared_trylock_function' attribute only applies to functions}}905 void test_method() SHARED_TRYLOCK_FUNCTION(1); // \906 // expected-warning {{'shared_trylock_function' attribute without capability arguments refers to 'this', but 'StfFoo' isn't annotated with 'capability' or 'scoped_lockable' attribute}}907};908 909class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \910 // expected-warning {{'shared_trylock_function' attribute only applies to functions}}911};912 913// Check argument parsing.914 915// legal attribute arguments916int stf_function_1() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu);917int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);918int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu());919int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());920int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1);921int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef);922int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());923int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer);924int stf_function_9() SHARED_TRYLOCK_FUNCTION(true); // \925 // expected-warning {{'shared_trylock_function' attribute without capability arguments can only be applied to non-static methods of a class}}926 927 928// illegal attribute arguments929int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \930 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}931int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \932 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}933int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \934 // expected-error {{'shared_trylock_function' attribute requires parameter 1 to be int or bool}}935 936int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \937 // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}938int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \939 // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}940int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \941 // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}942 943template<typename Mu>944int stf_template(Mu& mu) SHARED_TRYLOCK_FUNCTION(1, mu) {}945 946template int stf_template<Mutex>(Mutex&);947// FIXME: warn on template instantiation.948template int stf_template<UnlockableMu>(UnlockableMu&);949 950#if __cplusplus >= 201103951 952template<typename... Mus>953int stf_variadic_template(Mus&... mus) SHARED_TRYLOCK_FUNCTION(1, mus...) {}954 955template int stf_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);956// FIXME: warn on template instantiation.957template int stf_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);958 959#endif960 961 962//-----------------------------------------//963// Unlock Function (uf)964//-----------------------------------------//965 966#if !__has_attribute(unlock_function)967#error "Should support unlock_function attribute"968#endif969 970// takes zero or more arguments, all locks (vars/fields)971 972void uf_function() UNLOCK_FUNCTION(); // \973 // expected-warning {{'unlock_function' attribute without capability arguments can only be applied to non-static methods of a class}}974 975 976void uf_function_args() UNLOCK_FUNCTION(mu1, mu2);977 978int uf_testfn(int y) UNLOCK_FUNCTION(); //\979 // expected-warning {{'unlock_function' attribute without capability arguments can only be applied to non-static methods of a class}}980 981int uf_testfn(int y) {982 int x UNLOCK_FUNCTION() = y; // \983 // expected-warning {{'unlock_function' attribute only applies to functions}}984 return x;985};986 987int uf_test_var UNLOCK_FUNCTION(); // \988 // expected-warning {{'unlock_function' attribute only applies to functions}}989 990class UfFoo {991 private:992 int test_field UNLOCK_FUNCTION(); // \993 // expected-warning {{'unlock_function' attribute only applies to functions}}994 void test_method() UNLOCK_FUNCTION(); // \995 // expected-warning {{'unlock_function' attribute without capability arguments refers to 'this', but 'UfFoo' isn't annotated with 'capability' or 'scoped_lockable' attribute}}996};997 998class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \999 // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}1000};1001 1002void uf_fun_params1(MutexLock& scope UNLOCK_FUNCTION(mu1));1003void uf_fun_params2(int lvar UNLOCK_FUNCTION(mu1)); // \1004 // expected-warning {{'unlock_function' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}1005void uf_fun_params3(MutexLock& scope UNLOCK_FUNCTION()); // \1006 // expected-warning {{'unlock_function' attribute without capability arguments can only be applied to non-static methods of a class}}1007 1008// Check argument parsing.1009 1010// legal attribute arguments1011int uf_function_1() UNLOCK_FUNCTION(muWrapper.mu);1012int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);1013int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu());1014int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer());1015int uf_function_5() UNLOCK_FUNCTION(&mu1);1016int uf_function_6() UNLOCK_FUNCTION(muRef);1017int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());1018int uf_function_8() UNLOCK_FUNCTION(muPointer);1019int uf_function_9(Mutex x) UNLOCK_FUNCTION(1);1020int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2);1021 1022 1023// illegal attribute arguments1024int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \1025 // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}1026int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \1027 // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}1028int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \1029 // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}1030 1031int uf_function_bad_1() UNLOCK_FUNCTION(1); // \1032 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}1033int uf_function_bad_5(Mutex x) UNLOCK_FUNCTION(0); // \1034 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}1035int uf_function_bad_6(Mutex x, Mutex y) UNLOCK_FUNCTION(0); // \1036 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}1037int uf_function_bad_7() UNLOCK_FUNCTION(0); // \1038 // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}1039 1040template<typename Mu>1041int uf_template(Mu& mu) UNLOCK_FUNCTION(mu) {}1042 1043template int uf_template<Mutex>(Mutex&);1044// FIXME: warn on template instantiation.1045template int uf_template<UnlockableMu>(UnlockableMu&);1046 1047#if __cplusplus >= 2011031048 1049template<typename... Mus>1050int uf_variadic_template(Mus&... mus) UNLOCK_FUNCTION(mus...) {}1051 1052template int uf_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);1053// FIXME: warn on template instantiation.1054template int uf_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);1055 1056#endif1057 1058 1059//-----------------------------------------//1060// Lock Returned (lr)1061//-----------------------------------------//1062 1063#if !__has_attribute(lock_returned)1064#error "Should support lock_returned attribute"1065#endif1066 1067// Takes exactly one argument, a var/field1068 1069void lr_function() __attribute__((lock_returned)); // \1070 // expected-error {{'lock_returned' attribute takes one argument}}1071 1072void lr_function_arg() LOCK_RETURNED(mu1);1073 1074void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \1075 // expected-error {{'lock_returned' attribute takes one argument}}1076 1077int lr_testfn(int y) LOCK_RETURNED(mu1);1078 1079int lr_testfn(int y) {1080 int x LOCK_RETURNED(mu1) = y; // \1081 // expected-warning {{'lock_returned' attribute only applies to functions}}1082 return x;1083};1084 1085int lr_test_var LOCK_RETURNED(mu1); // \1086 // expected-warning {{'lock_returned' attribute only applies to functions}}1087 1088void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \1089 // expected-warning {{'lock_returned' attribute only applies to functions}}1090 1091class LrFoo {1092 private:1093 int test_field LOCK_RETURNED(mu1); // \1094 // expected-warning {{'lock_returned' attribute only applies to functions}}1095 void test_method() LOCK_RETURNED(mu1);1096};1097 1098class LOCK_RETURNED(mu1) LrTestClass { // \1099 // expected-warning {{'lock_returned' attribute only applies to functions}}1100};1101 1102// Check argument parsing.1103 1104// legal attribute arguments1105int lr_function_1() LOCK_RETURNED(muWrapper.mu);1106int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu);1107int lr_function_3() LOCK_RETURNED(muWrapper.getMu());1108int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer());1109int lr_function_5() LOCK_RETURNED(&mu1);1110int lr_function_6() LOCK_RETURNED(muRef);1111int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu());1112int lr_function_8() LOCK_RETURNED(muPointer);1113 1114 1115// illegal attribute arguments1116int lr_function_bad_1() LOCK_RETURNED(1); // \1117 // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}1118int lr_function_bad_2() LOCK_RETURNED("mu"); // \1119 // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}1120int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \1121 // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}1122int lr_function_bad_4() LOCK_RETURNED(umu); // \1123 // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}}1124 1125 1126 1127//-----------------------------------------//1128// Locks Excluded (le)1129//-----------------------------------------//1130 1131#if !__has_attribute(locks_excluded)1132#error "Should support locks_excluded attribute"1133#endif1134 1135// takes one or more arguments, all locks (vars/fields)1136 1137void le_function() __attribute__((locks_excluded)); // \1138 // expected-error {{'locks_excluded' attribute takes at least 1 argument}}1139 1140void le_function_arg() LOCKS_EXCLUDED(mu1);1141 1142void le_function_args() LOCKS_EXCLUDED(mu1, mu2);1143 1144int le_testfn(int y) LOCKS_EXCLUDED(mu1);1145 1146int le_testfn(int y) {1147 int x LOCKS_EXCLUDED(mu1) = y; // \1148 // expected-warning {{'locks_excluded' attribute only applies to functions}}1149 return x;1150};1151 1152int le_test_var LOCKS_EXCLUDED(mu1); // \1153 // expected-warning {{'locks_excluded' attribute only applies to functions}}1154 1155void le_fun_params1(MutexLock& scope LOCKS_EXCLUDED(mu1));1156void le_fun_params2(int lvar LOCKS_EXCLUDED(mu1)); // \1157 // expected-warning{{'locks_excluded' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}1158 1159class LeFoo {1160 private:1161 int test_field LOCKS_EXCLUDED(mu1); // \1162 // expected-warning {{'locks_excluded' attribute only applies to functions}}1163 void test_method() LOCKS_EXCLUDED(mu1);1164};1165 1166class LOCKS_EXCLUDED(mu1) LeTestClass { // \1167 // expected-warning {{'locks_excluded' attribute only applies to functions}}1168};1169 1170// Check argument parsing.1171 1172// legal attribute arguments1173int le_function_1() LOCKS_EXCLUDED(muWrapper.mu);1174int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu);1175int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu());1176int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer());1177int le_function_5() LOCKS_EXCLUDED(&mu1);1178int le_function_6() LOCKS_EXCLUDED(muRef);1179int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu());1180int le_function_8() LOCKS_EXCLUDED(muPointer);1181 1182 1183// illegal attribute arguments1184int le_function_bad_1() LOCKS_EXCLUDED(1); // \1185 // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}1186int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \1187 // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}1188int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \1189 // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}1190int le_function_bad_4() LOCKS_EXCLUDED(umu); // \1191 // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}}1192 1193template<typename Mu>1194int le_template(Mu& mu) LOCKS_EXCLUDED(mu) {}1195 1196template int le_template<Mutex>(Mutex&);1197// FIXME: warn on template instantiation.1198template int le_template<UnlockableMu>(UnlockableMu&);1199 1200#if __cplusplus >= 2011031201 1202template<typename... Mus>1203int le_variadic_template(Mus&... mus) LOCKS_EXCLUDED(mus...) {}1204 1205template int le_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);1206// FIXME: warn on template instantiation.1207template int le_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);1208 1209#endif1210 1211 1212//-----------------------------------------//1213// Exclusive Locks Required (elr)1214//-----------------------------------------//1215 1216#if !__has_attribute(exclusive_locks_required)1217#error "Should support exclusive_locks_required attribute"1218#endif1219 1220// takes one or more arguments, all locks (vars/fields)1221 1222void elr_function() __attribute__((exclusive_locks_required)); // \1223 // expected-error {{'exclusive_locks_required' attribute takes at least 1 argument}}1224 1225void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);1226 1227void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2);1228 1229int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1);1230 1231int elr_testfn(int y) {1232 int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \1233 // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}1234 return x;1235};1236 1237int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \1238 // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}1239 1240void elr_fun_params1(MutexLock& scope EXCLUSIVE_LOCKS_REQUIRED(mu1));1241void elr_fun_params2(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \1242 // expected-warning {{'exclusive_locks_required' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}1243 1244class ElrFoo {1245 private:1246 int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \1247 // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}1248 void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);1249};1250 1251class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \1252 // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}1253};1254 1255// Check argument parsing.1256 1257// legal attribute arguments1258int elr_function_1() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu);1259int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);1260int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu());1261int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer());1262int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1);1263int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef);1264int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());1265int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer);1266 1267 1268// illegal attribute arguments1269int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \1270 // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}1271int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \1272 // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}1273int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \1274 // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}1275int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \1276 // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}1277 1278template<typename Mu>1279int elr_template(Mu& mu) EXCLUSIVE_LOCKS_REQUIRED(mu) {}1280 1281template int elr_template<Mutex>(Mutex&);1282// FIXME: warn on template instantiation.1283template int elr_template<UnlockableMu>(UnlockableMu&);1284 1285#if __cplusplus >= 2011031286 1287template<typename... Mus>1288int elr_variadic_template(Mus&... mus) EXCLUSIVE_LOCKS_REQUIRED(mus...) {}1289 1290template int elr_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);1291// FIXME: warn on template instantiation.1292template int elr_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);1293 1294#endif1295 1296 1297 1298 1299//-----------------------------------------//1300// Shared Locks Required (slr)1301//-----------------------------------------//1302 1303#if !__has_attribute(shared_locks_required)1304#error "Should support shared_locks_required attribute"1305#endif1306 1307// takes one or more arguments, all locks (vars/fields)1308 1309void slr_function() __attribute__((shared_locks_required)); // \1310 // expected-error {{'shared_locks_required' attribute takes at least 1 argument}}1311 1312void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);1313 1314void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2);1315 1316int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1);1317 1318int slr_testfn(int y) {1319 int x SHARED_LOCKS_REQUIRED(mu1) = y; // \1320 // expected-warning {{'shared_locks_required' attribute only applies to functions}}1321 return x;1322};1323 1324int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \1325 // expected-warning {{'shared_locks_required' attribute only applies to functions}}1326 1327void slr_fun_params1(MutexLock& scope SHARED_LOCKS_REQUIRED(mu1));1328void slr_fun_params2(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \1329 // expected-warning {{'shared_locks_required' attribute applies to function parameters only if their type is a reference to a 'scoped_lockable'-annotated type}}1330 1331class SlrFoo {1332 private:1333 int test_field SHARED_LOCKS_REQUIRED(mu1); // \1334 // expected-warning {{'shared_locks_required' attribute only applies to functions}}1335 void test_method() SHARED_LOCKS_REQUIRED(mu1);1336};1337 1338class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \1339 // expected-warning {{'shared_locks_required' attribute only applies to functions}}1340};1341 1342// Check argument parsing.1343 1344// legal attribute arguments1345int slr_function_1() SHARED_LOCKS_REQUIRED(muWrapper.mu);1346int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);1347int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu());1348int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer());1349int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1);1350int slr_function_6() SHARED_LOCKS_REQUIRED(muRef);1351int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());1352int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer);1353 1354 1355// illegal attribute arguments1356int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \1357 // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}1358int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \1359 // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}1360int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \1361 // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}1362int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \1363 // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}1364 1365template<typename Mu>1366int slr_template(Mu& mu) SHARED_LOCKS_REQUIRED(mu) {}1367 1368template int slr_template<Mutex>(Mutex&);1369// FIXME: warn on template instantiation.1370template int slr_template<UnlockableMu>(UnlockableMu&);1371 1372#if __cplusplus >= 2011031373 1374template<typename... Mus>1375int slr_variadic_template(Mus&... mus) SHARED_LOCKS_REQUIRED(mus...) {}1376 1377template int slr_variadic_template<Mutex, Mutex>(Mutex&, Mutex&);1378// FIXME: warn on template instantiation.1379template int slr_variadic_template<Mutex, UnlockableMu>(Mutex&, UnlockableMu&);1380 1381#endif1382 1383 1384//-----------------------------------------//1385// Regression tests for unusual cases.1386//-----------------------------------------//1387 1388int trivially_false_edges(bool b) {1389 // Create NULL (never taken) edges in CFG1390 if (false) return 1;1391 else return 2;1392}1393 1394// Possible Clang bug -- method pointer in template parameter1395class UnFoo {1396public:1397 void foo();1398};1399 1400template<void (UnFoo::*methptr)()>1401class MCaller {1402public:1403 static void call_method_ptr(UnFoo *f) {1404 // FIXME: Possible Clang bug:1405 // getCalleeDecl() returns NULL in the following case:1406 (f->*methptr)();1407 }1408};1409 1410void call_method_ptr_inst(UnFoo* f) {1411 MCaller<&UnFoo::foo>::call_method_ptr(f);1412}1413 1414int temp;1415void empty_back_edge() {1416 // Create a back edge to a block with no statements1417 for (;;) {1418 ++temp;1419 if (temp > 10) break;1420 }1421}1422 1423struct Foomger {1424 void operator++();1425};1426 1427struct Foomgoper {1428 Foomger f;1429 1430 bool done();1431 void invalid_back_edge() {1432 do {1433 // FIXME: Possible Clang bug:1434 // The first statement in this basic block has no source location1435 ++f;1436 } while (!done());1437 }1438};1439 1440template <typename Mutex>1441struct SCOPED_LOCKABLE SLTemplateClass {1442 ~SLTemplateClass() UNLOCK_FUNCTION();1443};1444 1445template <typename Mutex>1446struct NonSLTemplateClass {1447 ~NonSLTemplateClass() UNLOCK_FUNCTION(); // \1448 // expected-warning{{'unlock_function' attribute without capability arguments refers to 'this', but 'NonSLTemplateClass' isn't annotated with 'capability' or 'scoped_lockable' attribute}}1449};1450 1451template <>1452struct SLTemplateClass<int> {};1453 1454template <typename Mutex>1455struct SLTemplateDerived : public SLTemplateClass<Mutex> {1456 ~SLTemplateDerived() UNLOCK_FUNCTION();1457};1458 1459// FIXME: warn on template instantiation.1460template struct SLTemplateDerived<int>;1461 1462struct SLDerived1 : public SLTemplateClass<double> {1463 ~SLDerived1() UNLOCK_FUNCTION();1464};1465 1466struct SLDerived2 : public SLTemplateClass<int> {1467 ~SLDerived2() UNLOCK_FUNCTION(); // \1468 // expected-warning{{'unlock_function' attribute without capability arguments refers to 'this', but 'SLDerived2' isn't annotated with 'capability' or 'scoped_lockable' attribute}}1469};1470 1471struct SLDerived3 : public SLTemplateDerived<int> {1472 ~SLDerived3() UNLOCK_FUNCTION(); // \1473 // expected-warning{{'unlock_function' attribute without capability arguments refers to 'this', but 'SLDerived3' isn't annotated with 'capability' or 'scoped_lockable' attribute}}1474};1475 1476//-----------------------------------------------------1477// Parsing of member variables and function parameters1478//------------------------------------------------------1479 1480Mutex gmu;1481 1482class StaticMu {1483 static Mutex statmu;1484};1485 1486class FooLate {1487public:1488 void foo1() EXCLUSIVE_LOCKS_REQUIRED(gmu) { }1489 void foo2() EXCLUSIVE_LOCKS_REQUIRED(mu) { }1490 void foo3(Mutex *m) EXCLUSIVE_LOCKS_REQUIRED(m) { }1491 void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }1492 void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);1493 1494 static void foo5() EXCLUSIVE_LOCKS_REQUIRED(mu);1495//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect1496#if __cplusplus <= 199711L1497 // expected-error@-3 {{invalid use of member 'mu' in static member function}}1498#endif1499 1500 template <class T>1501 void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }1502 1503 template <class T>1504 void foo7(T* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }1505 1506 int a GUARDED_BY(gmu);1507 int b GUARDED_BY(mu);1508 int c GUARDED_BY(this->mu);1509 1510 Mutex mu;1511};1512 1513//-------------------------1514// Empty argument lists1515//-------------------------1516 1517class LOCKABLE EmptyArgListsTest {1518 void lock() EXCLUSIVE_LOCK_FUNCTION() { }1519 void unlock() UNLOCK_FUNCTION() { }1520};1521 1522 1523namespace FunctionDefinitionParseTest {1524// Test parsing of attributes on function definitions.1525 1526class Foo {1527public:1528 Mutex mu_;1529 void foo1();1530 void foo2(Foo *f);1531};1532 1533template <class T>1534class Bar {1535public:1536 Mutex mu_;1537 void bar();1538};1539 1540void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }1541void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }1542 1543template <class T>1544void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }1545 1546void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }1547 1548} // end namespace1549 1550 1551namespace TestMultiDecl {1552 1553class Foo {1554public:1555 int GUARDED_BY(mu_) a;1556 int GUARDED_BY(mu_) b, c;1557 1558private:1559 Mutex mu_;1560};1561 1562} // end namespace TestMultiDecl1563 1564 1565namespace NestedClassLateDecl {1566 1567class Foo {1568 class Bar {1569 int a GUARDED_BY(mu);1570 int b GUARDED_BY(fooMuStatic);1571 1572 void bar() EXCLUSIVE_LOCKS_REQUIRED(mu) { a = 0; }1573 void bar2(Bar* b) EXCLUSIVE_LOCKS_REQUIRED(b->mu) { b->a = 0; }1574 void bar3(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->fooMu) { f->a = 0; }1575 1576 Mutex mu;1577 };1578 1579 int a GUARDED_BY(fooMu);1580 Mutex fooMu;1581 static Mutex fooMuStatic;1582};1583 1584}1585 1586namespace PointerToMemberTest {1587 1588// Empty string should be ignored.1589int testEmptyAttribute GUARDED_BY("");1590void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED("");1591 1592class Graph {1593public:1594 Mutex mu_;1595 1596 static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_);1597};1598 1599class Node {1600public:1601 void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_);1602 int a GUARDED_BY(&Graph::mu_);1603};1604 1605}1606 1607 1608namespace SmartPointerTest {1609 1610template<class T>1611class smart_ptr {1612 public:1613 T* operator->() { return ptr_; }1614 T& operator*() { return ptr_; }1615 1616 private:1617 T* ptr_;1618};1619 1620 1621Mutex gmu;1622smart_ptr<int> gdat PT_GUARDED_BY(gmu);1623 1624 1625class MyClass {1626public:1627 Mutex mu_;1628 smart_ptr<Mutex> smu_;1629 1630 1631 smart_ptr<int> a PT_GUARDED_BY(mu_);1632 int b GUARDED_BY(smu_);1633};1634 1635}1636 1637 1638namespace InheritanceTest {1639 1640class LOCKABLE Base {1641 public:1642 void lock() EXCLUSIVE_LOCK_FUNCTION();1643 void unlock() UNLOCK_FUNCTION();1644};1645 1646class Base2 { };1647 1648class Derived1 : public Base { };1649 1650class Derived2 : public Base2, public Derived1 { };1651 1652class Derived3 : public Base2 { };1653 1654class Foo {1655 Derived1 mu1_;1656 Derived2 mu2_;1657 Derived3 mu3_;1658 int a GUARDED_BY(mu1_);1659 int b GUARDED_BY(mu2_);1660 int c GUARDED_BY(mu3_); // \1661 // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Derived3'}}1662 1663 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {1664 a = 0;1665 b = 0;1666 }1667};1668 1669}1670 1671 1672namespace InvalidDeclTest {1673 1674class Foo { };1675namespace {1676void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \1677 // expected-error {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \1678 // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}1679}1680 1681} // end namespace InvalidDeclTest1682 1683 1684namespace StaticScopeTest {1685 1686class FooStream;1687 1688class Foo {1689 mutable Mutex mu;1690 int a GUARDED_BY(mu);1691 1692 static int si GUARDED_BY(mu);1693//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect1694#if __cplusplus <= 199711L1695 // expected-error@-3 {{invalid use of non-static data member 'mu'}}1696#endif1697 1698 static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu);1699//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect1700#if __cplusplus <= 199711L1701 // expected-error@-3 {{invalid use of member 'mu' in static member function}}1702#endif1703 1704 friend FooStream& operator<<(FooStream& s, const Foo& f)1705 EXCLUSIVE_LOCKS_REQUIRED(mu);1706//FIXME: Bug 32066 - Error should be emitted irrespective of C++ dialect1707#if __cplusplus <= 199711L1708 // expected-error@-3 {{invalid use of non-static data member 'mu'}}1709#endif1710};1711 1712 1713} // end namespace StaticScopeTest1714 1715 1716namespace FunctionAttributesInsideClass_ICE_Test {1717 1718class Foo {1719public:1720 /* Originally found when parsing foo() as an ordinary method after the1721 * the following:1722 1723 template <class T>1724 void syntaxErrorMethod(int i) {1725 if (i) {1726 foo(1727 }1728 }1729 */1730 1731 void method() {1732 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \1733 // expected-error {{use of undeclared identifier 'mu'}}1734 }1735};1736 1737} // end namespace FunctionAttributesInsideClass_ICE_Test1738 1739 1740#if __cplusplus >= 2011031741namespace CRASH_POST_R301735 {1742 class SomeClass {1743 public:1744 void foo() {1745 auto l = [this] { auto l = [] () EXCLUSIVE_LOCKS_REQUIRED(mu_) {}; };1746 }1747 Mutex mu_;1748 };1749}1750#endif1751