diff options
author | Malek Ben Slimane <85631834+malek203@users.noreply.github.com> | 2024-09-04 16:18:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-04 16:18:11 +0200 |
commit | e64ef634bbd940dfaae23d9fb43e6385014ffd10 (patch) | |
tree | 9193114cdbf285cc0feb794d8fae824931087bc1 /clang/lib/Analysis/ThreadSafety.cpp | |
parent | 30f1cfb4d0784de869ab3a4a9774b696b9769093 (diff) | |
download | llvm-e64ef634bbd940dfaae23d9fb43e6385014ffd10.zip llvm-e64ef634bbd940dfaae23d9fb43e6385014ffd10.tar.gz llvm-e64ef634bbd940dfaae23d9fb43e6385014ffd10.tar.bz2 |
Thread Safety Analysis: Differentiate between lock sets at real join points and expected/actual sets at function end (#105526)
This fixes false positives related to returning a scoped lockable
object. At the end of a function, we check managed locks instead of
scoped locks.
At real join points, we skip checking managed locks because we assume
that the scope keeps track of its underlying mutexes and will release
them at its destruction. So, checking for the scopes is sufficient.
However, at the end of a function, we aim at comparing the expected and
the actual lock sets. There, we skip checking scoped locks to prevent to
get duplicate warnings for the same lock.
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index e25b843..c4a83b0 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -922,6 +922,9 @@ public: handleRemovalFromIntersection(const FactSet &FSet, FactManager &FactMan, SourceLocation JoinLoc, LockErrorKind LEK, ThreadSafetyHandler &Handler) const override { + if (LEK == LEK_LockedAtEndOfFunction || LEK == LEK_NotLockedAtEndOfFunction) + return; + for (const auto &UnderlyingMutex : UnderlyingMutexes) { const auto *Entry = FSet.findLock(FactMan, UnderlyingMutex.Cap); if ((UnderlyingMutex.Kind == UCK_Acquired && Entry) || @@ -2224,7 +2227,7 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &EntrySet, if (join(FactMan[*EntryIt], ExitFact, EntryLEK != LEK_LockedSomeLoopIterations)) *EntryIt = Fact; - } else if (!ExitFact.managed()) { + } else if (!ExitFact.managed() || EntryLEK == LEK_LockedAtEndOfFunction) { ExitFact.handleRemovalFromIntersection(ExitSet, FactMan, JoinLoc, EntryLEK, Handler); } @@ -2236,7 +2239,8 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &EntrySet, const FactEntry *ExitFact = ExitSet.findLock(FactMan, *EntryFact); if (!ExitFact) { - if (!EntryFact->managed() || ExitLEK == LEK_LockedSomeLoopIterations) + if (!EntryFact->managed() || ExitLEK == LEK_LockedSomeLoopIterations || + ExitLEK == LEK_NotLockedAtEndOfFunction) EntryFact->handleRemovalFromIntersection(EntrySetOrig, FactMan, JoinLoc, ExitLEK, Handler); if (ExitLEK == LEK_LockedSomePredecessors) |