@@ -747,6 +747,65 @@ class LoanPropagationAnalysis
747
747
}
748
748
};
749
749
750
+ // ========================================================================= //
751
+ // Expired Loans Analysis
752
+ // ========================================================================= //
753
+
754
+ // / The lattice for tracking expired loans. It is a set of loan IDs.
755
+ struct ExpiredLattice {
756
+ LoanSet Expired;
757
+
758
+ ExpiredLattice () : Expired(nullptr ) {};
759
+ explicit ExpiredLattice (LoanSet S) : Expired(S) {}
760
+
761
+ bool operator ==(const ExpiredLattice &Other) const {
762
+ return Expired == Other.Expired ;
763
+ }
764
+ bool operator !=(const ExpiredLattice &Other) const {
765
+ return !(*this == Other);
766
+ }
767
+
768
+ void dump (llvm::raw_ostream &OS) const {
769
+ OS << " ExpiredLattice State:\n " ;
770
+ if (Expired.isEmpty ())
771
+ OS << " <empty>\n " ;
772
+ for (const LoanID &LID : Expired)
773
+ OS << " Loan " << LID << " is expired\n " ;
774
+ }
775
+ };
776
+
777
+ class ExpiredLoansAnalysis
778
+ : public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice> {
779
+
780
+ LoanSet::Factory &SetFactory;
781
+
782
+ public:
783
+ ExpiredLoansAnalysis (const CFG &C, AnalysisDeclContext &AC, FactManager &F,
784
+ LoanSet::Factory &SF)
785
+ : DataflowAnalysis(C, AC, F), SetFactory(SF) {}
786
+
787
+ using DataflowAnalysis<ExpiredLoansAnalysis, Lattice>::transfer;
788
+
789
+ const char *getAnalysisName () const { return " ExpiredLoans" ; }
790
+
791
+ Lattice getInitialState () { return Lattice (SetFactory.getEmptySet ()); }
792
+
793
+ Lattice join (Lattice L1, Lattice L2) const {
794
+ LoanSet JoinedSet = L1.Expired ;
795
+ for (LoanID LID : L2.Expired )
796
+ JoinedSet = SetFactory.add (JoinedSet, LID);
797
+ return Lattice (JoinedSet);
798
+ }
799
+
800
+ Lattice transfer (Lattice In, const ExpireFact &F) {
801
+ return Lattice (SetFactory.add (In.Expired , F.getLoanID ()));
802
+ }
803
+
804
+ Lattice transfer (Lattice In, const IssueFact &F) {
805
+ return Lattice (SetFactory.remove (In.Expired , F.getLoanID ()));
806
+ }
807
+ };
808
+
750
809
// ========================================================================= //
751
810
// TODO:
752
811
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -779,5 +838,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
779
838
LoanPropagationAnalysis LoanPropagation (Cfg, AC, FactMgr, LifetimeFact);
780
839
LoanPropagation.run ();
781
840
DEBUG_WITH_TYPE (" LifetimeLoanPropagation" , LoanPropagation.dump ());
841
+
842
+ ExpiredLoansAnalysis ExpiredAnalysis (Cfg, AC, FactMgr,
843
+ LifetimeFact.LoanSetFact );
782
844
}
783
845
} // namespace clang
0 commit comments