@@ -1055,6 +1055,19 @@ class ThreadSafetyAnalyzer {
1055
1055
}
1056
1056
1057
1057
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);
1058
1071
};
1059
1072
1060
1073
} // namespace
@@ -1534,16 +1547,15 @@ class BuildLockset : public ConstStmtVisitor<BuildLockset> {
1534
1547
unsigned CtxIndex;
1535
1548
1536
1549
// 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);
1542
1550
1543
1551
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
+ }
1545
1555
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
+ }
1547
1559
1548
1560
void handleCall (const Expr *Exp, const NamedDecl *D,
1549
1561
til::LiteralPtr *Self = nullptr ,
@@ -1571,86 +1583,82 @@ class BuildLockset : public ConstStmtVisitor<BuildLockset> {
1571
1583
1572
1584
// / Warn if the LSet does not contain a lock sufficient to protect access
1573
1585
// / 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) {
1579
1590
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);
1583
1592
if (Cp.isInvalid ()) {
1584
- warnInvalidLock (Analyzer-> Handler , MutexExp, D, Exp, Cp.getKind ());
1593
+ warnInvalidLock (Handler, MutexExp, D, Exp, Cp.getKind ());
1585
1594
return ;
1586
1595
} else if (Cp.shouldIgnore ()) {
1587
1596
return ;
1588
1597
}
1589
1598
1590
1599
if (Cp.negative ()) {
1591
1600
// Negative capabilities act like locks excluded
1592
- const FactEntry *LDat = FSet.findLock (Analyzer-> FactMan , !Cp);
1601
+ const FactEntry *LDat = FSet.findLock (FactMan, !Cp);
1593
1602
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);
1596
1605
return ;
1597
1606
}
1598
1607
1599
1608
// If this does not refer to a negative capability in the same class,
1600
1609
// then stop here.
1601
- if (!Analyzer-> inCurrentScope (Cp))
1610
+ if (!inCurrentScope (Cp))
1602
1611
return ;
1603
1612
1604
1613
// Otherwise the negative requirement must be propagated to the caller.
1605
- LDat = FSet.findLock (Analyzer-> FactMan , Cp);
1614
+ LDat = FSet.findLock (FactMan, Cp);
1606
1615
if (!LDat) {
1607
- Analyzer-> Handler .handleNegativeNotHeld (D, Cp.toString (), Loc);
1616
+ Handler.handleNegativeNotHeld (D, Cp.toString (), Loc);
1608
1617
}
1609
1618
return ;
1610
1619
}
1611
1620
1612
- const FactEntry *LDat = FSet.findLockUniv (Analyzer-> FactMan , Cp);
1621
+ const FactEntry *LDat = FSet.findLockUniv (FactMan, Cp);
1613
1622
bool NoError = true ;
1614
1623
if (!LDat) {
1615
1624
// No exact match found. Look for a partial match.
1616
- LDat = FSet.findPartialMatch (Analyzer-> FactMan , Cp);
1625
+ LDat = FSet.findPartialMatch (FactMan, Cp);
1617
1626
if (LDat) {
1618
1627
// Warn that there's no precise match.
1619
1628
std::string PartMatchStr = LDat->toString ();
1620
1629
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);
1623
1632
} else {
1624
1633
// 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);
1627
1635
}
1628
1636
NoError = false ;
1629
1637
}
1630
1638
// Make sure the mutex we found is the right kind.
1631
1639
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);
1634
1641
}
1635
1642
}
1636
1643
1637
1644
// / 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);
1643
1651
if (Cp.isInvalid ()) {
1644
- warnInvalidLock (Analyzer-> Handler , MutexExp, D, Exp, Cp.getKind ());
1652
+ warnInvalidLock (Handler, MutexExp, D, Exp, Cp.getKind ());
1645
1653
return ;
1646
1654
} else if (Cp.shouldIgnore ()) {
1647
1655
return ;
1648
1656
}
1649
1657
1650
- const FactEntry *LDat = FSet.findLock (Analyzer-> FactMan , Cp);
1658
+ const FactEntry *LDat = FSet.findLock (FactMan, Cp);
1651
1659
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);
1654
1662
}
1655
1663
}
1656
1664
@@ -1659,8 +1667,9 @@ void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr *Exp,
1659
1667
// / marked with guarded_by, we must ensure the appropriate mutexes are held.
1660
1668
// / Similarly, we check if the access is to an expression that dereferences
1661
1669
// / 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) {
1664
1673
Exp = Exp->IgnoreImplicit ()->IgnoreParenCasts ();
1665
1674
1666
1675
SourceLocation Loc = Exp->getExprLoc ();
@@ -1684,49 +1693,50 @@ void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK,
1684
1693
if (const auto *UO = dyn_cast<UnaryOperator>(Exp)) {
1685
1694
// For dereferences
1686
1695
if (UO->getOpcode () == UO_Deref)
1687
- checkPtAccess (UO->getSubExpr (), AK, POK);
1696
+ checkPtAccess (FSet, UO->getSubExpr (), AK, POK);
1688
1697
return ;
1689
1698
}
1690
1699
1691
1700
if (const auto *BO = dyn_cast<BinaryOperator>(Exp)) {
1692
1701
switch (BO->getOpcode ()) {
1693
1702
case BO_PtrMemD: // .*
1694
- return checkAccess (BO->getLHS (), AK, POK);
1703
+ return checkAccess (FSet, BO->getLHS (), AK, POK);
1695
1704
case BO_PtrMemI: // ->*
1696
- return checkPtAccess (BO->getLHS (), AK, POK);
1705
+ return checkPtAccess (FSet, BO->getLHS (), AK, POK);
1697
1706
default :
1698
1707
return ;
1699
1708
}
1700
1709
}
1701
1710
1702
1711
if (const auto *AE = dyn_cast<ArraySubscriptExpr>(Exp)) {
1703
- checkPtAccess (AE->getLHS (), AK, POK);
1712
+ checkPtAccess (FSet, AE->getLHS (), AK, POK);
1704
1713
return ;
1705
1714
}
1706
1715
1707
1716
if (const auto *ME = dyn_cast<MemberExpr>(Exp)) {
1708
1717
if (ME->isArrow ())
1709
- checkPtAccess (ME->getBase (), AK, POK);
1718
+ checkPtAccess (FSet, ME->getBase (), AK, POK);
1710
1719
else
1711
- checkAccess (ME->getBase (), AK, POK);
1720
+ checkAccess (FSet, ME->getBase (), AK, POK);
1712
1721
}
1713
1722
1714
1723
const ValueDecl *D = getValueDecl (Exp);
1715
1724
if (!D || !D->hasAttrs ())
1716
1725
return ;
1717
1726
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);
1720
1729
}
1721
1730
1722
1731
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);
1724
1733
}
1725
1734
1726
1735
// / Checks pt_guarded_by and pt_guarded_var attributes.
1727
1736
// / 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) {
1730
1740
while (true ) {
1731
1741
if (const auto *PE = dyn_cast<ParenExpr>(Exp)) {
1732
1742
Exp = PE->getSubExpr ();
@@ -1736,7 +1746,7 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK,
1736
1746
if (CE->getCastKind () == CK_ArrayToPointerDecay) {
1737
1747
// If it's an actual array, and not a pointer, then it's elements
1738
1748
// are protected by GUARDED_BY, not PT_GUARDED_BY;
1739
- checkAccess (CE->getSubExpr (), AK, POK);
1749
+ checkAccess (FSet, CE->getSubExpr (), AK, POK);
1740
1750
return ;
1741
1751
}
1742
1752
Exp = CE->getSubExpr ();
@@ -1753,11 +1763,11 @@ void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK,
1753
1763
if (!D || !D->hasAttrs ())
1754
1764
return ;
1755
1765
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 ());
1758
1768
1759
1769
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 ,
1761
1771
Exp->getExprLoc ());
1762
1772
}
1763
1773
@@ -1869,8 +1879,9 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
1869
1879
case attr::RequiresCapability: {
1870
1880
const auto *A = cast<RequiresCapabilityAttr>(At);
1871
1881
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);
1874
1885
// use for adopting a lock
1875
1886
if (!Scp.shouldIgnore ())
1876
1887
Analyzer->getMutexIDs (ScopedReqsAndExcludes, A, Exp, D, Self);
@@ -1881,7 +1892,7 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
1881
1892
case attr::LocksExcluded: {
1882
1893
const auto *A = cast<LocksExcludedAttr>(At);
1883
1894
for (auto *Arg : A->args ()) {
1884
- warnIfMutexHeld (D, Exp, Arg, Self, Loc);
1895
+ Analyzer-> warnIfMutexHeld (FSet, D, Exp, Arg, Self, Loc);
1885
1896
// use for deferring a lock
1886
1897
if (!Scp.shouldIgnore ())
1887
1898
Analyzer->getMutexIDs (ScopedReqsAndExcludes, A, Exp, D, Self);
0 commit comments