diff options
Diffstat (limited to 'test/SemaCXX/warn-thread-safety-analysis.cpp')
-rw-r--r-- | test/SemaCXX/warn-thread-safety-analysis.cpp | 88 |
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(); + } +}; + +} + + + + |