https://github.com/AbhinavPradeep created 
https://github.com/llvm/llvm-project/pull/186126

This is a draft PR. So far:
1. Added new fact `CallEscapeFact`. This stores a pointer to the call like 
expresion (currently a union of `CallExpr *` and `CXXConstructExpr *` as these 
are the call like expressions the analysis handles). 

>From 45b8ecad6e32b1e70edd5b58d701d07e54087ce0 Mon Sep 17 00:00:00 2001
From: Abhinav Pradeep <[email protected]>
Date: Fri, 13 Mar 2026 00:21:23 +1000
Subject: [PATCH] Added new CallEscapeFact.

---
 .../Analysis/Analyses/LifetimeSafety/Facts.h  | 37 +++++++++++++++++++
 clang/lib/Analysis/LifetimeSafety/Facts.cpp   |  7 ++++
 2 files changed, 44 insertions(+)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
index 42a71fb5a50d2..11ab374a5e82c 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
@@ -15,11 +15,13 @@
 #define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_FACTS_H
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
 #include "clang/Analysis/Analyses/LifetimeSafety/Loans.h"
 #include "clang/Analysis/Analyses/LifetimeSafety/Origins.h"
 #include "clang/Analysis/Analyses/LifetimeSafety/Utils.h"
 #include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
@@ -153,6 +155,7 @@ class OriginEscapesFact : public Fact {
     Return, /// Escapes via return statement.
     Field,  /// Escapes via assignment to a field.
     Global, /// Escapes via assignment to global storage.
+    Call,   /// Escapes as argument to a function call.
   } EscKind;
 
   static bool classof(const Fact *F) {
@@ -222,6 +225,40 @@ class GlobalEscapeFact : public OriginEscapesFact {
             const OriginManager &OM) const override;
 };
 
+/// Represents escape of an origin through a function call.
+/// Example:
+/// void f(int *i);
+/// void g(int *j[[clang::noescape]]) {f(j)};
+/// This fact enables us to catch that the noescape parameter j escapes through
+/// the call to function f
+class CallEscapeFact : public OriginEscapesFact {
+  // Currently the analysis handles the following call-like expressions:
+  // - VisitCXXOperatorCallExpr to handle CXXOperatorCallExpr, a sub-class of
+  // CallExpr.
+  // - VisitCXXMemberCallExpr to handle CXXMemberCallExpr, a sub-class of
+  // CallExpr.
+  // - VisitCXXConstructExpr and handleGSLPointerConstruction deal with
+  // CXXConstructExpr. Whilst call like, it is not a sub-class of CallExpr.
+  // Therefore, this type is taken to be the union of CallExpr * and
+  // CXXConstructExpr *:
+  using CallLikeExprPtr = llvm::PointerUnion<CallExpr *, CXXConstructExpr *>;
+  const CallLikeExprPtr Call;
+  const unsigned ArgumentIndex;
+
+public:
+  CallEscapeFact(OriginID OID, const CallLikeExprPtr Call, const unsigned 
Index)
+      : OriginEscapesFact(OID, EscapeKind::Call), Call(Call),
+        ArgumentIndex(Index) {}
+  static bool classof(const Fact *F) {
+    return F->getKind() == Kind::OriginEscapes &&
+           static_cast<const OriginEscapesFact *>(F)->getEscapeKind() ==
+               EscapeKind::Call;
+  }
+  const CallLikeExprPtr getCall() const { return Call; };
+  void dump(llvm::raw_ostream &OS, const LoanManager &,
+            const OriginManager &OM) const override;
+};
+
 class UseFact : public Fact {
   const Expr *UseExpr;
   const OriginList *OList;
diff --git a/clang/lib/Analysis/LifetimeSafety/Facts.cpp 
b/clang/lib/Analysis/LifetimeSafety/Facts.cpp
index 4ffc8b4195949..b03b3f7ec8a0f 100644
--- a/clang/lib/Analysis/LifetimeSafety/Facts.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Facts.cpp
@@ -76,6 +76,13 @@ void GlobalEscapeFact::dump(llvm::raw_ostream &OS, const 
LoanManager &,
   OS << ", via Global)\n";
 }
 
+void CallEscapeFact::dump(llvm::raw_ostream &OS, const LoanManager &,
+                          const OriginManager &OM) const {
+  OS << "CallEscapes (";
+  OM.dump(getEscapedOriginID(), OS);
+  OS << ", via Call)\n";
+}
+
 void UseFact::dump(llvm::raw_ostream &OS, const LoanManager &,
                    const OriginManager &OM) const {
   OS << "Use (";

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

Reply via email to