Skip to content

Commit 04d6193

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 30deadd commit 04d6193

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
@@ -767,6 +767,64 @@ class LoanPropagationAnalysis
767767
}
768768
};
769769

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

0 commit comments

Comments
 (0)