Skip to content

Commit a0b1ef0

Browse files
committed
lifetime-lattice-tracking-per-point
1 parent d9190f8 commit a0b1ef0

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

clang/lib/Analysis/LifetimeSafety.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,12 @@ class FactGenerator : public ConstStmtVisitor<FactGenerator> {
502502

503503
enum class Direction { Forward, Backward };
504504

505+
/// A program point is a pair of a CFGBlock and a Fact within that block.
506+
///
507+
/// This is used to represent the state of the program *after* the Fact is
508+
/// executed.
509+
using ProgramPoint = std::pair<const CFGBlock *, const Fact *>;
510+
505511
/// A generic, policy-based driver for dataflow analyses. It combines
506512
/// the dataflow runner and the transferer logic into a single class hierarchy.
507513
///
@@ -530,8 +536,14 @@ class DataflowAnalysis {
530536
const CFG &Cfg;
531537
AnalysisDeclContext &AC;
532538

539+
/// The dataflow state before a basic block is processed.
533540
llvm::DenseMap<const CFGBlock *, Lattice> InStates;
541+
/// The dataflow state after a basic block is processed.
534542
llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
543+
/// The dataflow state at a Program Point.
544+
/// In a forward analysis, this is the state after the Fact at that point has
545+
/// been applied, while in a backward analysis, it is the state before.
546+
llvm::DenseMap<ProgramPoint, Lattice> PerPointStates;
535547

536548
static constexpr bool isForward() { return Dir == Direction::Forward; }
537549

@@ -577,6 +589,8 @@ class DataflowAnalysis {
577589
}
578590
}
579591

592+
Lattice getState(ProgramPoint P) const { return PerPointStates.lookup(P); }
593+
580594
Lattice getInState(const CFGBlock *B) const { return InStates.lookup(B); }
581595

582596
Lattice getOutState(const CFGBlock *B) const { return OutStates.lookup(B); }
@@ -590,18 +604,23 @@ class DataflowAnalysis {
590604
getOutState(&B).dump(llvm::dbgs());
591605
}
592606

607+
private:
593608
/// Computes the state at one end of a block by applying all its facts
594609
/// sequentially to a given state from the other end.
595-
/// TODO: We might need to store intermediate states per-fact in the block for
596-
/// later analysis.
597610
Lattice transferBlock(const CFGBlock *Block, Lattice State) {
598611
auto Facts = AllFacts.getFacts(Block);
599-
if constexpr (isForward())
600-
for (const Fact *F : Facts)
612+
if constexpr (isForward()) {
613+
for (const Fact *F : Facts) {
601614
State = transferFact(State, F);
602-
else
603-
for (const Fact *F : llvm::reverse(Facts))
615+
PerPointStates[{Block, F}] = State;
616+
}
617+
} else {
618+
for (const Fact *F : llvm::reverse(Facts)) {
619+
// In backward analysis, capture the state before applying the fact.
620+
PerPointStates[{Block, F}] = State;
604621
State = transferFact(State, F);
622+
}
623+
}
605624
return State;
606625
}
607626

@@ -769,6 +788,10 @@ class LoanPropagationAnalysis
769788
Factory.OriginMapFactory.add(In.Origins, DestOID, SrcLoans));
770789
}
771790

791+
LoanSet getLoans(OriginID OID, ProgramPoint P) {
792+
return getLoans(getState(P), OID);
793+
}
794+
772795
private:
773796
LoanSet getLoans(Lattice L, OriginID OID) {
774797
if (auto *Loans = L.Origins.lookup(OID))
@@ -779,7 +802,6 @@ class LoanPropagationAnalysis
779802

780803
// ========================================================================= //
781804
// TODO:
782-
// - Modifying loan propagation to answer `LoanSet getLoans(Origin O, Point P)`
783805
// - Modify loan expiry analysis to answer `bool isExpired(Loan L, Point P)`
784806
// - Modify origin liveness analysis to answer `bool isLive(Origin O, Point P)`
785807
// - Using the above three to perform the final error reporting.

0 commit comments

Comments
 (0)