@@ -762,6 +762,64 @@ class LoanPropagationAnalysis
762762 }
763763};
764764
765+ // ========================================================================= //
766+ // Expired Loans Analysis
767+ // ========================================================================= //
768+
769+ // / The dataflow lattice for tracking the set of expired loans.
770+ struct ExpiredLattice {
771+ LoanSet Expired;
772+
773+ ExpiredLattice () : Expired(nullptr ) {};
774+ explicit ExpiredLattice (LoanSet S) : Expired(S) {}
775+
776+ bool operator ==(const ExpiredLattice &Other) const {
777+ return Expired == Other.Expired ;
778+ }
779+ bool operator !=(const ExpiredLattice &Other) const {
780+ return !(*this == Other);
781+ }
782+
783+ void dump (llvm::raw_ostream &OS) const {
784+ OS << " ExpiredLattice State:\n " ;
785+ if (Expired.isEmpty ())
786+ OS << " <empty>\n " ;
787+ for (const LoanID &LID : Expired)
788+ OS << " Loan " << LID << " is expired\n " ;
789+ }
790+ };
791+
792+ // / The analysis that tracks which loans have expired.
793+ class ExpiredLoansAnalysis
794+ : public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice> {
795+
796+ LoanSet::Factory &Factory;
797+
798+ public:
799+ ExpiredLoansAnalysis (const CFG &C, AnalysisDeclContext &AC, FactManager &F,
800+ LifetimeFactory &SF)
801+ : DataflowAnalysis(C, AC, F), Factory(SF.LoanSetFactory) {}
802+
803+ using DataflowAnalysis<ExpiredLoansAnalysis, Lattice>::transfer;
804+
805+ StringRef getAnalysisName () const { return " ExpiredLoans" ; }
806+
807+ Lattice getInitialState () { return Lattice (Factory.getEmptySet ()); }
808+
809+ // / Merges two lattices by taking the union of the expired loan sets.
810+ Lattice join (Lattice L1, Lattice L2) const {
811+ return Lattice (utils::join (L1.Expired , L2.Expired , Factory));
812+ }
813+
814+ Lattice transfer (Lattice In, const ExpireFact &F) {
815+ return Lattice (Factory.add (In.Expired , F.getLoanID ()));
816+ }
817+
818+ Lattice transfer (Lattice In, const IssueFact &F) {
819+ return Lattice (Factory.remove (In.Expired , F.getLoanID ()));
820+ }
821+ };
822+
765823// ========================================================================= //
766824// TODO:
767825// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -794,5 +852,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
794852 LoanPropagationAnalysis LoanPropagation (Cfg, AC, FactMgr, Factory);
795853 LoanPropagation.run ();
796854 DEBUG_WITH_TYPE (" LifetimeLoanPropagation" , LoanPropagation.dump ());
855+
856+ ExpiredLoansAnalysis ExpiredLoans (Cfg, AC, FactMgr, Factory);
857+ ExpiredLoans.run ();
797858}
798859} // namespace clang
0 commit comments