diff options
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index b5d87d2e651..37819a74d5d 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1690,8 +1690,19 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) { SourceLocation Loc = Exp->getExprLoc(); CapExprSet ExclusiveLocksToAdd, SharedLocksToAdd; CapExprSet ExclusiveLocksToRemove, SharedLocksToRemove, GenericLocksToRemove; + CapExprSet ScopedExclusiveReqs, ScopedSharedReqs; StringRef CapDiagKind = "mutex"; + // Figure out if we're calling the constructor of scoped lockable class + bool isScopedVar = false; + if (VD) { + if (const CXXConstructorDecl *CD = dyn_cast<const CXXConstructorDecl>(D)) { + const CXXRecordDecl* PD = CD->getParent(); + if (PD && PD->hasAttr<ScopedLockableAttr>()) + isScopedVar = true; + } + } + for(Attr *Atconst : D->attrs()) { Attr* At = const_cast<Attr*>(Atconst); switch (At->getKind()) { @@ -1751,10 +1762,17 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) { case attr::RequiresCapability: { RequiresCapabilityAttr *A = cast<RequiresCapabilityAttr>(At); - for (auto *Arg : A->args()) + for (auto *Arg : A->args()) { warnIfMutexNotHeld(D, Exp, A->isShared() ? AK_Read : AK_Written, Arg, POK_FunctionCall, ClassifyDiagnostic(A), Exp->getExprLoc()); + // use for adopting a lock + if (isScopedVar) { + Analyzer->getMutexIDs(A->isShared() ? ScopedSharedReqs + : ScopedExclusiveReqs, + A, Exp, D, VD); + } + } break; } @@ -1771,16 +1789,6 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) { } } - // Figure out if we're calling the constructor of scoped lockable class - bool isScopedVar = false; - if (VD) { - if (const CXXConstructorDecl *CD = dyn_cast<const CXXConstructorDecl>(D)) { - const CXXRecordDecl* PD = CD->getParent(); - if (PD && PD->hasAttr<ScopedLockableAttr>()) - isScopedVar = true; - } - } - // Add locks. for (const auto &M : ExclusiveLocksToAdd) Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>( @@ -1797,6 +1805,11 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) { DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation()); // FIXME: does this store a pointer to DRE? CapabilityExpr Scp = Analyzer->SxBuilder.translateAttrExpr(&DRE, nullptr); + + std::copy(ScopedExclusiveReqs.begin(), ScopedExclusiveReqs.end(), + std::back_inserter(ExclusiveLocksToAdd)); + std::copy(ScopedSharedReqs.begin(), ScopedSharedReqs.end(), + std::back_inserter(SharedLocksToAdd)); Analyzer->addLock(FSet, llvm::make_unique<ScopedLockableFactEntry>( Scp, MLoc, ExclusiveLocksToAdd, SharedLocksToAdd), |