aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorAaron Puchert <aaron.puchert@sap.com>2021-05-27 17:45:59 +0200
committerAaron Puchert <aaron.puchert@sap.com>2021-05-27 17:46:04 +0200
commitcf0b337c1b1f064c81fe40124ddba178572778d6 (patch)
treec8bf4ba7239da6f70e30c142a0e43553e61da72f /clang/lib/Analysis/ThreadSafety.cpp
parent3d64677c28072867ea6025a22805977386b767f8 (diff)
downloadllvm-cf0b337c1b1f064c81fe40124ddba178572778d6.zip
llvm-cf0b337c1b1f064c81fe40124ddba178572778d6.tar.gz
llvm-cf0b337c1b1f064c81fe40124ddba178572778d6.tar.bz2
Thread safety analysis: Allow exlusive/shared joins for managed and asserted capabilities
Similar to how we allow managed and asserted locks to be held and not held in joining branches, we also allow them to be held shared and exclusive. The scoped lock should restore the original state at the end of the scope in any event, and asserted locks need not be released. We should probably only allow asserted locks to be subsumed by managed, not by (directly) acquired locks, but that's for another change. Reviewed By: delesley Differential Revision: https://reviews.llvm.org/D102026
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index c65e9f3..6727e13 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -2194,9 +2194,16 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
/// \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;
+ // For managed capabilities, the destructor should unlock in the right mode
+ // anyway. For asserted capabilities no unlocking is needed.
+ if ((A.managed() || A.asserted()) && (B.managed() || B.asserted())) {
+ // The shared capability subsumes the exclusive capability.
+ return B.kind() == LK_Shared;
+ } else {
+ 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();