diff options
author | Aaron Puchert <aaronpuchert@alice-dsl.net> | 2025-04-15 23:21:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-15 23:21:34 +0200 |
commit | 9c73eba8aa17cb7ca4248ab1c7f67ea7ec9b50b1 (patch) | |
tree | 9a73317d6a54d5d607a9d59e6e1990341534ac90 /clang/lib/Analysis/ThreadSafety.cpp | |
parent | d30a5b41fe72a1dd83714d3e21fd539b91e63c8c (diff) | |
download | llvm-9c73eba8aa17cb7ca4248ab1c7f67ea7ec9b50b1.zip llvm-9c73eba8aa17cb7ca4248ab1c7f67ea7ec9b50b1.tar.gz llvm-9c73eba8aa17cb7ca4248ab1c7f67ea7ec9b50b1.tar.bz2 |
Merge similar Clang Thread Safety attributes (#135561)
Some of the old lock-based and new capability-based spellings behave
basically in the same way, so merging them simplifies the code
significantly.
There are two minor functional changes: we only warn (instead of an
error) when the try_acquire_capability attribute is used on something
else than a function. The alternative would have been to produce an
error for the old spelling, but we seem to only warn for all function
attributes, so this is arguably more consistent.
The second change is that we also check the first argument (which is the
value returned for a successful try-acquire) for `this`. But from what I
can tell, this code is defunct anyway at the moment (see #31414).
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 60 |
1 files changed, 5 insertions, 55 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 6b5b493..42fb0fe 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1511,38 +1511,17 @@ void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result, return; auto *FunDecl = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl()); - if(!FunDecl || !FunDecl->hasAttrs()) + if (!FunDecl || !FunDecl->hasAttr<TryAcquireCapabilityAttr>()) return; CapExprSet ExclusiveLocksToAdd; CapExprSet SharedLocksToAdd; // If the condition is a call to a Trylock function, then grab the attributes - for (const auto *Attr : FunDecl->attrs()) { - switch (Attr->getKind()) { - case attr::TryAcquireCapability: { - auto *A = cast<TryAcquireCapabilityAttr>(Attr); - getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A, - Exp, FunDecl, PredBlock, CurrBlock, A->getSuccessValue(), - Negate); - break; - }; - case attr::ExclusiveTrylockFunction: { - const auto *A = cast<ExclusiveTrylockFunctionAttr>(Attr); - getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, - A->getSuccessValue(), Negate); - break; - } - case attr::SharedTrylockFunction: { - const auto *A = cast<SharedTrylockFunctionAttr>(Attr); - getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, - A->getSuccessValue(), Negate); - break; - } - default: - break; - } - } + for (const auto *Attr : FunDecl->specific_attrs<TryAcquireCapabilityAttr>()) + getMutexIDs(Attr->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, Attr, + Exp, FunDecl, PredBlock, CurrBlock, Attr->getSuccessValue(), + Negate); // Add and remove locks. SourceLocation Loc = Exp->getExprLoc(); @@ -1882,29 +1861,6 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, // An assert will add a lock to the lockset, but will not generate // a warning if it is already there, and will not generate a warning // if it is not removed. - case attr::AssertExclusiveLock: { - const auto *A = cast<AssertExclusiveLockAttr>(At); - - CapExprSet AssertLocks; - Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); - for (const auto &AssertLock : AssertLocks) - Analyzer->addLock( - FSet, std::make_unique<LockableFactEntry>( - AssertLock, LK_Exclusive, Loc, FactEntry::Asserted)); - break; - } - case attr::AssertSharedLock: { - const auto *A = cast<AssertSharedLockAttr>(At); - - CapExprSet AssertLocks; - Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); - for (const auto &AssertLock : AssertLocks) - Analyzer->addLock( - FSet, std::make_unique<LockableFactEntry>( - AssertLock, LK_Shared, Loc, FactEntry::Asserted)); - break; - } - case attr::AssertCapability: { const auto *A = cast<AssertCapabilityAttr>(At); CapExprSet AssertLocks; @@ -2499,12 +2455,6 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { getMutexIDs(A->isShared() ? SharedLocksAcquired : ExclusiveLocksAcquired, A, nullptr, D); - } else if (isa<ExclusiveTrylockFunctionAttr>(Attr)) { - // Don't try to check trylock functions for now. - return; - } else if (isa<SharedTrylockFunctionAttr>(Attr)) { - // Don't try to check trylock functions for now. - return; } else if (isa<TryAcquireCapabilityAttr>(Attr)) { // Don't try to check trylock functions for now. return; |