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