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