Skip to content

Commit ed73e3b

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 7c28380 commit ed73e3b

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,65 @@ class LoanPropagationAnalysis
746746
return Factory.LoanSetFact.getEmptySet();
747747
}
748748
};
749+
// ========================================================================= //
750+
// Expired Loans Analysis
751+
// ========================================================================= //
752+
753+
/// The lattice for tracking expired loans. It is a set of loan IDs.
754+
struct ExpiredLattice {
755+
LoanSet Expired;
756+
757+
ExpiredLattice() : Expired(nullptr) {};
758+
explicit ExpiredLattice(LoanSet S) : Expired(S) {}
759+
760+
bool operator==(const ExpiredLattice &Other) const {
761+
return Expired == Other.Expired;
762+
}
763+
bool operator!=(const ExpiredLattice &Other) const {
764+
return !(*this == Other);
765+
}
766+
767+
void dump(llvm::raw_ostream &OS) const {
768+
OS << "ExpiredLattice State:\n";
769+
if (Expired.isEmpty())
770+
OS << " <empty>\n";
771+
for (const LoanID &LID : Expired)
772+
OS << " Loan " << LID << " is expired\n";
773+
}
774+
};
775+
776+
class ExpiredLoansAnalysis
777+
: public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice> {
778+
779+
LoanSet::Factory &SetFactory;
780+
781+
public:
782+
ExpiredLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
783+
LoanSet::Factory &SF)
784+
: DataflowAnalysis(C, AC, F), SetFactory(SF) {}
785+
786+
using DataflowAnalysis<ExpiredLoansAnalysis, Lattice>::transfer;
787+
788+
const char *getAnalysisName() const { return "ExpiredLoans"; }
789+
790+
Lattice getInitialState() { return Lattice(SetFactory.getEmptySet()); }
791+
792+
Lattice join(Lattice L1, Lattice L2) const {
793+
LoanSet JoinedSet = L1.Expired;
794+
for (LoanID LID : L2.Expired)
795+
JoinedSet = SetFactory.add(JoinedSet, LID);
796+
return Lattice(JoinedSet);
797+
}
798+
799+
Lattice transfer(Lattice In, const ExpireFact &F) {
800+
return Lattice(SetFactory.add(In.Expired, F.getLoanID()));
801+
}
802+
803+
Lattice transfer(Lattice In, const IssueFact &F) {
804+
return Lattice(SetFactory.remove(In.Expired, F.getLoanID()));
805+
}
806+
};
807+
749808
// ========================================================================= //
750809
// TODO:
751810
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -778,5 +837,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
778837
LoanPropagationAnalysis LoanPropagation(Cfg, AC, FactMgr, LifetimeFact);
779838
LoanPropagation.run();
780839
DEBUG_WITH_TYPE("LifetimeLoanPropagation", LoanPropagation.dump());
840+
841+
ExpiredLoansAnalysis ExpiredAnalysis(Cfg, AC, FactMgr,
842+
LifetimeFact.LoanSetFact);
781843
}
782844
} // namespace clang

0 commit comments

Comments
 (0)