diff options
| author | Caitlin Sadowski <supertri@google.com> | 2011-07-28 20:12:35 +0000 |
|---|---|---|
| committer | Caitlin Sadowski <supertri@google.com> | 2011-07-28 20:12:35 +0000 |
| commit | 63fa667c68740ef3430bf30876550b770254ad28 (patch) | |
| tree | 482f7fbbf921ba4054698fafdea5cacecc331f02 /clang/test/SemaCXX/warn-thread-safety.cpp | |
| parent | d7ac43eed1ec186f95edd72277494926764bb913 (diff) | |
| download | bcm5719-llvm-63fa667c68740ef3430bf30876550b770254ad28.tar.gz bcm5719-llvm-63fa667c68740ef3430bf30876550b770254ad28.zip | |
Added basic parsing for all remaining attributes, thread safety
analysis. This includes checking that the attributes are applied in the
correct contexts and with the correct number of arguments.
llvm-svn: 136383
Diffstat (limited to 'clang/test/SemaCXX/warn-thread-safety.cpp')
| -rw-r--r-- | clang/test/SemaCXX/warn-thread-safety.cpp | 575 |
1 files changed, 575 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/warn-thread-safety.cpp b/clang/test/SemaCXX/warn-thread-safety.cpp index 39a3fa2e4de..4958d2ed0fa 100644 --- a/clang/test/SemaCXX/warn-thread-safety.cpp +++ b/clang/test/SemaCXX/warn-thread-safety.cpp @@ -1,5 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s + +/** + * Helper fields + */ + +class __attribute__((lockable)) Mu { +}; + +Mu mu1; +Mu mu2; + /*********************************** * No Thread Safety Analysis (noanal) ***********************************/ @@ -202,3 +213,567 @@ class SLFoo { void sl_function_params(int lvar __attribute__((scoped_lockable))); // \ expected-warning {{'scoped_lockable' attribute only applies to classes}} + + +/*********************************** + * Guarded By Attribute (gb) + ***********************************/ + +// FIXME: Would we like this attribute to take more than 1 arg? + +#if !__has_attribute(guarded_by) +#error "Should support guarded_by attribute" +#endif + +//1. Check applied to the right types & argument number + +int gb_var_arg __attribute__((guarded_by(mu1))); + +int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \ + expected-error {{attribute takes one argument}} + +int gb_var_noargs __attribute__((guarded_by)); // \ + expected-error {{attribute takes one argument}} + +class GBFoo { + private: + int gb_field_noargs __attribute__((guarded_by)); // \ + expected-error {{attribute takes one argument}} + int gb_field_args __attribute__((guarded_by(mu1))); +}; + +class __attribute__((guarded_by(mu1))) GB { // \ + expected-warning {{'guarded_by' attribute only applies to fields and global variables}} +}; + +void gb_function() __attribute__((guarded_by(mu1))); // \ + expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + +void gb_function_params(int gv_lvar __attribute__((guarded_by(mu1)))); // \ + expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + +int gb_testfn(int y){ + int x __attribute__((guarded_by(mu1))) = y; // \ + expected-warning {{'guarded_by' attribute only applies to fields and global variables}} + return x; +} + +//2.Deal with argument parsing: +// grab token stream parsing from C++0x branch +// possibly create new, more permissive category for gcc attributes + +//foo +//foo.bar +//foo.bar->baz +//foo.bar()->baz()->a +//&foo +//*foo + +//3. +// Thread Safety analysis tests + + +/*********************************** + * Pt Guarded By Attribute (pgb) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes one argument}} + +int *pgb_ptr_var_arg __attribute__((pt_guarded_by(mu1))); + +int *pgb_ptr_var_args __attribute__((guarded_by(mu1, mu2))); // \ + expected-error {{attribute takes one argument}} + +int pgb_var_args __attribute__((pt_guarded_by(mu1))); // \ + expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}} + +class PGBFoo { + private: + int *pgb_field_noargs __attribute__((pt_guarded_by)); // \ + expected-error {{attribute takes one argument}} + int *pgb_field_args __attribute__((pt_guarded_by(mu1))); +}; + +class __attribute__((pt_guarded_by(mu1))) PGB { // \ + expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} +}; + +void pgb_function() __attribute__((pt_guarded_by(mu1))); // \ + expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + +void pgb_function_params(int gv_lvar __attribute__((pt_guarded_by(mu1)))); // \ + expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + +void pgb_testfn(int y){ + int *x __attribute__((pt_guarded_by(mu1))) = new int(0); // \ + expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}} + delete x; +} + +/*********************************** + * Acquired After (aa) + ***********************************/ + +// FIXME: Would we like this attribute to take more than 1 arg? +// FIXME: What about pointers to locks? + +#if !__has_attribute(acquired_after) +#error "Should support acquired_after attribute" +#endif + +Mu mu_aa __attribute__((acquired_after(mu1))); + +Mu aa_var_noargs __attribute__((acquired_after)); // \ + expected-error {{attribute takes at least 1 argument}} + +class AAFoo { + private: + Mu aa_field_noargs __attribute__((acquired_after)); // \ + expected-error {{attribute takes at least 1 argument}} + Mu aa_field_args __attribute__((acquired_after(mu1))); +}; + +class __attribute__((acquired_after(mu1))) AA { // \ + expected-warning {{'acquired_after' attribute only applies to fields and global variables}} +}; + +void aa_function() __attribute__((acquired_after(mu1))); // \ + expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + +void aa_function_params(int gv_lvar __attribute__((acquired_after(mu1)))); // \ + expected-warning {{'acquired_after' attribute only applies to fields and global variables}} + +void aa_testfn(int y){ + Mu x __attribute__((acquired_after(mu1))) = Mu(); // \ + expected-warning {{'acquired_after' attribute only applies to fields and global variables}} +} + +// Note: illegal int aa_int __attribute__((acquired_after(mu1))) will +// be taken care of by warnings that aa__int is not lockable. + + +/*********************************** + * Acquired Before (ab) + ***********************************/ + +#if !__has_attribute(acquired_before) +#error "Should support acquired_before attribute" +#endif + +Mu mu_ab __attribute__((acquired_before(mu1))); + +Mu ab_var_noargs __attribute__((acquired_before)); // \ + expected-error {{attribute takes at least 1 argument}} + +class ABFoo { + private: + Mu ab_field_noargs __attribute__((acquired_before)); // \ + expected-error {{attribute takes at least 1 argument}} + Mu ab_field_args __attribute__((acquired_before(mu1))); +}; + +class __attribute__((acquired_before(mu1))) AB { // \ + expected-warning {{'acquired_before' attribute only applies to fields and global variables}} +}; + +void ab_function() __attribute__((acquired_before(mu1))); // \ + expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + +void ab_function_params(int gv_lvar __attribute__((acquired_before(mu1)))); // \ + expected-warning {{'acquired_before' attribute only applies to fields and global variables}} + +void ab_testfn(int y){ + Mu x __attribute__((acquired_before(mu1))) = Mu(); // \ + expected-warning {{'acquired_before' attribute only applies to fields and global variables}} +} + +// Note: illegal int ab_int __attribute__((acquired_before(mu1))) will +// be taken care of by warnings that ab__int is not lockable. + +/*********************************** + * Exclusive Lock Function (elf) + ***********************************/ + +#if !__has_attribute(exclusive_lock_function) +#error "Should support exclusive_lock_function attribute" +#endif + +// takes zero or more arguments, all locks (vars/fields) + +void elf_function() __attribute__((exclusive_lock_function)); + +void elf_function_args() __attribute__((exclusive_lock_function(mu1, mu2))); + +int elf_testfn(int y) __attribute__((exclusive_lock_function)); + +int elf_testfn(int y) { + int x __attribute__((exclusive_lock_function)) = y; // \ + expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} + return x; +}; + +int elf_test_var __attribute__((exclusive_lock_function)); // \ + expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} + +class ElfFoo { + private: + int test_field __attribute__((exclusive_lock_function)); // \ + expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} + void test_method() __attribute__((exclusive_lock_function)); +}; + +class __attribute__((exclusive_lock_function)) ElfTestClass { // \ + expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} +}; + +void elf_fun_params(int lvar __attribute__((exclusive_lock_function))); // \ + expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}} + + + +/*********************************** + * Shared Lock Function (slf) + ***********************************/ + +#if !__has_attribute(shared_lock_function) +#error "Should support shared_lock_function attribute" +#endif + +// takes zero or more arguments, all locks (vars/fields) + +void slf_function() __attribute__((shared_lock_function)); + +void slf_function_args() __attribute__((shared_lock_function(mu1, mu2))); + +int slf_testfn(int y) __attribute__((shared_lock_function)); + +int slf_testfn(int y) { + int x __attribute__((shared_lock_function)) = y; // \ + expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} + return x; +}; + +int slf_test_var __attribute__((shared_lock_function)); // \ + expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} + +void slf_fun_params(int lvar __attribute__((shared_lock_function))); // \ + expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} + +class SlfFoo { + private: + int test_field __attribute__((shared_lock_function)); // \ + expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} + void test_method() __attribute__((shared_lock_function)); +}; + +class __attribute__((shared_lock_function)) SlfTestClass { // \ + expected-warning {{'shared_lock_function' attribute only applies to functions and methods}} +}; + + +/*********************************** + * Exclusive TryLock Function (etf) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes attribute takes at least 1 argument arguments}} + +void etf_function_args() __attribute__((exclusive_trylock_function(1, mu2))); + +void etf_function_arg() __attribute__((exclusive_trylock_function(1))); + +int etf_testfn(int y) __attribute__((exclusive_trylock_function(1))); + +int etf_testfn(int y) { + int x __attribute__((exclusive_trylock_function(1))) = y; // \ + expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} + return x; +}; + +int etf_test_var __attribute__((exclusive_trylock_function(1))); // \ + expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} + +class EtfFoo { + private: + int test_field __attribute__((exclusive_trylock_function(1))); // \ + expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} + void test_method() __attribute__((exclusive_trylock_function(1))); +}; + +class __attribute__((exclusive_trylock_function(1))) EtfTestClass { // \ + expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} +}; + +void etf_fun_params(int lvar __attribute__((exclusive_trylock_function(1)))); // \ + expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}} + + + +/*********************************** + * Shared TryLock Function (stf) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes at least 1 argument}} + +void stf_function_args() __attribute__((shared_trylock_function(1, mu2))); + +void stf_function_arg() __attribute__((shared_trylock_function(1))); + +int stf_testfn(int y) __attribute__((shared_trylock_function(1))); + +int stf_testfn(int y) { + int x __attribute__((shared_trylock_function(1))) = y; // \ + expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} + return x; +}; + +int stf_test_var __attribute__((shared_trylock_function(1))); // \ + expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} + +void stf_fun_params(int lvar __attribute__((shared_trylock_function(1)))); // \ + expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} + + +class StfFoo { + private: + int test_field __attribute__((shared_trylock_function(1))); // \ + expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} + void test_method() __attribute__((shared_trylock_function(1))); +}; + +class __attribute__((shared_trylock_function(1))) StfTestClass { // \ + expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}} +}; + + +/*********************************** + * Unlock Function (uf) + ***********************************/ + +#if !__has_attribute(unlock_function) +#error "Should support unlock_function attribute" +#endif + +// takes zero or more arguments, all locks (vars/fields) + +void uf_function() __attribute__((unlock_function)); + +void uf_function_args() __attribute__((unlock_function(mu1, mu2))); + +int uf_testfn(int y) __attribute__((unlock_function)); + +int uf_testfn(int y) { + int x __attribute__((unlock_function)) = y; // \ + expected-warning {{'unlock_function' attribute only applies to functions and methods}} + return x; +}; + +int uf_test_var __attribute__((unlock_function)); // \ + expected-warning {{'unlock_function' attribute only applies to functions and methods}} + +class UfFoo { + private: + int test_field __attribute__((unlock_function)); // \ + expected-warning {{'unlock_function' attribute only applies to functions and methods}} + void test_method() __attribute__((unlock_function)); +}; + +class __attribute__((no_thread_safety_analysis)) UfTestClass { // \ + expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}} +}; + +void uf_fun_params(int lvar __attribute__((unlock_function))); // \ + expected-warning {{'unlock_function' attribute only applies to functions and methods}} + + +/*********************************** + * Lock Returned (lr) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes one argument}} + +void lr_function_arg() __attribute__((lock_returned(mu1))); + +void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \ + expected-error {{attribute takes one argument}} + +int lr_testfn(int y) __attribute__((lock_returned(mu1))); + +int lr_testfn(int y) { + int x __attribute__((lock_returned(mu1))) = y; // \ + expected-warning {{'lock_returned' attribute only applies to functions and methods}} + return x; +}; + +int lr_test_var __attribute__((lock_returned(mu1))); // \ + expected-warning {{'lock_returned' attribute only applies to functions and methods}} + +void lr_fun_params(int lvar __attribute__((lock_returned(mu1)))); // \ + expected-warning {{'lock_returned' attribute only applies to functions and methods}} + +class LrFoo { + private: + int test_field __attribute__((lock_returned(mu1))); // \ + expected-warning {{'lock_returned' attribute only applies to functions and methods}} + void test_method() __attribute__((lock_returned(mu1))); +}; + +class __attribute__((lock_returned(mu1))) LrTestClass { // \ + expected-warning {{'lock_returned' attribute only applies to functions and methods}} +}; + +/*********************************** + * Locks Excluded (le) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes at least 1 argument}} + +void le_function_arg() __attribute__((locks_excluded(mu1))); + +void le_function_args() __attribute__((locks_excluded(mu1, mu2))); + +int le_testfn(int y) __attribute__((locks_excluded(mu1))); + +int le_testfn(int y) { + int x __attribute__((locks_excluded(mu1))) = y; // \ + expected-warning {{'locks_excluded' attribute only applies to functions and methods}} + return x; +}; + +int le_test_var __attribute__((locks_excluded(mu1))); // \ + expected-warning {{'locks_excluded' attribute only applies to functions and methods}} + +void le_fun_params(int lvar __attribute__((locks_excluded(mu1)))); // \ + expected-warning {{'locks_excluded' attribute only applies to functions and methods}} + +class LeFoo { + private: + int test_field __attribute__((locks_excluded(mu1))); // \ + expected-warning {{'locks_excluded' attribute only applies to functions and methods}} + void test_method() __attribute__((locks_excluded(mu1))); +}; + +class __attribute__((locks_excluded(mu1))) LeTestClass { // \ + expected-warning {{'locks_excluded' attribute only applies to functions and methods}} +}; + + +/*********************************** + * Exclusive Locks Required (elr) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes at least 1 argument}} + +void elr_function_arg() __attribute__((exclusive_locks_required(mu1))); + +void elr_function_args() __attribute__((exclusive_locks_required(mu1, mu2))); + +int elr_testfn(int y) __attribute__((exclusive_locks_required(mu1))); + +int elr_testfn(int y) { + int x __attribute__((exclusive_locks_required(mu1))) = y; // \ + expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} + return x; +}; + +int elr_test_var __attribute__((exclusive_locks_required(mu1))); // \ + expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} + +void elr_fun_params(int lvar __attribute__((exclusive_locks_required(mu1)))); // \ + expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} + +class ElrFoo { + private: + int test_field __attribute__((exclusive_locks_required(mu1))); // \ + expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} + void test_method() __attribute__((exclusive_locks_required(mu1))); +}; + +class __attribute__((exclusive_locks_required(mu1))) ElrTestClass { // \ + expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}} +}; + +/*********************************** + * Shared Locks Required (slr) + ***********************************/ + +#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)); // \ + expected-error {{attribute takes at least 1 argument}} + +void slr_function_arg() __attribute__((shared_locks_required(mu1))); + +void slr_function_args() __attribute__((shared_locks_required(mu1, mu2))); + +int slr_testfn(int y) __attribute__((shared_locks_required(mu1))); + +int slr_testfn(int y) { + int x __attribute__((shared_locks_required(mu1))) = y; // \ + expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} + return x; +}; + +int slr_test_var __attribute__((shared_locks_required(mu1))); // \ + expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} + +void slr_fun_params(int lvar __attribute__((shared_locks_required(mu1)))); // \ + expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} + +class SlrFoo { + private: + int test_field __attribute__((shared_locks_required(mu1))); // \ + expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} + void test_method() __attribute__((shared_locks_required(mu1))); +}; + +class __attribute__((shared_locks_required(mu1))) SlrTestClass { // \ + expected-warning {{'shared_locks_required' attribute only applies to functions and methods}} +}; |

