diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-07-26 13:03:16 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-07-26 13:03:16 +0000 |
commit | 1b58759d82f1e56261e2e1b25407de624f88fc0e (patch) | |
tree | df7449fb0dc1be0bdc27446a15d807d8e402a93d /clang/lib/Analysis | |
parent | 04f97cf2f01b4e2bf9e67b19dd2c204935d4d2ef (diff) | |
download | bcm5719-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.cpp | 27 |
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 |