2011-08-10 01:59:31 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
2011-07-29 01:21:07 +08:00
2012-04-06 23:10:17 +08:00
# define LOCKABLE __attribute__ ((lockable))
# define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
# define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
# define GUARDED_VAR __attribute__ ((guarded_var))
# define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
# define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
# define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
# define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
# define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
# define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
# define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
# define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
# define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
# define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
# define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
# define EXCLUSIVE_LOCKS_REQUIRED(...) \
__attribute__ ( ( exclusive_locks_required ( __VA_ARGS__ ) ) )
# define SHARED_LOCKS_REQUIRED(...) \
__attribute__ ( ( shared_locks_required ( __VA_ARGS__ ) ) )
# define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
class LOCKABLE Mutex {
2011-09-09 01:42:22 +08:00
public :
void Lock ( ) ;
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
class UnlockableMu {
} ;
class MuWrapper {
public :
2012-04-24 04:41:57 +08:00
Mutex mu ;
Mutex getMu ( ) {
2011-08-10 01:59:31 +08:00
return mu ;
}
2012-04-24 04:41:57 +08:00
Mutex * getMuPointer ( ) {
2011-08-10 01:59:31 +08:00
return & mu ;
}
} ;
class MuDoubleWrapper {
public :
MuWrapper * muWrapper ;
MuWrapper * getWrapper ( ) {
return muWrapper ;
}
} ;
2012-04-24 04:41:57 +08:00
Mutex mu1 ;
2011-08-10 01:59:31 +08:00
UnlockableMu umu ;
2012-04-24 04:41:57 +08:00
Mutex mu2 ;
2011-08-10 01:59:31 +08:00
MuWrapper muWrapper ;
MuDoubleWrapper muDoubleWrapper ;
2012-04-24 04:41:57 +08:00
Mutex * muPointer ;
Mutex * * muDoublePointer = & muPointer ;
Mutex & muRef = mu1 ;
2011-07-29 04:12:35 +08:00
2011-09-09 01:42:22 +08:00
//---------------------------------------//
// Scoping tests
//--------------------------------------//
class Foo {
2012-04-24 04:41:57 +08:00
Mutex foomu ;
void needLock ( ) EXCLUSIVE_LOCK_FUNCTION ( foomu ) ;
2011-09-09 01:42:22 +08:00
} ;
class Foo2 {
2012-04-24 04:41:57 +08:00
void needLock ( ) EXCLUSIVE_LOCK_FUNCTION ( foomu ) ;
Mutex foomu ;
2011-09-09 01:42:22 +08:00
} ;
class Bar {
2012-04-24 04:41:57 +08:00
Mutex barmu ;
Mutex barmu2 ACQUIRED_AFTER ( barmu ) ;
2011-09-09 01:42:22 +08:00
} ;
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// No Thread Safety Analysis (noanal) //
//-----------------------------------------//
2011-07-29 01:21:07 +08:00
// FIXME: Right now we cannot parse attributes put on function definitions
// We would like to patch this at some point.
# if !__has_attribute(no_thread_safety_analysis)
# error "Should support no_thread_safety_analysis attribute"
# endif
2012-04-24 04:41:57 +08:00
void noanal_fun ( ) NO_THREAD_SAFETY_ANALYSIS ;
2011-07-29 01:21:07 +08:00
2011-08-24 02:46:34 +08:00
void noanal_fun_args ( ) __attribute__ ( ( no_thread_safety_analysis ( 1 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
2012-04-24 04:41:57 +08:00
int noanal_testfn ( int y ) NO_THREAD_SAFETY_ANALYSIS ;
2011-07-29 01:21:07 +08:00
int noanal_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x NO_THREAD_SAFETY_ANALYSIS = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2011-07-29 01:21:07 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int noanal_test_var NO_THREAD_SAFETY_ANALYSIS ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2011-07-29 01:21:07 +08:00
class NoanalFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field NO_THREAD_SAFETY_ANALYSIS ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) NO_THREAD_SAFETY_ANALYSIS ;
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void noanal_fun_params ( int lvar NO_THREAD_SAFETY_ANALYSIS ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2011-07-29 01:21:07 +08:00
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Guarded Var Attribute (gv)
//-----------------------------------------//
2011-07-29 01:21:07 +08:00
# if !__has_attribute(guarded_var)
# error "Should support guarded_var attribute"
# endif
2012-04-24 04:41:57 +08:00
int gv_var_noargs GUARDED_VAR ;
2011-07-29 01:21:07 +08:00
int gv_var_args __attribute__ ( ( guarded_var ( 1 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
class GVFoo {
private :
2012-04-24 04:41:57 +08:00
int gv_field_noargs GUARDED_VAR ;
2011-07-29 01:21:07 +08:00
int gv_field_args __attribute__ ( ( guarded_var ( 1 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
class GUARDED_VAR GV { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void gv_function ( ) GUARDED_VAR ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
2012-04-24 04:41:57 +08:00
void gv_function_params ( int gv_lvar GUARDED_VAR ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
int gv_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x GUARDED_VAR = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
return x ;
}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Pt Guarded Var Attribute (pgv)
//-----------------------------------------//
2011-07-29 01:21:07 +08:00
//FIXME: add support for boost::scoped_ptr<int> fancyptr and references
# if !__has_attribute(pt_guarded_var)
# error "Should support pt_guarded_var attribute"
# endif
2012-04-24 04:41:57 +08:00
int * pgv_pt_var_noargs PT_GUARDED_VAR ;
2011-07-29 01:21:07 +08:00
2012-04-24 04:41:57 +08:00
int pgv_var_noargs PT_GUARDED_VAR ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
2011-07-29 01:21:07 +08:00
class PGVFoo {
private :
2012-04-24 04:41:57 +08:00
int * pt_field_noargs PT_GUARDED_VAR ;
int field_noargs PT_GUARDED_VAR ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
2011-07-29 01:21:07 +08:00
int * gv_field_args __attribute__ ( ( pt_guarded_var ( 1 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
class PT_GUARDED_VAR PGV { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
} ;
int * pgv_var_args __attribute__ ( ( pt_guarded_var ( 1 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
2012-04-24 04:41:57 +08:00
void pgv_function ( ) PT_GUARDED_VAR ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
2012-04-24 04:41:57 +08:00
void pgv_function_params ( int * gv_lvar PT_GUARDED_VAR ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
void pgv_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int * x PT_GUARDED_VAR = new int ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
2011-07-29 01:21:07 +08:00
delete x ;
}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Lockable Attribute (l)
//-----------------------------------------//
2011-07-29 01:21:07 +08:00
//FIXME: In future we may want to add support for structs, ObjC classes, etc.
# if !__has_attribute(lockable)
# error "Should support lockable attribute"
# endif
2012-04-24 04:41:57 +08:00
class LOCKABLE LTestClass {
2011-07-29 01:21:07 +08:00
} ;
class __attribute__ ( ( lockable ( 1 ) ) ) LTestClass_args { / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void l_test_function ( ) LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
int l_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x LOCKABLE = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
return x ;
}
2012-04-24 04:41:57 +08:00
int l_test_var LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
class LFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2012-04-24 04:41:57 +08:00
void test_method ( ) LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void l_function_params ( int lvar LOCKABLE ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Scoped Lockable Attribute (sl)
//-----------------------------------------//
2011-07-29 01:21:07 +08:00
# if !__has_attribute(scoped_lockable)
# error "Should support scoped_lockable attribute"
# endif
2012-04-24 04:41:57 +08:00
class SCOPED_LOCKABLE SLTestClass {
2011-07-29 01:21:07 +08:00
} ;
class __attribute__ ( ( scoped_lockable ( 1 ) ) ) SLTestClass_args { / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes no arguments}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void sl_test_function ( ) SCOPED_LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
int sl_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x SCOPED_LOCKABLE = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
return x ;
}
2012-04-24 04:41:57 +08:00
int sl_test_var SCOPED_LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
class SLFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field SCOPED_LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2012-04-24 04:41:57 +08:00
void test_method ( ) SCOPED_LOCKABLE ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2011-07-29 01:21:07 +08:00
} ;
2012-04-24 04:41:57 +08:00
void sl_function_params ( int lvar SCOPED_LOCKABLE ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Guarded By Attribute (gb)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
// FIXME: Eventually, would we like this attribute to take more than 1 arg?
2011-07-29 04:12:35 +08:00
# if !__has_attribute(guarded_by)
# error "Should support guarded_by attribute"
# endif
//1. Check applied to the right types & argument number
2012-04-24 04:41:57 +08:00
int gb_var_arg GUARDED_BY ( mu1 ) ;
2011-07-29 04:12:35 +08:00
int gb_var_args __attribute__ ( ( guarded_by ( mu1 , mu2 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
int gb_var_noargs __attribute__ ( ( guarded_by ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
class GBFoo {
private :
int gb_field_noargs __attribute__ ( ( guarded_by ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2012-04-24 04:41:57 +08:00
int gb_field_args GUARDED_BY ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class GUARDED_BY ( mu1 ) GB { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void gb_function ( ) GUARDED_BY ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void gb_function_params ( int gv_lvar GUARDED_BY ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
int gb_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x GUARDED_BY ( mu1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
return x ;
}
2011-08-10 01:59:31 +08:00
//2. Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int gb_var_arg_1 GUARDED_BY ( muWrapper . mu ) ;
int gb_var_arg_2 GUARDED_BY ( muDoubleWrapper . muWrapper - > mu ) ;
int gb_var_arg_3 GUARDED_BY ( muWrapper . getMu ( ) ) ;
int gb_var_arg_4 GUARDED_BY ( * muWrapper . getMuPointer ( ) ) ;
int gb_var_arg_5 GUARDED_BY ( & mu1 ) ;
int gb_var_arg_6 GUARDED_BY ( muRef ) ;
int gb_var_arg_7 GUARDED_BY ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int gb_var_arg_8 GUARDED_BY ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int gb_var_arg_bad_1 GUARDED_BY ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
2012-04-24 04:41:57 +08:00
int gb_var_arg_bad_2 GUARDED_BY ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int gb_var_arg_bad_3 GUARDED_BY ( muDoublePointer ) ; / / \
// expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
int gb_var_arg_bad_4 GUARDED_BY ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
2011-07-29 04:12:35 +08:00
//3.
// Thread Safety analysis tests
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Pt Guarded By Attribute (pgb)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(pt_guarded_by)
# error "Should support pt_guarded_by attribute"
# endif
//1. Check applied to the right types & argument number
int * pgb_var_noargs __attribute__ ( ( pt_guarded_by ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int * pgb_ptr_var_arg PT_GUARDED_BY ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int * pgb_ptr_var_args __attribute__ ( ( pt_guarded_by ( mu1 , mu2 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int pgb_var_args PT_GUARDED_BY ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
2011-07-29 04:12:35 +08:00
class PGBFoo {
private :
int * pgb_field_noargs __attribute__ ( ( pt_guarded_by ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2012-04-24 04:41:57 +08:00
int * pgb_field_args PT_GUARDED_BY ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class PT_GUARDED_BY ( mu1 ) PGB { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void pgb_function ( ) PT_GUARDED_BY ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void pgb_function_params ( int gv_lvar PT_GUARDED_BY ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
void pgb_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int * x PT_GUARDED_BY ( mu1 ) = new int ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
delete x ;
}
2011-08-10 01:59:31 +08:00
//2. Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int * pgb_var_arg_1 PT_GUARDED_BY ( muWrapper . mu ) ;
int * pgb_var_arg_2 PT_GUARDED_BY ( muDoubleWrapper . muWrapper - > mu ) ;
int * pgb_var_arg_3 PT_GUARDED_BY ( muWrapper . getMu ( ) ) ;
int * pgb_var_arg_4 PT_GUARDED_BY ( * muWrapper . getMuPointer ( ) ) ;
int * pgb_var_arg_5 PT_GUARDED_BY ( & mu1 ) ;
int * pgb_var_arg_6 PT_GUARDED_BY ( muRef ) ;
int * pgb_var_arg_7 PT_GUARDED_BY ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int * pgb_var_arg_8 PT_GUARDED_BY ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int * pgb_var_arg_bad_1 PT_GUARDED_BY ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int * pgb_var_arg_bad_2 PT_GUARDED_BY ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int * pgb_var_arg_bad_3 PT_GUARDED_BY ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int * pgb_var_arg_bad_4 PT_GUARDED_BY ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Acquired After (aa)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
// FIXME: Would we like this attribute to take more than 1 arg?
# if !__has_attribute(acquired_after)
# error "Should support acquired_after attribute"
# endif
2012-04-24 04:41:57 +08:00
Mutex mu_aa ACQUIRED_AFTER ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
Mutex aa_var_noargs __attribute__ ( ( acquired_after ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
class AAFoo {
private :
2012-04-24 04:41:57 +08:00
Mutex aa_field_noargs __attribute__ ( ( acquired_after ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2012-04-24 04:41:57 +08:00
Mutex aa_field_args ACQUIRED_AFTER ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class ACQUIRED_AFTER ( mu1 ) AA { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void aa_function ( ) ACQUIRED_AFTER ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void aa_function_params ( int gv_lvar ACQUIRED_AFTER ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
void aa_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
Mutex x ACQUIRED_AFTER ( mu1 ) = Mutex ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
}
2011-08-10 01:59:31 +08:00
//Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
Mutex aa_var_arg_1 ACQUIRED_AFTER ( muWrapper . mu ) ;
Mutex aa_var_arg_2 ACQUIRED_AFTER ( muDoubleWrapper . muWrapper - > mu ) ;
Mutex aa_var_arg_3 ACQUIRED_AFTER ( muWrapper . getMu ( ) ) ;
Mutex aa_var_arg_4 ACQUIRED_AFTER ( * muWrapper . getMuPointer ( ) ) ;
Mutex aa_var_arg_5 ACQUIRED_AFTER ( & mu1 ) ;
Mutex aa_var_arg_6 ACQUIRED_AFTER ( muRef ) ;
Mutex aa_var_arg_7 ACQUIRED_AFTER ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
Mutex aa_var_arg_8 ACQUIRED_AFTER ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
Mutex aa_var_arg_bad_1 ACQUIRED_AFTER ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
Mutex aa_var_arg_bad_2 ACQUIRED_AFTER ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
Mutex aa_var_arg_bad_3 ACQUIRED_AFTER ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
Mutex aa_var_arg_bad_4 ACQUIRED_AFTER ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2012-04-24 04:41:57 +08:00
UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER ( mu_aa ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Acquired Before (ab)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(acquired_before)
# error "Should support acquired_before attribute"
# endif
2012-04-24 04:41:57 +08:00
Mutex mu_ab ACQUIRED_BEFORE ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
Mutex ab_var_noargs __attribute__ ( ( acquired_before ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
class ABFoo {
private :
2012-04-24 04:41:57 +08:00
Mutex ab_field_noargs __attribute__ ( ( acquired_before ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2012-04-24 04:41:57 +08:00
Mutex ab_field_args ACQUIRED_BEFORE ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class ACQUIRED_BEFORE ( mu1 ) AB { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void ab_function ( ) ACQUIRED_BEFORE ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void ab_function_params ( int gv_lvar ACQUIRED_BEFORE ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
void ab_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
Mutex x ACQUIRED_BEFORE ( mu1 ) = Mutex ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
2011-07-29 04:12:35 +08:00
}
2012-04-24 04:41:57 +08:00
// Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will
2011-07-29 04:12:35 +08:00
// be taken care of by warnings that ab__int is not lockable.
2011-08-10 01:59:31 +08:00
//Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
Mutex ab_var_arg_1 ACQUIRED_BEFORE ( muWrapper . mu ) ;
Mutex ab_var_arg_2 ACQUIRED_BEFORE ( muDoubleWrapper . muWrapper - > mu ) ;
Mutex ab_var_arg_3 ACQUIRED_BEFORE ( muWrapper . getMu ( ) ) ;
Mutex ab_var_arg_4 ACQUIRED_BEFORE ( * muWrapper . getMuPointer ( ) ) ;
Mutex ab_var_arg_5 ACQUIRED_BEFORE ( & mu1 ) ;
Mutex ab_var_arg_6 ACQUIRED_BEFORE ( muRef ) ;
Mutex ab_var_arg_7 ACQUIRED_BEFORE ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
Mutex ab_var_arg_8 ACQUIRED_BEFORE ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2012-04-24 04:41:57 +08:00
UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE ( mu_ab ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Exclusive Lock Function (elf)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(exclusive_lock_function)
# error "Should support exclusive_lock_function attribute"
# endif
// takes zero or more arguments, all locks (vars/fields)
2012-04-24 04:41:57 +08:00
void elf_function ( ) EXCLUSIVE_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void elf_function_args ( ) EXCLUSIVE_LOCK_FUNCTION ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int elf_testfn ( int y ) EXCLUSIVE_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
int elf_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x EXCLUSIVE_LOCK_FUNCTION ( ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int elf_test_var EXCLUSIVE_LOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class ElfFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field EXCLUSIVE_LOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) EXCLUSIVE_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class EXCLUSIVE_LOCK_FUNCTION ( ) ElfTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void elf_fun_params ( int lvar EXCLUSIVE_LOCK_FUNCTION ( ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int elf_function_1 ( ) EXCLUSIVE_LOCK_FUNCTION ( muWrapper . mu ) ;
int elf_function_2 ( ) EXCLUSIVE_LOCK_FUNCTION ( muDoubleWrapper . muWrapper - > mu ) ;
int elf_function_3 ( ) EXCLUSIVE_LOCK_FUNCTION ( muWrapper . getMu ( ) ) ;
int elf_function_4 ( ) EXCLUSIVE_LOCK_FUNCTION ( * muWrapper . getMuPointer ( ) ) ;
int elf_function_5 ( ) EXCLUSIVE_LOCK_FUNCTION ( & mu1 ) ;
int elf_function_6 ( ) EXCLUSIVE_LOCK_FUNCTION ( muRef ) ;
int elf_function_7 ( ) EXCLUSIVE_LOCK_FUNCTION ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int elf_function_8 ( ) EXCLUSIVE_LOCK_FUNCTION ( muPointer ) ;
int elf_function_9 ( Mutex x ) EXCLUSIVE_LOCK_FUNCTION ( 1 ) ;
int elf_function_9 ( Mutex x , Mutex y ) EXCLUSIVE_LOCK_FUNCTION ( 1 , 2 ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int elf_function_bad_2 ( ) EXCLUSIVE_LOCK_FUNCTION ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int elf_function_bad_3 ( ) EXCLUSIVE_LOCK_FUNCTION ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int elf_function_bad_4 ( ) EXCLUSIVE_LOCK_FUNCTION ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
2012-04-24 04:41:57 +08:00
int elf_function_bad_1 ( ) EXCLUSIVE_LOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2012-04-24 04:41:57 +08:00
int elf_function_bad_5 ( Mutex x ) EXCLUSIVE_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
2012-04-24 04:41:57 +08:00
int elf_function_bad_6 ( Mutex x , Mutex y ) EXCLUSIVE_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
2012-04-24 04:41:57 +08:00
int elf_function_bad_7 ( ) EXCLUSIVE_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Shared Lock Function (slf)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(shared_lock_function)
# error "Should support shared_lock_function attribute"
# endif
// takes zero or more arguments, all locks (vars/fields)
2012-04-24 04:41:57 +08:00
void slf_function ( ) SHARED_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void slf_function_args ( ) SHARED_LOCK_FUNCTION ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int slf_testfn ( int y ) SHARED_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
int slf_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x SHARED_LOCK_FUNCTION ( ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int slf_test_var SHARED_LOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void slf_fun_params ( int lvar SHARED_LOCK_FUNCTION ( ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class SlfFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field SHARED_LOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) SHARED_LOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class SHARED_LOCK_FUNCTION ( ) SlfTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int slf_function_1 ( ) SHARED_LOCK_FUNCTION ( muWrapper . mu ) ;
int slf_function_2 ( ) SHARED_LOCK_FUNCTION ( muDoubleWrapper . muWrapper - > mu ) ;
int slf_function_3 ( ) SHARED_LOCK_FUNCTION ( muWrapper . getMu ( ) ) ;
int slf_function_4 ( ) SHARED_LOCK_FUNCTION ( * muWrapper . getMuPointer ( ) ) ;
int slf_function_5 ( ) SHARED_LOCK_FUNCTION ( & mu1 ) ;
int slf_function_6 ( ) SHARED_LOCK_FUNCTION ( muRef ) ;
int slf_function_7 ( ) SHARED_LOCK_FUNCTION ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int slf_function_8 ( ) SHARED_LOCK_FUNCTION ( muPointer ) ;
int slf_function_9 ( Mutex x ) SHARED_LOCK_FUNCTION ( 1 ) ;
int slf_function_9 ( Mutex x , Mutex y ) SHARED_LOCK_FUNCTION ( 1 , 2 ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int slf_function_bad_2 ( ) SHARED_LOCK_FUNCTION ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int slf_function_bad_3 ( ) SHARED_LOCK_FUNCTION ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int slf_function_bad_4 ( ) SHARED_LOCK_FUNCTION ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
2012-04-24 04:41:57 +08:00
int slf_function_bad_1 ( ) SHARED_LOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2012-04-24 04:41:57 +08:00
int slf_function_bad_5 ( Mutex x ) SHARED_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
2012-04-24 04:41:57 +08:00
int slf_function_bad_6 ( Mutex x , Mutex y ) SHARED_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
2012-04-24 04:41:57 +08:00
int slf_function_bad_7 ( ) SHARED_LOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Exclusive TryLock Function (etf)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(exclusive_trylock_function)
# error "Should support exclusive_trylock_function attribute"
# endif
// takes a mandatory boolean or integer argument specifying the retval
// plus an optional list of locks (vars/fields)
void etf_function ( ) __attribute__ ( ( exclusive_trylock_function ) ) ; / / \
2011-12-15 08:38:15 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void etf_function_args ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void etf_function_arg ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int etf_testfn ( int y ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
int etf_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class EtfFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) EtfTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void etf_fun_params ( int lvar EXCLUSIVE_TRYLOCK_FUNCTION ( 1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int etf_function_1 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muWrapper . mu ) ;
int etf_function_2 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muDoubleWrapper . muWrapper - > mu ) ;
int etf_function_3 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muWrapper . getMu ( ) ) ;
int etf_function_4 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , * muWrapper . getMuPointer ( ) ) ;
int etf_function_5 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , & mu1 ) ;
int etf_function_6 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muRef ) ;
int etf_function_7 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int etf_functetfn_8 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muPointer ) ;
int etf_function_9 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( true ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int etf_function_bad_1 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
2012-04-24 04:41:57 +08:00
int etf_function_bad_2 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( " mu " ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
2012-04-24 04:41:57 +08:00
int etf_function_bad_3 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( muDoublePointer ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int etf_function_bad_4 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int etf_function_bad_5 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int etf_function_bad_6 ( ) EXCLUSIVE_TRYLOCK_FUNCTION ( 1 , umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Shared TryLock Function (stf)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(shared_trylock_function)
# error "Should support shared_trylock_function attribute"
# endif
// takes a mandatory boolean or integer argument specifying the retval
// plus an optional list of locks (vars/fields)
void stf_function ( ) __attribute__ ( ( shared_trylock_function ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void stf_function_args ( ) SHARED_TRYLOCK_FUNCTION ( 1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void stf_function_arg ( ) SHARED_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int stf_testfn ( int y ) SHARED_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
int stf_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x SHARED_TRYLOCK_FUNCTION ( 1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int stf_test_var SHARED_TRYLOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void stf_fun_params ( int lvar SHARED_TRYLOCK_FUNCTION ( 1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class StfFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field SHARED_TRYLOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) SHARED_TRYLOCK_FUNCTION ( 1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class SHARED_TRYLOCK_FUNCTION ( 1 ) StfTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int stf_function_1 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muWrapper . mu ) ;
int stf_function_2 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muDoubleWrapper . muWrapper - > mu ) ;
int stf_function_3 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muWrapper . getMu ( ) ) ;
int stf_function_4 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , * muWrapper . getMuPointer ( ) ) ;
int stf_function_5 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , & mu1 ) ;
int stf_function_6 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muRef ) ;
int stf_function_7 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int stf_function_8 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muPointer ) ;
int stf_function_9 ( ) SHARED_TRYLOCK_FUNCTION ( true ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int stf_function_bad_1 ( ) SHARED_TRYLOCK_FUNCTION ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
2012-04-24 04:41:57 +08:00
int stf_function_bad_2 ( ) SHARED_TRYLOCK_FUNCTION ( " mu " ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
2012-04-24 04:41:57 +08:00
int stf_function_bad_3 ( ) SHARED_TRYLOCK_FUNCTION ( muDoublePointer ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int stf_function_bad_4 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int stf_function_bad_5 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int stf_function_bad_6 ( ) SHARED_TRYLOCK_FUNCTION ( 1 , umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Unlock Function (uf)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(unlock_function)
# error "Should support unlock_function attribute"
# endif
// takes zero or more arguments, all locks (vars/fields)
2012-04-24 04:41:57 +08:00
void uf_function ( ) UNLOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void uf_function_args ( ) UNLOCK_FUNCTION ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int uf_testfn ( int y ) UNLOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
int uf_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x UNLOCK_FUNCTION ( ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int uf_test_var UNLOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class UfFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field UNLOCK_FUNCTION ( ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) UNLOCK_FUNCTION ( ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class NO_THREAD_SAFETY_ANALYSIS UfTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
void uf_fun_params ( int lvar UNLOCK_FUNCTION ( ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int uf_function_1 ( ) UNLOCK_FUNCTION ( muWrapper . mu ) ;
int uf_function_2 ( ) UNLOCK_FUNCTION ( muDoubleWrapper . muWrapper - > mu ) ;
int uf_function_3 ( ) UNLOCK_FUNCTION ( muWrapper . getMu ( ) ) ;
int uf_function_4 ( ) UNLOCK_FUNCTION ( * muWrapper . getMuPointer ( ) ) ;
int uf_function_5 ( ) UNLOCK_FUNCTION ( & mu1 ) ;
int uf_function_6 ( ) UNLOCK_FUNCTION ( muRef ) ;
int uf_function_7 ( ) UNLOCK_FUNCTION ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int uf_function_8 ( ) UNLOCK_FUNCTION ( muPointer ) ;
int uf_function_9 ( Mutex x ) UNLOCK_FUNCTION ( 1 ) ;
int uf_function_9 ( Mutex x , Mutex y ) UNLOCK_FUNCTION ( 1 , 2 ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int uf_function_bad_2 ( ) UNLOCK_FUNCTION ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int uf_function_bad_3 ( ) UNLOCK_FUNCTION ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int uf_function_bad_4 ( ) UNLOCK_FUNCTION ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
2012-04-24 04:41:57 +08:00
int uf_function_bad_1 ( ) UNLOCK_FUNCTION ( 1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2012-04-24 04:41:57 +08:00
int uf_function_bad_5 ( Mutex x ) UNLOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
2012-04-24 04:41:57 +08:00
int uf_function_bad_6 ( Mutex x , Mutex y ) UNLOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
2012-04-24 04:41:57 +08:00
int uf_function_bad_7 ( ) UNLOCK_FUNCTION ( 0 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Lock Returned (lr)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(lock_returned)
# error "Should support lock_returned attribute"
# endif
// Takes exactly one argument, a var/field
void lr_function ( ) __attribute__ ( ( lock_returned ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void lr_function_arg ( ) LOCK_RETURNED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
void lr_function_args ( ) __attribute__ ( ( lock_returned ( mu1 , mu2 ) ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes one argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int lr_testfn ( int y ) LOCK_RETURNED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
int lr_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x LOCK_RETURNED ( mu1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int lr_test_var LOCK_RETURNED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void lr_fun_params ( int lvar LOCK_RETURNED ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class LrFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field LOCK_RETURNED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) LOCK_RETURNED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class LOCK_RETURNED ( mu1 ) LrTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int lr_function_1 ( ) LOCK_RETURNED ( muWrapper . mu ) ;
int lr_function_2 ( ) LOCK_RETURNED ( muDoubleWrapper . muWrapper - > mu ) ;
int lr_function_3 ( ) LOCK_RETURNED ( muWrapper . getMu ( ) ) ;
int lr_function_4 ( ) LOCK_RETURNED ( * muWrapper . getMuPointer ( ) ) ;
int lr_function_5 ( ) LOCK_RETURNED ( & mu1 ) ;
int lr_function_6 ( ) LOCK_RETURNED ( muRef ) ;
int lr_function_7 ( ) LOCK_RETURNED ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int lr_function_8 ( ) LOCK_RETURNED ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int lr_function_bad_1 ( ) LOCK_RETURNED ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int lr_function_bad_2 ( ) LOCK_RETURNED ( " mu " ) ; / / \
2012-05-03 01:38:37 +08:00
// expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int lr_function_bad_3 ( ) LOCK_RETURNED ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int lr_function_bad_4 ( ) LOCK_RETURNED ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Locks Excluded (le)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(locks_excluded)
# error "Should support locks_excluded attribute"
# endif
// takes one or more arguments, all locks (vars/fields)
void le_function ( ) __attribute__ ( ( locks_excluded ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void le_function_arg ( ) LOCKS_EXCLUDED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void le_function_args ( ) LOCKS_EXCLUDED ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int le_testfn ( int y ) LOCKS_EXCLUDED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
int le_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x LOCKS_EXCLUDED ( mu1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int le_test_var LOCKS_EXCLUDED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void le_fun_params ( int lvar LOCKS_EXCLUDED ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class LeFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field LOCKS_EXCLUDED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) LOCKS_EXCLUDED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class LOCKS_EXCLUDED ( mu1 ) LeTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int le_function_1 ( ) LOCKS_EXCLUDED ( muWrapper . mu ) ;
int le_function_2 ( ) LOCKS_EXCLUDED ( muDoubleWrapper . muWrapper - > mu ) ;
int le_function_3 ( ) LOCKS_EXCLUDED ( muWrapper . getMu ( ) ) ;
int le_function_4 ( ) LOCKS_EXCLUDED ( * muWrapper . getMuPointer ( ) ) ;
int le_function_5 ( ) LOCKS_EXCLUDED ( & mu1 ) ;
int le_function_6 ( ) LOCKS_EXCLUDED ( muRef ) ;
int le_function_7 ( ) LOCKS_EXCLUDED ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int le_function_8 ( ) LOCKS_EXCLUDED ( muPointer ) ;
2011-07-29 04:12:35 +08:00
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int le_function_bad_1 ( ) LOCKS_EXCLUDED ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int le_function_bad_2 ( ) LOCKS_EXCLUDED ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int le_function_bad_3 ( ) LOCKS_EXCLUDED ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int le_function_bad_4 ( ) LOCKS_EXCLUDED ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Exclusive Locks Required (elr)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(exclusive_locks_required)
# error "Should support exclusive_locks_required attribute"
# endif
// takes one or more arguments, all locks (vars/fields)
void elr_function ( ) __attribute__ ( ( exclusive_locks_required ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void elr_function_arg ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void elr_function_args ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int elr_testfn ( int y ) EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
int elr_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int elr_test_var EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void elr_fun_params ( int lvar EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class ElrFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class EXCLUSIVE_LOCKS_REQUIRED ( mu1 ) ElrTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int elr_function_1 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muWrapper . mu ) ;
int elr_function_2 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muDoubleWrapper . muWrapper - > mu ) ;
int elr_function_3 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muWrapper . getMu ( ) ) ;
int elr_function_4 ( ) EXCLUSIVE_LOCKS_REQUIRED ( * muWrapper . getMuPointer ( ) ) ;
int elr_function_5 ( ) EXCLUSIVE_LOCKS_REQUIRED ( & mu1 ) ;
int elr_function_6 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muRef ) ;
int elr_function_7 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int elr_function_8 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int elr_function_bad_1 ( ) EXCLUSIVE_LOCKS_REQUIRED ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int elr_function_bad_2 ( ) EXCLUSIVE_LOCKS_REQUIRED ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int elr_function_bad_3 ( ) EXCLUSIVE_LOCKS_REQUIRED ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int elr_function_bad_4 ( ) EXCLUSIVE_LOCKS_REQUIRED ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
//-----------------------------------------//
// Shared Locks Required (slr)
//-----------------------------------------//
2011-07-29 04:12:35 +08:00
# if !__has_attribute(shared_locks_required)
# error "Should support shared_locks_required attribute"
# endif
// takes one or more arguments, all locks (vars/fields)
void slr_function ( ) __attribute__ ( ( shared_locks_required ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-error {{attribute takes at least 1 argument}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void slr_function_arg ( ) SHARED_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void slr_function_args ( ) SHARED_LOCKS_REQUIRED ( mu1 , mu2 ) ;
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
int slr_testfn ( int y ) SHARED_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
int slr_testfn ( int y ) {
2012-04-24 04:41:57 +08:00
int x SHARED_LOCKS_REQUIRED ( mu1 ) = y ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
return x ;
} ;
2012-04-24 04:41:57 +08:00
int slr_test_var SHARED_LOCKS_REQUIRED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
2012-04-24 04:41:57 +08:00
void slr_fun_params ( int lvar SHARED_LOCKS_REQUIRED ( mu1 ) ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
class SlrFoo {
private :
2012-04-24 04:41:57 +08:00
int test_field SHARED_LOCKS_REQUIRED ( mu1 ) ; / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
2012-04-24 04:41:57 +08:00
void test_method ( ) SHARED_LOCKS_REQUIRED ( mu1 ) ;
2011-07-29 04:12:35 +08:00
} ;
2012-04-24 04:41:57 +08:00
class SHARED_LOCKS_REQUIRED ( mu1 ) SlrTestClass { / / \
2011-09-09 02:07:26 +08:00
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
2011-07-29 04:12:35 +08:00
} ;
2011-08-10 01:59:31 +08:00
// Check argument parsing.
// legal attribute arguments
2012-04-24 04:41:57 +08:00
int slr_function_1 ( ) SHARED_LOCKS_REQUIRED ( muWrapper . mu ) ;
int slr_function_2 ( ) SHARED_LOCKS_REQUIRED ( muDoubleWrapper . muWrapper - > mu ) ;
int slr_function_3 ( ) SHARED_LOCKS_REQUIRED ( muWrapper . getMu ( ) ) ;
int slr_function_4 ( ) SHARED_LOCKS_REQUIRED ( * muWrapper . getMuPointer ( ) ) ;
int slr_function_5 ( ) SHARED_LOCKS_REQUIRED ( & mu1 ) ;
int slr_function_6 ( ) SHARED_LOCKS_REQUIRED ( muRef ) ;
int slr_function_7 ( ) SHARED_LOCKS_REQUIRED ( muDoubleWrapper . getWrapper ( ) - > getMu ( ) ) ;
int slr_function_8 ( ) SHARED_LOCKS_REQUIRED ( muPointer ) ;
2011-08-10 01:59:31 +08:00
// illegal attribute arguments
2012-04-24 04:41:57 +08:00
int slr_function_bad_1 ( ) SHARED_LOCKS_REQUIRED ( 1 ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int slr_function_bad_2 ( ) SHARED_LOCKS_REQUIRED ( " mu " ) ; / / \
2012-04-20 00:10:44 +08:00
// expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
2012-04-24 04:41:57 +08:00
int slr_function_bad_3 ( ) SHARED_LOCKS_REQUIRED ( muDoublePointer ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
2012-04-24 04:41:57 +08:00
int slr_function_bad_4 ( ) SHARED_LOCKS_REQUIRED ( umu ) ; / / \
2012-04-07 04:02:30 +08:00
// expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
2011-08-10 01:59:31 +08:00
2011-08-30 01:12:27 +08:00
//-----------------------------------------//
// Regression tests for unusual cases.
//-----------------------------------------//
int trivially_false_edges ( bool b ) {
// Create NULL (never taken) edges in CFG
if ( false ) return 1 ;
else return 2 ;
}
// Possible Clang bug -- method pointer in template parameter
class UnFoo {
public :
void foo ( ) ;
} ;
template < void ( UnFoo : : * methptr ) ( ) >
class MCaller {
public :
static void call_method_ptr ( UnFoo * f ) {
// FIXME: Possible Clang bug:
// getCalleeDecl() returns NULL in the following case:
( f - > * methptr ) ( ) ;
}
} ;
void call_method_ptr_inst ( UnFoo * f ) {
MCaller < & UnFoo : : foo > : : call_method_ptr ( f ) ;
}
int temp ;
void empty_back_edge ( ) {
// Create a back edge to a block with with no statements
for ( ; ; ) {
+ + temp ;
if ( temp > 10 ) break ;
}
}
struct Foomger {
void operator + + ( ) ;
} ;
struct Foomgoper {
Foomger f ;
bool done ( ) ;
void invalid_back_edge ( ) {
do {
// FIXME: Possible Clang bug:
// The first statement in this basic block has no source location
+ + f ;
} while ( ! done ( ) ) ;
}
} ;
2011-09-09 01:42:31 +08:00
//-----------------------------------------------------
// Parsing of member variables and function parameters
//------------------------------------------------------
2012-04-24 04:41:57 +08:00
Mutex gmu ;
2011-09-09 01:42:31 +08:00
class StaticMu {
2012-04-24 04:41:57 +08:00
static Mutex statmu ;
2011-09-09 01:42:31 +08:00
} ;
class FooLate {
public :
2012-04-24 04:41:57 +08:00
void foo1 ( ) EXCLUSIVE_LOCKS_REQUIRED ( gmu ) { }
void foo2 ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu ) { }
void foo3 ( Mutex * m ) EXCLUSIVE_LOCKS_REQUIRED ( m ) { }
void foo3 ( FooLate * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > mu ) { }
void foo4 ( FooLate * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > mu ) ;
2011-09-09 01:42:31 +08:00
2012-04-24 04:41:57 +08:00
static void foo5 ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu ) ; / / \
2012-08-21 05:32:18 +08:00
// expected-error {{invalid use of member 'mu' in static member function}}
2011-09-09 01:42:31 +08:00
template < class T >
2012-04-24 04:41:57 +08:00
void foo6 ( ) EXCLUSIVE_LOCKS_REQUIRED ( T : : statmu ) { }
2011-09-09 01:42:31 +08:00
template < class T >
2012-04-24 04:41:57 +08:00
void foo7 ( T * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > mu ) { }
2011-09-09 01:42:31 +08:00
2012-04-24 04:41:57 +08:00
int a GUARDED_BY ( gmu ) ;
int b GUARDED_BY ( mu ) ;
int c GUARDED_BY ( this - > mu ) ;
2011-09-09 01:42:31 +08:00
2012-04-24 04:41:57 +08:00
Mutex mu ;
2011-09-09 01:42:31 +08:00
} ;
2011-12-15 03:36:06 +08:00
//-------------------------
// Empty argument lists
//-------------------------
2012-04-24 04:41:57 +08:00
class LOCKABLE EmptyArgListsTest {
void lock ( ) EXCLUSIVE_LOCK_FUNCTION ( ) { }
void unlock ( ) UNLOCK_FUNCTION ( ) { }
2011-12-15 03:36:06 +08:00
} ;
2012-02-17 00:50:43 +08:00
namespace FunctionDefinitionParseTest {
// Test parsing of attributes on function definitions.
class Foo {
public :
2012-04-24 04:41:57 +08:00
Mutex mu_ ;
2012-02-17 00:50:43 +08:00
void foo1 ( ) ;
void foo2 ( Foo * f ) ;
} ;
template < class T >
class Bar {
public :
2012-04-24 04:41:57 +08:00
Mutex mu_ ;
2012-02-17 00:50:43 +08:00
void bar ( ) ;
} ;
2012-04-24 04:41:57 +08:00
void Foo : : foo1 ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu_ ) { }
void Foo : : foo2 ( Foo * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > mu_ ) { }
2012-02-17 00:50:43 +08:00
template < class T >
2012-04-24 04:41:57 +08:00
void Bar < T > : : bar ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu_ ) { }
2012-02-17 00:50:43 +08:00
2012-04-24 04:41:57 +08:00
void baz ( Foo * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > mu_ ) { }
2012-03-03 06:12:59 +08:00
} // end namespace
namespace TestMultiDecl {
class Foo {
public :
2012-04-24 04:41:57 +08:00
int GUARDED_BY ( mu_ ) a ;
int GUARDED_BY ( mu_ ) b , c ;
2012-03-03 06:12:59 +08:00
private :
2012-04-24 04:41:57 +08:00
Mutex mu_ ;
2012-02-17 00:50:43 +08:00
} ;
2012-05-05 00:28:38 +08:00
} // end namespace TestMultiDecl
2012-03-03 06:12:59 +08:00
2012-04-06 23:10:17 +08:00
namespace NestedClassLateDecl {
class Foo {
class Bar {
int a GUARDED_BY ( mu ) ;
int b GUARDED_BY ( fooMuStatic ) ;
void bar ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu ) { a = 0 ; }
void bar2 ( Bar * b ) EXCLUSIVE_LOCKS_REQUIRED ( b - > mu ) { b - > a = 0 ; }
void bar3 ( Foo * f ) EXCLUSIVE_LOCKS_REQUIRED ( f - > fooMu ) { f - > a = 0 ; }
2012-04-24 04:41:57 +08:00
Mutex mu ;
2012-04-06 23:10:17 +08:00
} ;
int a GUARDED_BY ( fooMu ) ;
2012-04-24 04:41:57 +08:00
Mutex fooMu ;
static Mutex fooMuStatic ;
2012-04-06 23:10:17 +08:00
} ;
}
2012-04-24 00:45:01 +08:00
namespace PointerToMemberTest {
2012-04-24 02:39:55 +08:00
// Empty string should be ignored.
int testEmptyAttribute GUARDED_BY ( " " ) ;
void testEmptyAttributeFunction ( ) EXCLUSIVE_LOCKS_REQUIRED ( " " ) ;
2012-04-24 00:45:01 +08:00
class Graph {
public :
2012-04-24 04:41:57 +08:00
Mutex mu_ ;
2012-05-03 01:38:37 +08:00
static Mutex * get_static_mu ( ) LOCK_RETURNED ( & Graph : : mu_ ) ;
2012-04-24 00:45:01 +08:00
} ;
class Node {
public :
void foo ( ) EXCLUSIVE_LOCKS_REQUIRED ( & Graph : : mu_ ) ;
int a GUARDED_BY ( & Graph : : mu_ ) ;
} ;
}
2012-04-24 02:39:55 +08:00
namespace SmartPointerTest {
template < class T >
class smart_ptr {
public :
T * operator - > ( ) { return ptr_ ; }
T & operator * ( ) { return ptr_ ; }
private :
T * ptr_ ;
} ;
2012-05-03 06:18:42 +08:00
Mutex gmu ;
smart_ptr < int > gdat PT_GUARDED_BY ( gmu ) ;
2012-04-24 02:39:55 +08:00
class MyClass {
public :
2012-04-24 04:41:57 +08:00
Mutex mu_ ;
2012-05-03 06:18:42 +08:00
smart_ptr < Mutex > smu_ ;
2012-04-24 02:39:55 +08:00
smart_ptr < int > a PT_GUARDED_BY ( mu_ ) ;
2012-05-03 06:18:42 +08:00
int b GUARDED_BY ( smu_ ) ;
2012-04-24 02:39:55 +08:00
} ;
}
2012-05-05 00:28:38 +08:00
namespace InheritanceTest {
class LOCKABLE Base {
public :
void lock ( ) EXCLUSIVE_LOCK_FUNCTION ( ) ;
void unlock ( ) UNLOCK_FUNCTION ( ) ;
} ;
class Base2 { } ;
class Derived1 : public Base { } ;
class Derived2 : public Base2 , public Derived1 { } ;
class Derived3 : public Base2 { } ;
class Foo {
Derived1 mu1_ ;
Derived2 mu2_ ;
Derived3 mu3_ ;
int a GUARDED_BY ( mu1_ ) ;
int b GUARDED_BY ( mu2_ ) ;
int c GUARDED_BY ( mu3_ ) ; / / \
// expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
void foo ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu1_ , mu2_ ) {
a = 0 ;
b = 0 ;
}
} ;
}
2012-08-16 06:41:04 +08:00
namespace InvalidDeclTest {
class Foo { } ;
namespace {
void Foo : : bar ( Mutex * mu ) LOCKS_EXCLUDED ( mu ) { } / / \
/ / expected - error { { cannot define or redeclare ' bar ' here because namespace ' ' does not enclose namespace ' Foo ' } } \
// expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}
}
} // end namespace InvalidDeclTest
2012-03-03 06:12:59 +08:00
2012-08-21 05:32:18 +08:00
namespace StaticScopeTest {
class FooStream ;
class Foo {
mutable Mutex mu ;
int a GUARDED_BY ( mu ) ;
static int si GUARDED_BY ( mu ) ; / / \
// expected-error {{invalid use of non-static data member 'mu'}}
static void foo ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu ) ; / / \
// expected-error {{invalid use of member 'mu' in static member function}}
friend FooStream & operator < < ( FooStream & s , const Foo & f )
EXCLUSIVE_LOCKS_REQUIRED ( mu ) ; / / \
// expected-error {{invalid use of non-static data member 'mu'}}
} ;
} // end namespace StaticScopeTest
2012-11-03 05:44:32 +08:00
namespace FunctionAttributesInsideClass_ICE_Test {
class Foo {
public :
/* Originally found when parsing foo() as an ordinary method after the
* the following :
template < class T >
void syntaxErrorMethod ( int i ) {
if ( i ) {
foo (
}
}
*/
void method ( ) {
void foo ( ) EXCLUSIVE_LOCKS_REQUIRED ( mu ) ; / / \
// expected-error {{use of undeclared identifier 'mu'}}
}
} ;
} // end namespace FunctionAttributesInsideClass_ICE_Test
2012-08-21 05:32:18 +08:00