Skip to content

Commit a9f1e8d

Browse files
committed
[LifetimeSafety] Add loan expiry analysis
1 parent d6c554c commit a9f1e8d

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
@@ -747,6 +747,65 @@ class LoanPropagationAnalysis
747747
}
748748
};
749749

750+
// ========================================================================= //
751+
// Expired Loans Analysis
752+
// ========================================================================= //
753+
754+
/// The lattice for tracking expired loans. It is a set of loan IDs.
755+
struct ExpiredLattice {
756+
LoanSet Expired;
757+
758+
ExpiredLattice() : Expired(nullptr) {};
759+
explicit ExpiredLattice(LoanSet S) : Expired(S) {}
760+
761+
bool operator==(const ExpiredLattice &Other) const {
762+
return Expired == Other.Expired;
763+
}
764+
bool operator!=(const ExpiredLattice &Other) const {
765+
return !(*this == Other);
766+
}
767+
768+
void dump(llvm::raw_ostream &OS) const {
769+
OS << "ExpiredLattice State:\n";
770+
if (Expired.isEmpty())
771+
OS << " <empty>\n";
772+
for (const LoanID &LID : Expired)
773+
OS << " Loan " << LID << " is expired\n";
774+
}
775+
};
776+
777+
class ExpiredLoansAnalysis
778+
: public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice> {
779+
780+
LoanSet::Factory &SetFactory;
781+
782+
public:
783+
ExpiredLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
784+
LoanSet::Factory &SF)
785+
: DataflowAnalysis(C, AC, F), SetFactory(SF) {}
786+
787+
using DataflowAnalysis<ExpiredLoansAnalysis, Lattice>::transfer;
788+
789+
const char *getAnalysisName() const { return "ExpiredLoans"; }
790+
791+
Lattice getInitialState() { return Lattice(SetFactory.getEmptySet()); }
792+
793+
Lattice join(Lattice L1, Lattice L2) const {
794+
LoanSet JoinedSet = L1.Expired;
795+
for (LoanID LID : L2.Expired)
796+
JoinedSet = SetFactory.add(JoinedSet, LID);
797+
return Lattice(JoinedSet);
798+
}
799+
800+
Lattice transfer(Lattice In, const ExpireFact &F) {
801+
return Lattice(SetFactory.add(In.Expired, F.getLoanID()));
802+
}
803+
804+
Lattice transfer(Lattice In, const IssueFact &F) {
805+
return Lattice(SetFactory.remove(In.Expired, F.getLoanID()));
806+
}
807+
};
808+
750809
// ========================================================================= //
751810
// TODO:
752811
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
@@ -779,5 +838,8 @@ void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg,
779838
LoanPropagationAnalysis LoanPropagation(Cfg, AC, FactMgr, LifetimeFact);
780839
LoanPropagation.run();
781840
DEBUG_WITH_TYPE("LifetimeLoanPropagation", LoanPropagation.dump());
841+
842+
ExpiredLoansAnalysis ExpiredAnalysis(Cfg, AC, FactMgr,
843+
LifetimeFact.LoanSetFact);
782844
}
783845
} // namespace clang

0 commit comments

Comments
 (0)