warn-thread-safety-analysis.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta %s
  2. #define LOCKABLE __attribute__ ((lockable))
  3. #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
  4. #define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
  5. #define GUARDED_VAR __attribute__ ((guarded_var))
  6. #define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
  7. #define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
  8. #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
  9. #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
  10. #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
  11. #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
  12. #define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__)))
  13. #define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__VA_ARGS__)))
  14. #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
  15. #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
  16. #define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
  17. #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
  18. #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
  19. #define EXCLUSIVE_LOCKS_REQUIRED(...) \
  20. __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
  21. #define SHARED_LOCKS_REQUIRED(...) \
  22. __attribute__ ((shared_locks_required(__VA_ARGS__)))
  23. #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
  24. // Define the mutex struct.
  25. // Simplified only for test purpose.
  26. struct LOCKABLE Mutex {};
  27. struct Foo {
  28. struct Mutex *mu_;
  29. };
  30. // Declare mutex lock/unlock functions.
  31. void mutex_exclusive_lock(struct Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
  32. void mutex_shared_lock(struct Mutex *mu) SHARED_LOCK_FUNCTION(mu);
  33. void mutex_unlock(struct Mutex *mu) UNLOCK_FUNCTION(mu);
  34. void mutex_shared_unlock(struct Mutex *mu) __attribute__((release_shared_capability(mu)));
  35. void mutex_exclusive_unlock(struct Mutex *mu) __attribute__((release_capability(mu)));
  36. // Define global variables.
  37. struct Mutex mu1;
  38. struct Mutex mu2 ACQUIRED_AFTER(mu1);
  39. struct Foo foo_ = {&mu1};
  40. int a_ GUARDED_BY(foo_.mu_);
  41. int *b_ PT_GUARDED_BY(foo_.mu_) = &a_;
  42. int c_ GUARDED_VAR;
  43. int *d_ PT_GUARDED_VAR = &c_;
  44. // Define test functions.
  45. int Foo_fun1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
  46. return i;
  47. }
  48. int Foo_fun2(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1) {
  49. return i;
  50. }
  51. int Foo_func3(int i) LOCKS_EXCLUDED(mu1, mu2) {
  52. return i;
  53. }
  54. static int Bar_fun1(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
  55. return i;
  56. }
  57. void set_value(int *a, int value) EXCLUSIVE_LOCKS_REQUIRED(foo_.mu_) {
  58. *a = value;
  59. }
  60. int get_value(int *p) SHARED_LOCKS_REQUIRED(foo_.mu_){
  61. return *p;
  62. }
  63. int main() {
  64. Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu2'}} \
  65. expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
  66. mutex_exclusive_lock(&mu1);
  67. mutex_shared_lock(&mu2);
  68. Foo_fun1(1);
  69. mutex_shared_lock(&mu1); // expected-warning{{acquiring mutex 'mu1' that is already held}}
  70. mutex_unlock(&mu1);
  71. mutex_unlock(&mu2);
  72. mutex_shared_lock(&mu1);
  73. mutex_exclusive_lock(&mu2);
  74. Foo_fun2(2);
  75. mutex_unlock(&mu2);
  76. mutex_unlock(&mu1);
  77. mutex_exclusive_lock(&mu1);
  78. Bar_fun1(3);
  79. mutex_unlock(&mu1);
  80. mutex_exclusive_lock(&mu1);
  81. Foo_func3(4); // expected-warning{{cannot call function 'Foo_func3' while mutex 'mu1' is held}}
  82. mutex_unlock(&mu1);
  83. Foo_func3(5);
  84. set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}}
  85. get_value(b_); // expected-warning{{calling function 'get_value' requires holding mutex 'foo_.mu_'}}
  86. mutex_exclusive_lock(foo_.mu_);
  87. set_value(&a_, 1);
  88. mutex_unlock(foo_.mu_);
  89. mutex_shared_lock(foo_.mu_);
  90. (void)(get_value(b_) == 1);
  91. mutex_unlock(foo_.mu_);
  92. c_ = 0; // expected-warning{{writing variable 'c_' requires holding any mutex exclusively}}
  93. (void)(*d_ == 0); // expected-warning{{reading the value pointed to by 'd_' requires holding any mutex}}
  94. mutex_exclusive_lock(foo_.mu_);
  95. c_ = 1;
  96. (void)(*d_ == 1);
  97. mutex_unlock(foo_.mu_);
  98. mutex_exclusive_lock(&mu1);
  99. mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using shared access, expected exclusive access}}
  100. mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}}
  101. mutex_shared_lock(&mu1);
  102. mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using exclusive access, expected shared access}}
  103. mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}}
  104. return 0;
  105. }