summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2018-07-26 13:03:16 +0000
committerAaron Ballman <aaron@aaronballman.com>2018-07-26 13:03:16 +0000
commit1b58759d82f1e56261e2e1b25407de624f88fc0e (patch)
treedf7449fb0dc1be0bdc27446a15d807d8e402a93d /clang/lib/Analysis
parent04f97cf2f01b4e2bf9e67b19dd2c204935d4d2ef (diff)
downloadbcm5719-llvm-1b58759d82f1e56261e2e1b25407de624f88fc0e.tar.gz
bcm5719-llvm-1b58759d82f1e56261e2e1b25407de624f88fc0e.zip
Allow thread safety annotation lock upgrading and downgrading.
Patch thanks to Aaron Puchert! llvm-svn: 338024
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp27
1 files changed, 12 insertions, 15 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 8895dec02b9..03cc234dce5 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -109,9 +109,7 @@ class FactSet;
/// along with additional information, such as where it was acquired, whether
/// it is exclusive or shared, etc.
///
-/// FIXME: this analysis does not currently support either re-entrant
-/// locking or lock "upgrading" and "downgrading" between exclusive and
-/// shared.
+/// FIXME: this analysis does not currently support re-entrant locking.
class FactEntry : public CapabilityExpr {
private:
/// Exclusive or shared.
@@ -1737,8 +1735,7 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
}
}
- for(Attr *Atconst : D->attrs()) {
- auto *At = const_cast<Attr *>(Atconst);
+ for(const Attr *At : D->attrs()) {
switch (At->getKind()) {
// When we encounter a lock function, we need to add the lock to our
// lockset.
@@ -1838,6 +1835,16 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
}
}
+ // Remove locks first to allow lock upgrading/downgrading.
+ // FIXME -- should only fully remove if the attribute refers to 'this'.
+ bool Dtor = isa<CXXDestructorDecl>(D);
+ for (const auto &M : ExclusiveLocksToRemove)
+ Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Exclusive, CapDiagKind);
+ for (const auto &M : SharedLocksToRemove)
+ Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Shared, CapDiagKind);
+ for (const auto &M : GenericLocksToRemove)
+ Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Generic, CapDiagKind);
+
// Add locks.
for (const auto &M : ExclusiveLocksToAdd)
Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
@@ -1864,16 +1871,6 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
Scp, MLoc, ExclusiveLocksToAdd, SharedLocksToAdd),
CapDiagKind);
}
-
- // Remove locks.
- // FIXME -- should only fully remove if the attribute refers to 'this'.
- bool Dtor = isa<CXXDestructorDecl>(D);
- for (const auto &M : ExclusiveLocksToRemove)
- Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Exclusive, CapDiagKind);
- for (const auto &M : SharedLocksToRemove)
- Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Shared, CapDiagKind);
- for (const auto &M : GenericLocksToRemove)
- Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Generic, CapDiagKind);
}
/// For unary operations which read and write a variable, we need to
OpenPOWER on IntegriCloud