diff options
| author | DeLesley Hutchins <delesley@google.com> | 2013-05-17 23:02:59 +0000 |
|---|---|---|
| committer | DeLesley Hutchins <delesley@google.com> | 2013-05-17 23:02:59 +0000 |
| commit | b68243177556fab5e0c5fee88a5767bda83f8eb5 (patch) | |
| tree | 2fa383fadd81024a13bf7bd45e258f0cca34ec95 /clang/test | |
| parent | f5bb53f19f342b9cfd88aaa9c0aa4f5785b60461 (diff) | |
| download | bcm5719-llvm-b68243177556fab5e0c5fee88a5767bda83f8eb5.tar.gz bcm5719-llvm-b68243177556fab5e0c5fee88a5767bda83f8eb5.zip | |
Thread safety analysis: add two new attributes to the thread safety analysis:
assert_exclusive_lock and assert_shared_lock. These attributes are used to
mark functions that dynamically check (i.e. assert) that a lock is held.
llvm-svn: 182170
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 111 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-parsing.cpp | 16 |
2 files changed, 122 insertions, 5 deletions
diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index bc4b40ead73..20b1a563541 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -11,8 +11,10 @@ #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_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) +#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__))) +#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__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__))) @@ -33,6 +35,9 @@ class __attribute__((lockable)) Mutex { bool TryLock() __attribute__((exclusive_trylock_function(true))); bool ReaderTryLock() __attribute__((shared_trylock_function(true))); void LockWhen(const int &cond) __attribute__((exclusive_lock_function)); + + void AssertHeld() ASSERT_EXCLUSIVE_LOCK(); + void AssertReaderHeld() ASSERT_SHARED_LOCK(); }; class __attribute__((scoped_lockable)) MutexLock { @@ -3985,3 +3990,105 @@ private: } // end namespace LockUnlockFunctionTest + +namespace AssertHeldTest { + +class Foo { +public: + int c; + int a GUARDED_BY(mu_); + Mutex mu_; + + void test1() { + mu_.AssertHeld(); + int b = a; + a = 0; + } + + void test2() { + mu_.AssertReaderHeld(); + int b = a; + a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}} + } + + void test3() { + if (c) { + mu_.AssertHeld(); + } + else { + mu_.AssertHeld(); + } + int b = a; + a = 0; + } + + void test4() EXCLUSIVE_LOCKS_REQUIRED(mu_) { + mu_.AssertHeld(); + int b = a; + a = 0; + } + + void test5() UNLOCK_FUNCTION(mu_) { + mu_.AssertHeld(); + mu_.Unlock(); + } + + void test6() { + mu_.AssertHeld(); + mu_.Unlock(); + } // should this be a warning? + + void test7() { + if (c) { + mu_.AssertHeld(); + } + else { + mu_.Lock(); + } + int b = a; + a = 0; + mu_.Unlock(); + } + + void test8() { + if (c) { + mu_.Lock(); + } + else { + mu_.AssertHeld(); + } + int b = a; + a = 0; + mu_.Unlock(); + } + + void test9() { + if (c) { + mu_.AssertHeld(); + } + else { + mu_.Lock(); // expected-note {{mutex acquired here}} + } + } // expected-warning {{mutex 'mu_' is still locked at the end of function}} + + void test10() { + if (c) { + mu_.Lock(); // expected-note {{mutex acquired here}} + } + else { + mu_.AssertHeld(); + } + } // expected-warning {{mutex 'mu_' is still locked at the end of function}} + + void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_); + + void test11() { + assertMu(); + int b = a; + a = 0; + } +}; + +} // end namespace AssertHeldTest + + diff --git a/clang/test/SemaCXX/warn-thread-safety-parsing.cpp b/clang/test/SemaCXX/warn-thread-safety-parsing.cpp index df9415cf860..ee6ec927521 100644 --- a/clang/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -8,8 +8,10 @@ #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_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) +#define ASSERT_EXCLUSIVE_LOCK(...) __attribute__ ((assert_exclusive_lock(__VA_ARGS__))) +#define ASSERT_SHARED_LOCK(...) __attribute__ ((assert_shared_lock(__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__))) @@ -24,7 +26,15 @@ class LOCKABLE Mutex { public: - void Lock(); + void Lock() EXCLUSIVE_LOCK_FUNCTION(); + void ReaderLock() SHARED_LOCK_FUNCTION(); + void Unlock() UNLOCK_FUNCTION(); + + bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); + bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); + + void AssertHeld() ASSERT_EXCLUSIVE_LOCK(); + void AssertReaderHeld() ASSERT_SHARED_LOCK(); }; class UnlockableMu{ |

