================
@@ -97,48 +102,64 @@ class IssueFact : public Fact {
   LoanID getLoanID() const { return LID; }
   OriginID getOriginID() const { return OID; }
   void dump(llvm::raw_ostream &OS, const LoanManager &LM,
-            const OriginManager &OM) const override;
+            const OriginManager &OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
+/// Represents the expiration of loans at a specific storage location.
+///
+/// When an AccessPath expires (e.g., a variable goes out of scope), all loans
+/// that are prefixed by this path expire. For example, if `x` expires, then
+/// loans to `x`, `x.field`, and `x.field.*` all expire.
 class ExpireFact : public Fact {
-  LoanID LID;
+  /// The access path that expires (e.g., the variable going out of scope).
+  AccessPath AP;
   SourceLocation ExpiryLoc;
 
 public:
   static bool classof(const Fact *F) { return F->getKind() == Kind::Expire; }
 
-  ExpireFact(LoanID LID, SourceLocation ExpiryLoc)
-      : Fact(Kind::Expire), LID(LID), ExpiryLoc(ExpiryLoc) {}
+  ExpireFact(AccessPath AP, SourceLocation ExpiryLoc)
+      : Fact(Kind::Expire), AP(AP), ExpiryLoc(ExpiryLoc) {}
 
-  LoanID getLoanID() const { return LID; }
+  const AccessPath &getAccessPath() const { return AP; }
   SourceLocation getExpiryLoc() const { return ExpiryLoc; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &LM,
-            const OriginManager &) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &LM, const OriginManager 
&,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 class OriginFlowFact : public Fact {
   OriginID OIDDest;
   OriginID OIDSrc;
-  // True if the destination origin should be killed (i.e., its current loans
-  // cleared) before the source origin's loans are flowed into it.
+  /// True if the destination origin should be killed (i.e., its current loans
+  /// cleared) before the source origin's loans are flowed into it.
   bool KillDest;
+  /// If set, the source origin's loans are extended by this path element 
before
+  /// flowing into the destination.
+  ///
+  /// Example: If source has loan to `x` and Element=field, then destination
+  /// receives loan to `x.field`. This is used for member expressions like
+  /// `p = obj.field;` where `p` gets a loan to `obj.field`.
+  std::optional<PathElement> AddToPath;
----------------
Xazax-hun wrote:

I do not have a strong feeling here, just wondering if a new kind of fact, 
something like a "projection" would make sense to represent this scenario. 

https://github.com/llvm/llvm-project/pull/180369
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to