brintos

brintos / llvm-project-archived public Read only

0
0
Text · 63.0 KiB · 570586a Raw
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 &mu;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