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