Skip to content

Commit aca68c2

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent c808997 commit aca68c2

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,65 @@ class LoanPropagationAnalysis
777777
}
778778
};
779779

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+
780839
// ========================================================================= //
781840
// TODO:
782841
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -809,5 +868,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
809868
LoanPropagationAnalysis LoanPropagation(Cfg, AC, FactMgr, Factory);
810869
LoanPropagation.run();
811870
DEBUG_WITH_TYPE("LifetimeLoanPropagation", LoanPropagation.dump());
871+
872+
ExpiredLoansAnalysis ExpiredLoans(Cfg, AC, FactMgr, Factory);
873+
ExpiredLoans.run();
812874
}
813875
} // namespace clang

0 commit comments

Comments
 (0)