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