@@ -1055,6 +1055,19 @@ class ThreadSafetyAnalyzer {
10551055 }
10561056
10571057 void runAnalysis (AnalysisDeclContext &AC);
1058+
1059+ void warnIfMutexNotHeld (const FactSet &FSet, const NamedDecl *D,
1060+ const Expr *Exp, AccessKind AK, Expr *MutexExp,
1061+ ProtectedOperationKind POK, til::LiteralPtr *Self,
1062+ SourceLocation Loc);
1063+ void warnIfMutexHeld (const FactSet &FSet, const NamedDecl *D, const Expr *Exp,
1064+ Expr *MutexExp, til::LiteralPtr *Self,
1065+ SourceLocation Loc);
1066+
1067+ void checkAccess (const FactSet &FSet, const Expr *Exp, AccessKind AK,
1068+ ProtectedOperationKind POK);
1069+ void checkPtAccess (const FactSet &FSet, const Expr *Exp, AccessKind AK,
1070+ ProtectedOperationKind POK);
10581071};
10591072
10601073} // namespace
@@ -1534,16 +1547,15 @@ class BuildLockset : public ConstStmtVisitor<BuildLockset> {
15341547 unsigned CtxIndex;
15351548
15361549 // helper functions
1537- void warnIfMutexNotHeld (const NamedDecl *D, const Expr *Exp, AccessKind AK,
1538- Expr *MutexExp, ProtectedOperationKind POK,
1539- til::LiteralPtr *Self, SourceLocation Loc);
1540- void warnIfMutexHeld (const NamedDecl *D, const Expr *Exp, Expr *MutexExp,
1541- til::LiteralPtr *Self, SourceLocation Loc);
15421550
15431551 void checkAccess (const Expr *Exp, AccessKind AK,
1544- ProtectedOperationKind POK = POK_VarAccess);
1552+ ProtectedOperationKind POK = POK_VarAccess) {
1553+ Analyzer->checkAccess (FSet, Exp, AK, POK);
1554+ }
15451555 void checkPtAccess (const Expr *Exp, AccessKind AK,
1546- ProtectedOperationKind POK = POK_VarAccess);
1556+ ProtectedOperationKind POK = POK_VarAccess) {
1557+ Analyzer->checkPtAccess (FSet, Exp, AK, POK);
1558+ }
15471559
15481560 void handleCall (const Expr *Exp, const NamedDecl *D,
15491561 til::LiteralPtr *Self = nullptr ,
@@ -1571,86 +1583,82 @@ class BuildLockset : public ConstStmtVisitor<BuildLockset> {
15711583
15721584// / Warn if the LSet does not contain a lock sufficient to protect access
15731585// / of at least the passed in AccessKind.
1574- void BuildLockset::warnIfMutexNotHeld (const NamedDecl *D, const Expr *Exp,
1575- AccessKind AK, Expr *MutexExp,
1576- ProtectedOperationKind POK,
1577- til::LiteralPtr *Self,
1578- SourceLocation Loc) {
1586+ void ThreadSafetyAnalyzer::warnIfMutexNotHeld (
1587+ const FactSet &FSet, const NamedDecl *D, const Expr *Exp, AccessKind AK,
1588+ Expr *MutexExp, ProtectedOperationKind POK, til::LiteralPtr *Self,
1589+ SourceLocation Loc) {
15791590 LockKind LK = getLockKindFromAccessKind (AK);
1580-
1581- CapabilityExpr Cp =
1582- Analyzer->SxBuilder .translateAttrExpr (MutexExp, D, Exp, Self);
1591+ CapabilityExpr Cp = SxBuilder.translateAttrExpr (MutexExp, D, Exp, Self);
15831592 if (Cp.isInvalid ()) {
1584- warnInvalidLock (Analyzer-> Handler , MutexExp, D, Exp, Cp.getKind ());
1593+ warnInvalidLock (Handler, MutexExp, D, Exp, Cp.getKind ());
15851594 return ;
15861595 } else if (Cp.shouldIgnore ()) {
15871596 return ;
15881597 }
15891598
15901599 if (Cp.negative ()) {
15911600 // Negative capabilities act like locks excluded
1592- const FactEntry *LDat = FSet.findLock (Analyzer-> FactMan , !Cp);
1601+ const FactEntry *LDat = FSet.findLock (FactMan, !Cp);
15931602 if (LDat) {
1594- Analyzer-> Handler .handleFunExcludesLock (
1595- Cp. getKind (), D-> getNameAsString (), (!Cp).toString (), Loc);
1603+ Handler.handleFunExcludesLock (Cp. getKind (), D-> getNameAsString (),
1604+ (!Cp).toString (), Loc);
15961605 return ;
15971606 }
15981607
15991608 // If this does not refer to a negative capability in the same class,
16001609 // then stop here.
1601- if (!Analyzer-> inCurrentScope (Cp))
1610+ if (!inCurrentScope (Cp))
16021611 return ;
16031612
16041613 // Otherwise the negative requirement must be propagated to the caller.
1605- LDat = FSet.findLock (Analyzer-> FactMan , Cp);
1614+ LDat = FSet.findLock (FactMan, Cp);
16061615 if (!LDat) {
1607- Analyzer-> Handler .handleNegativeNotHeld (D, Cp.toString (), Loc);
1616+ Handler.handleNegativeNotHeld (D, Cp.toString (), Loc);
16081617 }
16091618 return ;
16101619 }
16111620
1612- const FactEntry *LDat = FSet.findLockUniv (Analyzer-> FactMan , Cp);
1621+ const FactEntry *LDat = FSet.findLockUniv (FactMan, Cp);
16131622 bool NoError = true ;
16141623 if (!LDat) {
16151624 // No exact match found. Look for a partial match.
1616- LDat = FSet.findPartialMatch (Analyzer-> FactMan , Cp);
1625+ LDat = FSet.findPartialMatch (FactMan, Cp);
16171626 if (LDat) {
16181627 // Warn that there's no precise match.
16191628 std::string PartMatchStr = LDat->toString ();
16201629 StringRef PartMatchName (PartMatchStr);
1621- Analyzer-> Handler .handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (),
1622- LK, Loc, &PartMatchName);
1630+ Handler.handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (), LK, Loc ,
1631+ &PartMatchName);
16231632 } else {
16241633 // Warn that there's no match at all.
1625- Analyzer->Handler .handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (),
1626- LK, Loc);
1634+ Handler.handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (), LK, Loc);
16271635 }
16281636 NoError = false ;
16291637 }
16301638 // Make sure the mutex we found is the right kind.
16311639 if (NoError && LDat && !LDat->isAtLeast (LK)) {
1632- Analyzer->Handler .handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (),
1633- LK, Loc);
1640+ Handler.handleMutexNotHeld (Cp.getKind (), D, POK, Cp.toString (), LK, Loc);
16341641 }
16351642}
16361643
16371644// / Warn if the LSet contains the given lock.
1638- void BuildLockset::warnIfMutexHeld (const NamedDecl *D, const Expr *Exp,
1639- Expr *MutexExp, til::LiteralPtr *Self,
1640- SourceLocation Loc) {
1641- CapabilityExpr Cp =
1642- Analyzer->SxBuilder .translateAttrExpr (MutexExp, D, Exp, Self);
1645+ void ThreadSafetyAnalyzer::warnIfMutexHeld (const FactSet &FSet,
1646+ const NamedDecl *D, const Expr *Exp,
1647+ Expr *MutexExp,
1648+ til::LiteralPtr *Self,
1649+ SourceLocation Loc) {
1650+ CapabilityExpr Cp = SxBuilder.translateAttrExpr (MutexExp, D, Exp, Self);
16431651 if (Cp.isInvalid ()) {
1644- warnInvalidLock (Analyzer-> Handler , MutexExp, D, Exp, Cp.getKind ());
1652+ warnInvalidLock (Handler, MutexExp, D, Exp, Cp.getKind ());
16451653 return ;
16461654 } else if (Cp.shouldIgnore ()) {
16471655 return ;
16481656 }
16491657
1650- const FactEntry *LDat = FSet.findLock (Analyzer-> FactMan , Cp);
1658+ const FactEntry *LDat = FSet.findLock (FactMan, Cp);
16511659 if (LDat) {
1652- Analyzer-> Handler .handleFunExcludesLock (Cp.getKind (), D->getNameAsString (),
1653- Cp.toString (), Loc);
1660+ Handler.handleFunExcludesLock (Cp.getKind (), D->getNameAsString (),
1661+ Cp.toString (), Loc);
16541662 }
16551663}
16561664
@@ -1659,8 +1667,9 @@ void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr *Exp,
16591667// / marked with guarded_by, we must ensure the appropriate mutexes are held.
16601668// / Similarly, we check if the access is to an expression that dereferences
16611669// / a pointer marked with pt_guarded_by.
1662- void BuildLockset::checkAccess (const Expr *Exp, AccessKind AK,
1663- ProtectedOperationKind POK) {
1670+ void ThreadSafetyAnalyzer::checkAccess (const FactSet &FSet, const Expr *Exp,
1671+ AccessKind AK,
1672+ ProtectedOperationKind POK) {
16641673 Exp = Exp->IgnoreImplicit ()->IgnoreParenCasts ();
16651674
16661675 SourceLocation Loc = Exp->getExprLoc ();
@@ -1684,49 +1693,50 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK,
16841693 if (const auto *UO = dyn_cast<UnaryOperator>(Exp)) {
16851694 // For dereferences
16861695 if (UO->getOpcode () == UO_Deref)
1687- checkPtAccess (UO->getSubExpr (), AK, POK);
1696+ checkPtAccess (FSet, UO->getSubExpr (), AK, POK);
16881697 return ;
16891698 }
16901699
16911700 if (const auto *BO = dyn_cast<BinaryOperator>(Exp)) {
16921701 switch (BO->getOpcode ()) {
16931702 case BO_PtrMemD: // .*
1694- return checkAccess (BO->getLHS (), AK, POK);
1703+ return checkAccess (FSet, BO->getLHS (), AK, POK);
16951704 case BO_PtrMemI: // ->*
1696- return checkPtAccess (BO->getLHS (), AK, POK);
1705+ return checkPtAccess (FSet, BO->getLHS (), AK, POK);
16971706 default :
16981707 return ;
16991708 }
17001709 }
17011710
17021711 if (const auto *AE = dyn_cast<ArraySubscriptExpr>(Exp)) {
1703- checkPtAccess (AE->getLHS (), AK, POK);
1712+ checkPtAccess (FSet, AE->getLHS (), AK, POK);
17041713 return ;
17051714 }
17061715
17071716 if (const auto *ME = dyn_cast<MemberExpr>(Exp)) {
17081717 if (ME->isArrow ())
1709- checkPtAccess (ME->getBase (), AK, POK);
1718+ checkPtAccess (FSet, ME->getBase (), AK, POK);
17101719 else
1711- checkAccess (ME->getBase (), AK, POK);
1720+ checkAccess (FSet, ME->getBase (), AK, POK);
17121721 }
17131722
17141723 const ValueDecl *D = getValueDecl (Exp);
17151724 if (!D || !D->hasAttrs ())
17161725 return ;
17171726
1718- if (D->hasAttr <GuardedVarAttr>() && FSet.isEmpty (Analyzer-> FactMan )) {
1719- Analyzer-> Handler .handleNoMutexHeld (D, POK, AK, Loc);
1727+ if (D->hasAttr <GuardedVarAttr>() && FSet.isEmpty (FactMan)) {
1728+ Handler.handleNoMutexHeld (D, POK, AK, Loc);
17201729 }
17211730
17221731 for (const auto *I : D->specific_attrs <GuardedByAttr>())
1723- warnIfMutexNotHeld (D, Exp, AK, I->getArg (), POK, nullptr , Loc);
1732+ warnIfMutexNotHeld (FSet, D, Exp, AK, I->getArg (), POK, nullptr , Loc);
17241733}
17251734
17261735// / Checks pt_guarded_by and pt_guarded_var attributes.
17271736// / POK is the same operationKind that was passed to checkAccess.
1728- void BuildLockset::checkPtAccess (const Expr *Exp, AccessKind AK,
1729- ProtectedOperationKind POK) {
1737+ void ThreadSafetyAnalyzer::checkPtAccess (const FactSet &FSet, const Expr *Exp,
1738+ AccessKind AK,
1739+ ProtectedOperationKind POK) {
17301740 while (true ) {
17311741 if (const auto *PE = dyn_cast<ParenExpr>(Exp)) {
17321742 Exp = PE->getSubExpr ();
@@ -1736,7 +1746,7 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK,
17361746 if (CE->getCastKind () == CK_ArrayToPointerDecay) {
17371747 // If it's an actual array, and not a pointer, then it's elements
17381748 // are protected by GUARDED_BY, not PT_GUARDED_BY;
1739- checkAccess (CE->getSubExpr (), AK, POK);
1749+ checkAccess (FSet, CE->getSubExpr (), AK, POK);
17401750 return ;
17411751 }
17421752 Exp = CE->getSubExpr ();
@@ -1753,11 +1763,11 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK,
17531763 if (!D || !D->hasAttrs ())
17541764 return ;
17551765
1756- if (D->hasAttr <PtGuardedVarAttr>() && FSet.isEmpty (Analyzer-> FactMan ))
1757- Analyzer-> Handler .handleNoMutexHeld (D, PtPOK, AK, Exp->getExprLoc ());
1766+ if (D->hasAttr <PtGuardedVarAttr>() && FSet.isEmpty (FactMan))
1767+ Handler.handleNoMutexHeld (D, PtPOK, AK, Exp->getExprLoc ());
17581768
17591769 for (auto const *I : D->specific_attrs <PtGuardedByAttr>())
1760- warnIfMutexNotHeld (D, Exp, AK, I->getArg (), PtPOK, nullptr ,
1770+ warnIfMutexNotHeld (FSet, D, Exp, AK, I->getArg (), PtPOK, nullptr ,
17611771 Exp->getExprLoc ());
17621772}
17631773
@@ -1869,8 +1879,9 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
18691879 case attr::RequiresCapability: {
18701880 const auto *A = cast<RequiresCapabilityAttr>(At);
18711881 for (auto *Arg : A->args ()) {
1872- warnIfMutexNotHeld (D, Exp, A->isShared () ? AK_Read : AK_Written, Arg,
1873- POK_FunctionCall, Self, Loc);
1882+ Analyzer->warnIfMutexNotHeld (FSet, D, Exp,
1883+ A->isShared () ? AK_Read : AK_Written,
1884+ Arg, POK_FunctionCall, Self, Loc);
18741885 // use for adopting a lock
18751886 if (!Scp.shouldIgnore ())
18761887 Analyzer->getMutexIDs (ScopedReqsAndExcludes, A, Exp, D, Self);
@@ -1881,7 +1892,7 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
18811892 case attr::LocksExcluded: {
18821893 const auto *A = cast<LocksExcludedAttr>(At);
18831894 for (auto *Arg : A->args ()) {
1884- warnIfMutexHeld (D, Exp, Arg, Self, Loc);
1895+ Analyzer-> warnIfMutexHeld (FSet, D, Exp, Arg, Self, Loc);
18851896 // use for deferring a lock
18861897 if (!Scp.shouldIgnore ())
18871898 Analyzer->getMutexIDs (ScopedReqsAndExcludes, A, Exp, D, Self);
0 commit comments