Skip to content

Commit 2073937

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent 111163f commit 2073937

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
@@ -775,6 +775,65 @@ class LoanPropagationAnalysis
775775
}
776776
};
777777

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

0 commit comments

Comments
 (0)