@@ -777,6 +777,65 @@ class LoanPropagationAnalysis
777
777
}
778
778
};
779
779
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 &SF)
817
+ : DataflowAnalysis(C, AC, F), Factory(SF.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
+
780
839
// ========================================================================= //
781
840
// TODO:
782
841
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -809,5 +868,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
809
868
LoanPropagationAnalysis LoanPropagation (Cfg, AC, FactMgr, Factory);
810
869
LoanPropagation.run ();
811
870
DEBUG_WITH_TYPE (" LifetimeLoanPropagation" , LoanPropagation.dump ());
871
+
872
+ ExpiredLoansAnalysis ExpiredLoans (Cfg, AC, FactMgr, Factory);
873
+ ExpiredLoans.run ();
812
874
}
813
875
} // namespace clang
0 commit comments