diff options
Diffstat (limited to 'test/SemaCXX/warn-thread-safety-analysis.cpp')
| -rw-r--r-- | test/SemaCXX/warn-thread-safety-analysis.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 4f31d406b5fb..b5d2f8e1de83 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5091,3 +5091,101 @@ class Foo { } // end namespace ScopedAdoptTest + +namespace TestReferenceNoThreadSafetyAnalysis { + +#define TS_UNCHECKED_READ(x) ts_unchecked_read(x) + +// Takes a reference to a guarded data member, and returns an unguarded +// reference. +template <class T> +inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS { + return v; +} + +template <class T> +inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS { + return v; +} + + +class Foo { +public: + Foo(): a(0) { } + + int a; +}; + + +class Bar { +public: + Bar() : a(0) { } + + Mutex mu; + int a GUARDED_BY(mu); + Foo foo GUARDED_BY(mu); +}; + + +void test() { + Bar bar; + const Bar cbar; + + int a = TS_UNCHECKED_READ(bar.a); // nowarn + TS_UNCHECKED_READ(bar.a) = 1; // nowarn + + int b = TS_UNCHECKED_READ(bar.foo).a; // nowarn + TS_UNCHECKED_READ(bar.foo).a = 1; // nowarn + + int c = TS_UNCHECKED_READ(cbar.a); // nowarn +} + +#undef TS_UNCHECKED_READ + +} // end namespace TestReferenceNoThreadSafetyAnalysis + + +namespace GlobalAcquiredBeforeAfterTest { + +Mutex mu1; +Mutex mu2 ACQUIRED_AFTER(mu1); + +void test3() { + mu2.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} + mu1.Unlock(); + mu2.Unlock(); +} + +} // end namespace GlobalAcquiredBeforeAfterTest + + +namespace LockableUnions { + +union LOCKABLE MutexUnion { + int a; + char* b; + + void Lock() EXCLUSIVE_LOCK_FUNCTION(); + void Unlock() UNLOCK_FUNCTION(); +}; + +MutexUnion muun2; +MutexUnion muun1 ACQUIRED_BEFORE(muun2); + +void test() { + muun2.Lock(); + muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}} + muun1.Unlock(); + muun2.Unlock(); +} + +} // end namespace LockableUnions + +// This used to crash. +class acquired_before_empty_str { + void WaitUntilSpaceAvailable() { + lock_.ReaderLock(); // expected-note {{acquired here}} + } // expected-warning {{mutex 'lock_' is still held at the end of function}} + Mutex lock_ ACQUIRED_BEFORE(""); +}; |
