diff options
author | Aaron Puchert <aaron.puchert@sap.com> | 2021-05-27 17:44:43 +0200 |
---|---|---|
committer | Aaron Puchert <aaron.puchert@sap.com> | 2021-05-27 17:44:48 +0200 |
commit | 3d64677c28072867ea6025a22805977386b767f8 (patch) | |
tree | 2a0a02ecc1d35aecbfdd4cd8982ba42d649e5462 /clang/lib/Analysis/ThreadSafety.cpp | |
parent | 192b4141f0d74dd08a4eacf2184a6881906993ed (diff) | |
download | llvm-3d64677c28072867ea6025a22805977386b767f8.zip llvm-3d64677c28072867ea6025a22805977386b767f8.tar.gz llvm-3d64677c28072867ea6025a22805977386b767f8.tar.bz2 |
Thread safety analysis: Factor out function for merging locks (NFC)
It's going to become a bit more complicated, so let's have it separate.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D102025
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 83410eb..c65e9f3 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1050,6 +1050,8 @@ public: const CFGBlock* PredBlock, const CFGBlock *CurrBlock); + bool join(const FactEntry &a, const FactEntry &b); + void intersectAndWarn(FactSet &FSet1, const FactSet &FSet2, SourceLocation JoinLoc, LockErrorKind LEK1, LockErrorKind LEK2); @@ -2186,6 +2188,21 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) { } } +/// Given two facts merging on a join point, decide whether to warn and which +/// one to keep. +/// +/// \return false if we should keep \p A, true if we should keep \p B. +bool ThreadSafetyAnalyzer::join(const FactEntry &A, const FactEntry &B) { + if (A.kind() != B.kind()) { + Handler.handleExclusiveAndShared("mutex", B.toString(), B.loc(), A.loc()); + // Take the exclusive capability to reduce further warnings. + return B.kind() == LK_Exclusive; + } else { + // The non-asserted capability is the one we want to track. + return A.asserted() && !B.asserted(); + } +} + /// Compute the intersection of two locksets and issue warnings for any /// locks in the symmetric difference. /// @@ -2213,20 +2230,8 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &FSet1, FactSet::iterator Iter1 = FSet1.findLockIter(FactMan, LDat2); if (Iter1 != FSet1.end()) { - const FactEntry &LDat1 = FactMan[*Iter1]; - if (LDat1.kind() != LDat2.kind()) { - Handler.handleExclusiveAndShared("mutex", LDat2.toString(), LDat2.loc(), - LDat1.loc()); - if (LEK1 == LEK_LockedSomePredecessors && - LDat1.kind() != LK_Exclusive) { - // Take the exclusive lock, which is the one in FSet2. - *Iter1 = Fact; - } - } else if (LEK1 == LEK_LockedSomePredecessors && LDat1.asserted() && - !LDat2.asserted()) { - // The non-asserted lock in FSet2 is the one we want to track. + if (join(FactMan[*Iter1], LDat2) && LEK1 == LEK_LockedSomePredecessors) *Iter1 = Fact; - } } else { LDat2.handleRemovalFromIntersection(FSet2, FactMan, JoinLoc, LEK1, Handler); |