[llvm-branch-commits] [clang] [LifetimeSafety] Add loan expiry analysis (PR #148712)
Utkarsh Saxena via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 17 10:48:17 PDT 2025
https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/148712
>From d5b093e806ca03355eaa76ca7cf5bba252a92ad3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Mon, 14 Jul 2025 19:37:49 +0000
Subject: [PATCH] [LifetimeSafety] Add loan expiry analysis
---
.../clang/Analysis/Analyses/LifetimeSafety.h | 2 +
clang/lib/Analysis/LifetimeSafety.cpp | 64 +++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index f5ce23848448f..3d301941790df 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -33,6 +33,7 @@ namespace internal {
class Fact;
class FactManager;
class LoanPropagationAnalysis;
+class ExpiredLoansAnalysis;
struct LifetimeFactory;
/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -96,6 +97,7 @@ class LifetimeSafetyAnalysis {
std::unique_ptr<LifetimeFactory> Factory;
std::unique_ptr<FactManager> FactMgr;
std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
+ std::unique_ptr<ExpiredLoansAnalysis> ExpiredLoans;
};
} // namespace internal
} // namespace clang::lifetimes
diff --git a/clang/lib/Analysis/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety.cpp
index 22c724dbd6ed9..bbd944daffb75 100644
--- a/clang/lib/Analysis/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/TimeProfiler.h"
#include <cstdint>
+#include <memory>
namespace clang::lifetimes {
namespace internal {
@@ -832,6 +833,65 @@ class LoanPropagationAnalysis
}
};
+// ========================================================================= //
+// Expired Loans Analysis
+// ========================================================================= //
+
+/// The dataflow lattice for tracking the set of expired loans.
+struct ExpiredLattice {
+ LoanSet Expired;
+
+ ExpiredLattice() : Expired(nullptr) {};
+ explicit ExpiredLattice(LoanSet S) : Expired(S) {}
+
+ bool operator==(const ExpiredLattice &Other) const {
+ return Expired == Other.Expired;
+ }
+ bool operator!=(const ExpiredLattice &Other) const {
+ return !(*this == Other);
+ }
+
+ void dump(llvm::raw_ostream &OS) const {
+ OS << "ExpiredLattice State:\n";
+ if (Expired.isEmpty())
+ OS << " <empty>\n";
+ for (const LoanID &LID : Expired)
+ OS << " Loan " << LID << " is expired\n";
+ }
+};
+
+/// The analysis that tracks which loans have expired.
+class ExpiredLoansAnalysis
+ : public DataflowAnalysis<ExpiredLoansAnalysis, ExpiredLattice,
+ Direction::Forward> {
+
+ LoanSet::Factory &Factory;
+
+public:
+ ExpiredLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
+ LifetimeFactory &Factory)
+ : DataflowAnalysis(C, AC, F), Factory(Factory.LoanSetFactory) {}
+
+ using Base::transfer;
+
+ StringRef getAnalysisName() const { return "ExpiredLoans"; }
+
+ Lattice getInitialState() { return Lattice(Factory.getEmptySet()); }
+
+ /// Merges two lattices by taking the union of the expired loan sets.
+ Lattice join(Lattice L1, Lattice L2) const {
+ return Lattice(utils::join(L1.Expired, L2.Expired, Factory));
+ }
+
+ Lattice transfer(Lattice In, const ExpireFact &F) {
+ return Lattice(Factory.add(In.Expired, F.getLoanID()));
+ }
+
+ Lattice transfer(Lattice In, const IssueFact &F) {
+ return Lattice(Factory.remove(In.Expired, F.getLoanID()));
+ }
+};
+
// ========================================================================= //
// TODO:
// - Modify loan expiry analysis to answer `bool isExpired(Loan L, Point P)`
@@ -872,6 +932,10 @@ void LifetimeSafetyAnalysis::run() {
LoanPropagation =
std::make_unique<LoanPropagationAnalysis>(Cfg, AC, *FactMgr, *Factory);
LoanPropagation->run();
+
+ ExpiredLoans =
+ std::make_unique<ExpiredLoansAnalysis>(Cfg, AC, *FactMgr, *Factory);
+ ExpiredLoans->run();
}
LoanSet LifetimeSafetyAnalysis::getLoansAtPoint(OriginID OID,
More information about the llvm-branch-commits
mailing list