summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/warn-thread-safety-analysis.cpp')
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-analysis.cpp48
1 files changed, 47 insertions, 1 deletions
diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
index 8d231bd7f8b..1c47035c2b2 100644
--- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -49,6 +49,13 @@ class __attribute__((scoped_lockable)) ReaderMutexLock {
~ReaderMutexLock() __attribute__((unlock_function));
};
+class SCOPED_LOCKABLE ReleasableMutexLock {
+ public:
+ ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
+ ~ReleasableMutexLock() UNLOCK_FUNCTION();
+
+ void Release() UNLOCK_FUNCTION();
+};
Mutex sls_mu;
@@ -1578,7 +1585,7 @@ struct TestScopedLockable {
MutexLock mulock_a(&mu1);
MutexLock mulock_b(&mu1); // \
// expected-warning {{locking 'mu1' that is already locked}}
- } // expected-warning {{unlocking 'mu1' that was not locked}}
+ }
void foo4() {
MutexLock mulock1(&mu1), mulock2(&mu2);
@@ -2361,3 +2368,42 @@ void test3(Bar* b1, Bar* b2) {
} // end namespace LockReturned
+namespace ReleasableScopedLock {
+
+class Foo {
+ Mutex mu_;
+ bool c;
+ int a GUARDED_BY(mu_);
+
+ void test1();
+ void test2();
+ void test3();
+};
+
+
+void Foo::test1() {
+ ReleasableMutexLock rlock(&mu_);
+ rlock.Release();
+}
+
+void Foo::test2() {
+ ReleasableMutexLock rlock(&mu_);
+ if (c) { // test join point -- held/not held during release
+ rlock.Release();
+ }
+}
+
+void Foo::test3() {
+ ReleasableMutexLock rlock(&mu_);
+ a = 0;
+ rlock.Release();
+ a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+}
+
+} // end namespace ReleasableScopedLock
+
+
+
+
+
+
OpenPOWER on IntegriCloud