diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -983,7 +983,7 @@ } else { FSet.removeLock(FactMan, !Cp); FSet.addLock(FactMan, - std::make_unique(Cp, kind, loc)); + std::make_unique(Cp, kind, loc, true)); } } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -2595,6 +2595,7 @@ if (c) { // test join point -- held/not held during release rlock.Release(); } + // No warning on join point because the lock will be released by the scope object anyway. } void Foo::test3() { @@ -2615,7 +2616,7 @@ if (c) { rlock.Release(); } - // no warning on join point for managed lock. + // No warning on join point because the lock will be released by the scope object anyway. rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}} } @@ -2659,6 +2660,7 @@ Mutex mu; int x GUARDED_BY(mu); +bool b; void print(int); @@ -2740,6 +2742,23 @@ scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}} } +void lockJoin() { + RelockableMutexLock scope(&mu, DeferTraits{}); + if (b) + scope.Lock(); + // No warning on join point because the lock will be released by the scope object anyway. + x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} +} + +void unlockJoin() { + RelockableMutexLock scope(&mu, DeferTraits{}); + scope.Lock(); + if (b) + scope.Unlock(); + // No warning on join point because the lock will be released by the scope object anyway. + x = 2; // expected-warning {{writing variable 'x' requires holding mutex 'mu' exclusively}} +} + void directUnlock() { RelockableExclusiveMutexLock scope(&mu); mu.Unlock(); @@ -2871,10 +2890,9 @@ void join() EXCLUSIVE_LOCKS_REQUIRED(mu) { MutexUnlock scope(&mu); - if (c) { - scope.Lock(); // expected-note{{mutex acquired here}} - } - // expected-warning@+1{{mutex 'mu' is not held on every path through here}} + if (c) + scope.Lock(); + // No warning on join point because the lock will be released by the scope object anyway. scope.Lock(); }