================
@@ -136,19 +136,63 @@ class OriginFlowFact : public Fact {
const OriginManager &OM) const override;
};
+/// Represents that an origin escapes the current scope through various means.
+/// This is the base class for different escape scenarios.
class OriginEscapesFact : public Fact {
OriginID OID;
- const Expr *EscapeExpr;
public:
+ /// The way an origin can escape the current scope.
+ enum class EscapeKind : uint8_t {
+ Return, /// Escapes via return statement.
+ Field, /// Escapes via assignment to a field.
+ // FIXME: Add support for escape to global (dangling global ptr).
+ } EscKind;
+
static bool classof(const Fact *F) {
return F->getKind() == Kind::OriginEscapes;
}
- OriginEscapesFact(OriginID OID, const Expr *EscapeExpr)
- : Fact(Kind::OriginEscapes), OID(OID), EscapeExpr(EscapeExpr) {}
+ OriginEscapesFact(OriginID OID, EscapeKind EscKind)
+ : Fact(Kind::OriginEscapes), OID(OID), EscKind(EscKind) {}
OriginID getEscapedOriginID() const { return OID; }
- const Expr *getEscapeExpr() const { return EscapeExpr; };
+ EscapeKind getEscapeKind() const { return EscKind; }
+};
+
+/// Represents that an origin escapes via a return statement.
+class ReturnEscapeFact : public OriginEscapesFact {
+ const Expr *ReturnExpr;
+
+public:
+ ReturnEscapeFact(OriginID OID, const Expr *ReturnExpr)
+ : OriginEscapesFact(OID, EscapeKind::Return), ReturnExpr(ReturnExpr) {}
+
+ static bool classof(const Fact *F) {
+ return F->getKind() == Kind::OriginEscapes &&
+ static_cast<const OriginEscapesFact *>(F)->getEscapeKind() ==
+ EscapeKind::Return;
+ }
+ const Expr *getReturnExpr() const { return ReturnExpr; };
+ void dump(llvm::raw_ostream &OS, const LoanManager &,
+ const OriginManager &OM) const override;
+};
+
+/// Represents that an origin escapes via assignment to a field.
+/// Example: `this->view = local_var;` where local_var outlives the assignment
+/// but not the object containing the field.
+class FieldEscapeFact : public OriginEscapesFact {
----------------
usx95 wrote:
Hmm. This is slightly challenging to do atm. This needs some more work on
LoanPropagation dataflow to do this tracking.
The reason is we mark all the fields escaped at funciton exits. We need to
track one step back on LoanPropagation to identify which OriginFlow is
responsible of propagating the current loans to the escaped origin. That
OriginFlow could have an expression attached to it responsible for that flow.
FWIW, this goes in the direction of making the diagnostics highlight **all**
**the expressions** responsible for a loan making into a "use"/"escape". We
need to track the complete chain of originflow responsible for the current
loanset of an origin.
https://github.com/llvm/llvm-project/pull/177363
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits