Skip to content

Commit 6ce3173

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 542bc99 commit 6ce3173

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
@@ -763,6 +763,65 @@ class LoanPropagationAnalysis
763763
}
764764
};
765765

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

0 commit comments

Comments
 (0)