summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2013-05-17 23:02:59 +0000
committerDeLesley Hutchins <delesley@google.com>2013-05-17 23:02:59 +0000
commitb68243177556fab5e0c5fee88a5767bda83f8eb5 (patch)
tree2fa383fadd81024a13bf7bd45e258f0cca34ec95 /clang/test
parentf5bb53f19f342b9cfd88aaa9c0aa4f5785b60461 (diff)
downloadbcm5719-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.cpp111
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-parsing.cpp16
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{
OpenPOWER on IntegriCloud