Skip to content

Commit 037a7ec

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 615b4d0 commit 037a7ec

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

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

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+
781840
// ========================================================================= //
782841
// TODO:
783842
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -810,5 +869,9 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
810869
LoanPropagationAnalysis LoanPropagation(Cfg, AC, FactMgr, Factory);
811870
LoanPropagation.run();
812871
DEBUG_WITH_TYPE("LifetimeLoanPropagation", LoanPropagation.dump());
872+
873+
ExpiredLoansAnalysis ExpiredLoans(Cfg, AC, FactMgr, Factory);
874+
ExpiredLoans.run();
875+
DEBUG_WITH_TYPE("LifetimeExpiredLoans", ExpiredLoans.dump());
813876
}
814877
} // namespace clang

0 commit comments

Comments
 (0)