Skip to content

Commit 9265536

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 2469673 commit 9265536

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,64 @@ class LoanPropagationAnalysis
762762
}
763763
};
764764

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+
765823
// ========================================================================= //
766824
// TODO:
767825
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -794,5 +852,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
794852
LoanPropagationAnalysis LoanPropagation(Cfg, AC, FactMgr, Factory);
795853
LoanPropagation.run();
796854
DEBUG_WITH_TYPE("LifetimeLoanPropagation", LoanPropagation.dump());
855+
856+
ExpiredLoansAnalysis ExpiredLoans(Cfg, AC, FactMgr, Factory);
857+
ExpiredLoans.run();
797858
}
798859
} // namespace clang

0 commit comments

Comments
 (0)