@@ -778,6 +778,65 @@ class LoanPropagationAnalysis
778778 }
779779};
780780
781+ // ========================================================================= //
782+ // Expired Loans Analysis
783+ // ========================================================================= //
784+
785+ // / The dataflow lattice for tracking the set of expired loans.
786+ struct ExpiredLattice {
787+ LoanSet Expired;
788+
789+ ExpiredLattice () : Expired(nullptr ) {};
790+ explicit ExpiredLattice (LoanSet S) : Expired(S) {}
791+
792+ bool operator ==(const ExpiredLattice &Other) const {
793+ return Expired == Other.Expired ;
794+ }
795+ bool operator !=(const ExpiredLattice &Other) const {
796+ return !(*this == Other);
797+ }
798+
799+ void dump (llvm::raw_ostream &OS) const {
800+ OS << " ExpiredLattice State:\n " ;
801+ if (Expired.isEmpty ())
802+ OS << " <empty>\n " ;
803+ for (const LoanID &LID : Expired)
804+ OS << " Loan " << LID << " is expired\n " ;
805+ }
806+ };
807+
808+ // / The analysis that tracks which loans have expired.
809+ class ExpiredLoansAnalysis
810+ : public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice,
811+ Direction::Forward> {
812+
813+ LoanSet::Factory &Factory;
814+
815+ public:
816+ ExpiredLoansAnalysis (const CFG &C, AnalysisDeclContext &AC, FactManager &F,
817+ LifetimeFactory &Factory)
818+ : DataflowAnalysis(C, AC, F), Factory(Factory.LoanSetFactory) {}
819+
820+ using Base::transfer;
821+
822+ StringRef getAnalysisName () const { return " ExpiredLoans" ; }
823+
824+ Lattice getInitialState () { return Lattice (Factory.getEmptySet ()); }
825+
826+ // / Merges two lattices by taking the union of the expired loan sets.
827+ Lattice join (Lattice L1, Lattice L2) const {
828+ return Lattice (utils::join (L1.Expired , L2.Expired , Factory));
829+ }
830+
831+ Lattice transfer (Lattice In, const ExpireFact &F) {
832+ return Lattice (Factory.add (In.Expired , F.getLoanID ()));
833+ }
834+
835+ Lattice transfer (Lattice In, const IssueFact &F) {
836+ return Lattice (Factory.remove (In.Expired , F.getLoanID ()));
837+ }
838+ };
839+
781840// ========================================================================= //
782841// TODO:
783842// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -810,5 +869,9 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
810869 LoanPropagationAnalysis LoanPropagation (Cfg, AC, FactMgr, Factory);
811870 LoanPropagation.run ();
812871 DEBUG_WITH_TYPE (" LifetimeLoanPropagation" , LoanPropagation.dump ());
872+
873+ ExpiredLoansAnalysis ExpiredLoans (Cfg, AC, FactMgr, Factory);
874+ ExpiredLoans.run ();
875+ DEBUG_WITH_TYPE (" LifetimeExpiredLoans" , ExpiredLoans.dump ());
813876}
814877} // namespace clang
0 commit comments