aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/warn-thread-safety-analysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/warn-thread-safety-analysis.cpp')
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp88
1 files changed, 84 insertions, 4 deletions
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index cf378c5090..6044b79021 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -24,10 +24,6 @@
__attribute__ ((shared_locks_required(__VA_ARGS__)))
#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
-//-----------------------------------------//
-// Helper fields
-//-----------------------------------------//
-
class __attribute__((lockable)) Mutex {
public:
@@ -60,6 +56,14 @@ class SCOPED_LOCKABLE ReleasableMutexLock {
};
+// The universal lock, written "*", allows checking to be selectively turned
+// off for a particular piece of code.
+void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*");
+void endNoWarnOnReads() UNLOCK_FUNCTION("*");
+void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*");
+void endNoWarnOnWrites() UNLOCK_FUNCTION("*");
+
+
template<class T>
class SmartPtr {
public:
@@ -3217,3 +3221,79 @@ static void test() {
}
+namespace UniversalLock {
+
+class Foo {
+ Mutex mu_;
+ bool c;
+
+ int a GUARDED_BY(mu_);
+ void r_foo() SHARED_LOCKS_REQUIRED(mu_);
+ void w_foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+
+ void test1() {
+ int b;
+
+ beginNoWarnOnReads();
+ b = a;
+ r_foo();
+ endNoWarnOnReads();
+
+ beginNoWarnOnWrites();
+ a = 0;
+ w_foo();
+ endNoWarnOnWrites();
+ }
+
+ // don't warn on joins with universal lock
+ void test2() {
+ if (c) {
+ beginNoWarnOnWrites();
+ }
+ a = 0; // \
+ // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ endNoWarnOnWrites(); // \
+ // expected-warning {{unlocking '*' that was not locked}}
+ }
+
+
+ // make sure the universal lock joins properly
+ void test3() {
+ if (c) {
+ mu_.Lock();
+ beginNoWarnOnWrites();
+ }
+ else {
+ beginNoWarnOnWrites();
+ mu_.Lock();
+ }
+ a = 0;
+ endNoWarnOnWrites();
+ mu_.Unlock();
+ }
+
+
+ // combine universal lock with other locks
+ void test4() {
+ beginNoWarnOnWrites();
+ mu_.Lock();
+ mu_.Unlock();
+ endNoWarnOnWrites();
+
+ mu_.Lock();
+ beginNoWarnOnWrites();
+ endNoWarnOnWrites();
+ mu_.Unlock();
+
+ mu_.Lock();
+ beginNoWarnOnWrites();
+ mu_.Unlock();
+ endNoWarnOnWrites();
+ }
+};
+
+}
+
+
+
+