aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorAaron Puchert <aaron.puchert@sap.com>2021-06-29 23:46:43 +0200
committerAaron Puchert <aaron.puchert@sap.com>2021-06-29 23:56:52 +0200
commitf664e2ec371f61b69e11147d7f9e045083335917 (patch)
tree0e75793f8922cea2ffe64852dc62cda6bc0cdd88 /clang/lib/Analysis/ThreadSafety.cpp
parentcb3580e7ad247dfdcf2ad279895f52bb73c4cee4 (diff)
downloadllvm-f664e2ec371f61b69e11147d7f9e045083335917.zip
llvm-f664e2ec371f61b69e11147d7f9e045083335917.tar.gz
llvm-f664e2ec371f61b69e11147d7f9e045083335917.tar.bz2
Thread safety analysis: Always warn when dropping locks on back edges
We allow branches to join where one holds a managed lock but the other doesn't, but we can't do so for back edges: because there we can't drop them from the lockset, as we have already analyzed the loop with the larger lockset. So we can't allow dropping managed locks on back edges. We move the managed() check from handleRemovalFromIntersection up to intersectAndWarn, where we additionally check if we're on a back edge if we're removing from the first lock set (the entry set of the next block) but not if we're removing from the second lock set (the exit set of the previous block). Now that the order of arguments matters, I had to swap them in one invocation, which also causes some minor differences in the tests. Reviewed By: delesley Differential Revision: https://reviews.llvm.org/D104261
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp11
1 files changed, 6 insertions, 5 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 3eb1b64..b09de2b 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -865,7 +865,7 @@ public:
handleRemovalFromIntersection(const FactSet &FSet, FactManager &FactMan,
SourceLocation JoinLoc, LockErrorKind LEK,
ThreadSafetyHandler &Handler) const override {
- if (!managed() && !asserted() && !negative() && !isUniversal()) {
+ if (!asserted() && !negative() && !isUniversal()) {
Handler.handleMutexHeldEndOfScope("mutex", toString(), loc(), JoinLoc,
LEK);
}
@@ -2239,7 +2239,7 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &FSet1,
if (Iter1 != FSet1.end()) {
if (join(FactMan[*Iter1], LDat2) && LEK1 == LEK_LockedSomePredecessors)
*Iter1 = Fact;
- } else {
+ } else if (!LDat2.managed()) {
LDat2.handleRemovalFromIntersection(FSet2, FactMan, JoinLoc, LEK1,
Handler);
}
@@ -2251,8 +2251,9 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &FSet1,
const FactEntry *LDat2 = FSet2.findLock(FactMan, *LDat1);
if (!LDat2) {
- LDat1->handleRemovalFromIntersection(FSet1Orig, FactMan, JoinLoc, LEK2,
- Handler);
+ if (!LDat1->managed() || LEK2 == LEK_LockedSomeLoopIterations)
+ LDat1->handleRemovalFromIntersection(FSet1Orig, FactMan, JoinLoc, LEK2,
+ Handler);
if (LEK2 == LEK_LockedSomePredecessors)
FSet1.removeLock(FactMan, *LDat1);
}
@@ -2528,7 +2529,7 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
CFGBlock *FirstLoopBlock = *SI;
CFGBlockInfo *PreLoop = &BlockInfo[FirstLoopBlock->getBlockID()];
CFGBlockInfo *LoopEnd = &BlockInfo[CurrBlockID];
- intersectAndWarn(LoopEnd->ExitSet, PreLoop->EntrySet, PreLoop->EntryLoc,
+ intersectAndWarn(PreLoop->EntrySet, LoopEnd->ExitSet, PreLoop->EntryLoc,
LEK_LockedSomeLoopIterations);
}
}