================
@@ -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