https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/207526

>From e651381f27609025e4896943ddc92ef46f7b86dc Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Sat, 4 Jul 2026 16:44:49 +0000
Subject: [PATCH] [LifetimeSafety][NFC] Support printing propagated loans in
 Fact::dump

This patch updates Fact::dump to accept an optional LoanPropagationAnalysis 
parameter.
If provided, OriginFlowFact::dump will query it to print the loans held by the 
destination origin.

This enables richer debug output for LifetimeFacts.

TAG=agy
CONV=2cfd8d00-18d7-4a03-8d78-2aba2f9a8f23
---
 .../Analysis/Analyses/LifetimeSafety/Facts.h  | 51 ++++++++-------
 clang/lib/Analysis/LifetimeSafety/Facts.cpp   | 56 +++++++++++-----
 .../LifetimeSafety/LifetimeSafety.cpp         | 10 +--
 .../Sema/LifetimeSafety/lifetime-facts.cpp    | 64 +++++++++----------
 4 files changed, 108 insertions(+), 73 deletions(-)

diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
index 5c671a93b149c..8dccccc0f2257 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
@@ -23,11 +23,14 @@
 #include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
 #include <cstdint>
 #include <optional>
 
 namespace clang::lifetimes::internal {
 
+class LoanPropagationAnalysis;
+
 using FactID = utils::ID<struct FactTag>;
 
 /// An abstract base class for a single, atomic lifetime-relevant event.
@@ -80,7 +83,8 @@ class Fact {
   }
 
   virtual void dump(llvm::raw_ostream &OS, const LoanManager &,
-                    const OriginManager &) const;
+                    const OriginManager &,
+                    const LoanPropagationAnalysis *LPA = nullptr) const;
 };
 
 /// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
@@ -101,7 +105,8 @@ 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;
 };
 
 /// When an AccessPath expires (e.g., a variable goes out of scope), all loans
@@ -127,7 +132,8 @@ class ExpireFact : public Fact {
   SourceLocation getExpiryLoc() const { return ExpiryLoc; }
 
   void dump(llvm::raw_ostream &OS, const LoanManager &LM,
-            const OriginManager &OM) const override;
+            const OriginManager &OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 class OriginFlowFact : public Fact {
@@ -150,8 +156,8 @@ class OriginFlowFact : public Fact {
   OriginID getSrcOriginID() const { return OIDSrc; }
   bool getKillDest() const { return KillDest; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// Represents that an origin escapes the current scope through various means.
@@ -191,8 +197,8 @@ class ReturnEscapeFact : public OriginEscapesFact {
                EscapeKind::Return;
   }
   const Expr *getReturnExpr() const { return ReturnExpr; };
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// Represents that an origin escapes via assignment to a field.
@@ -211,8 +217,8 @@ class FieldEscapeFact : public OriginEscapesFact {
                EscapeKind::Field;
   }
   const FieldDecl *getFieldDecl() const { return FDecl; };
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// Represents that an origin escapes via assignment to global or static
@@ -230,8 +236,8 @@ class GlobalEscapeFact : public OriginEscapesFact {
                EscapeKind::Global;
   }
   const VarDecl *getGlobal() const { return Global; };
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 class UseFact : public Fact {
@@ -253,8 +259,8 @@ class UseFact : public Fact {
   void markAsWritten() { IsWritten = true; }
   bool isWritten() const { return IsWritten; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// Represents that an origin's storage has been invalidated by a container
@@ -276,8 +282,8 @@ class InvalidateOriginFact : public Fact {
 
   OriginID getInvalidatedOrigin() const { return OID; }
   const Expr *getInvalidationExpr() const { return InvalidationExpr; }
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// Top-level origin of the expression which was found to be moved, e.g, when
@@ -297,8 +303,8 @@ class MovedOriginFact : public Fact {
   OriginID getMovedOrigin() const { return MovedOrigin; }
   const Expr *getMoveExpr() const { return MoveExpr; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// A dummy-fact used to mark a specific point in the code for testing.
@@ -314,8 +320,8 @@ class TestPointFact : public Fact {
 
   StringRef getAnnotation() const { return Annotation; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 /// All loans are cleared from an origin (e.g., assigning a callable without
@@ -332,8 +338,8 @@ class KillOriginFact : public Fact {
 
   OriginID getKilledOrigin() const { return OID; }
 
-  void dump(llvm::raw_ostream &OS, const LoanManager &,
-            const OriginManager &OM) const override;
+  void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager 
&OM,
+            const LoanPropagationAnalysis *LPA = nullptr) const override;
 };
 
 class FactManager {
@@ -363,7 +369,8 @@ class FactManager {
     return Res;
   }
 
-  void dump(const CFG &Cfg, AnalysisDeclContext &AC) const;
+  void dump(const CFG &Cfg, AnalysisDeclContext &AC,
+            const LoanPropagationAnalysis *LPA = nullptr) const;
 
   /// Retrieves program points that were specially marked in the source code
   /// for testing.
diff --git a/clang/lib/Analysis/LifetimeSafety/Facts.cpp 
b/clang/lib/Analysis/LifetimeSafety/Facts.cpp
index 3d7fbcdacc830..44852a1333744 100644
--- a/clang/lib/Analysis/LifetimeSafety/Facts.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Facts.cpp
@@ -7,18 +7,20 @@
 
//===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h"
 #include "clang/AST/Decl.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
 
 namespace clang::lifetimes::internal {
 
 void Fact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                const OriginManager &) const {
+                const OriginManager &, const LoanPropagationAnalysis *) const {
   OS << "Fact (Kind: " << static_cast<int>(K) << ")\n";
 }
 
 void IssueFact::dump(llvm::raw_ostream &OS, const LoanManager &LM,
-                     const OriginManager &OM) const {
+                     const OriginManager &OM,
+                     const LoanPropagationAnalysis *) const {
   OS << "Issue (";
   LM.getLoan(getLoanID())->dump(OS);
   OS << ", ToOrigin: ";
@@ -27,7 +29,8 @@ void IssueFact::dump(llvm::raw_ostream &OS, const LoanManager 
&LM,
 }
 
 void ExpireFact::dump(llvm::raw_ostream &OS, const LoanManager &LM,
-                      const OriginManager &OM) const {
+                      const OriginManager &OM,
+                      const LoanPropagationAnalysis *LPA) const {
   OS << "Expire (";
   getAccessPath().dump(OS);
   if (auto OID = getOriginID()) {
@@ -37,11 +40,25 @@ void ExpireFact::dump(llvm::raw_ostream &OS, const 
LoanManager &LM,
   OS << ")\n";
 }
 
-void OriginFlowFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                          const OriginManager &OM) const {
+void OriginFlowFact::dump(llvm::raw_ostream &OS, const LoanManager &LM,
+                          const OriginManager &OM,
+                          const LoanPropagationAnalysis *LPA) const {
   OS << "OriginFlow: \n";
   OS << "\tDest: ";
   OM.dump(getDestOriginID(), OS);
+  if (LPA) {
+    LoanSet DestinationLoans = LPA->getLoans(getDestOriginID(), this);
+    if (DestinationLoans.isEmpty())
+      OS << " has no loans";
+    else {
+      OS << " has loans to { ";
+      for (LoanID LID : DestinationLoans) {
+        LM.getLoan(LID)->getAccessPath().dump(OS);
+        OS << " ";
+      }
+      OS << "}";
+    }
+  }
   OS << "\n";
   OS << "\tSrc:  ";
   OM.dump(getSrcOriginID(), OS);
@@ -50,35 +67,40 @@ void OriginFlowFact::dump(llvm::raw_ostream &OS, const 
LoanManager &,
 }
 
 void MovedOriginFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                           const OriginManager &OM) const {
+                           const OriginManager &OM,
+                           const LoanPropagationAnalysis *) const {
   OS << "MovedOrigins (";
   OM.dump(getMovedOrigin(), OS);
   OS << ")\n";
 }
 
 void ReturnEscapeFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                            const OriginManager &OM) const {
+                            const OriginManager &OM,
+                            const LoanPropagationAnalysis *) const {
   OS << "OriginEscapes (";
   OM.dump(getEscapedOriginID(), OS);
   OS << ", via Return)\n";
 }
 
 void FieldEscapeFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                           const OriginManager &OM) const {
+                           const OriginManager &OM,
+                           const LoanPropagationAnalysis *) const {
   OS << "OriginEscapes (";
   OM.dump(getEscapedOriginID(), OS);
   OS << ", via Field)\n";
 }
 
 void GlobalEscapeFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                            const OriginManager &OM) const {
+                            const OriginManager &OM,
+                            const LoanPropagationAnalysis *) const {
   OS << "OriginEscapes (";
   OM.dump(getEscapedOriginID(), OS);
   OS << ", via Global)\n";
 }
 
 void UseFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                   const OriginManager &OM) const {
+                   const OriginManager &OM,
+                   const LoanPropagationAnalysis *) const {
   OS << "Use (";
   size_t NumUsedOrigins = getUsedOrigins()->getLength();
   size_t I = 0;
@@ -92,19 +114,22 @@ void UseFact::dump(llvm::raw_ostream &OS, const 
LoanManager &,
 }
 
 void InvalidateOriginFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                                const OriginManager &OM) const {
+                                const OriginManager &OM,
+                                const LoanPropagationAnalysis *) const {
   OS << "InvalidateOrigin (";
   OM.dump(getInvalidatedOrigin(), OS);
   OS << ")\n";
 }
 
 void TestPointFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                         const OriginManager &) const {
+                         const OriginManager &,
+                         const LoanPropagationAnalysis *) const {
   OS << "TestPoint (Annotation: \"" << getAnnotation() << "\")\n";
 }
 
 void KillOriginFact::dump(llvm::raw_ostream &OS, const LoanManager &,
-                          const OriginManager &OM) const {
+                          const OriginManager &OM,
+                          const LoanPropagationAnalysis *) const {
   OS << "KillOrigin (";
   OM.dump(getKilledOrigin(), OS);
   OS << ")\n";
@@ -125,7 +150,8 @@ llvm::StringMap<ProgramPoint> FactManager::getTestPoints() 
const {
   return AnnotationToPointMap;
 }
 
-void FactManager::dump(const CFG &Cfg, AnalysisDeclContext &AC) const {
+void FactManager::dump(const CFG &Cfg, AnalysisDeclContext &AC,
+                       const LoanPropagationAnalysis *LPA) const {
   llvm::dbgs() << "==========================================\n";
   llvm::dbgs() << "       Lifetime Analysis Facts:\n";
   llvm::dbgs() << "==========================================\n";
@@ -137,7 +163,7 @@ void FactManager::dump(const CFG &Cfg, AnalysisDeclContext 
&AC) const {
     llvm::dbgs() << "  Block B" << B->getBlockID() << ":\n";
     for (const Fact *F : getFacts(B)) {
       llvm::dbgs() << "    ";
-      F->dump(llvm::dbgs(), LoanMgr, OriginMgr);
+      F->dump(llvm::dbgs(), LoanMgr, OriginMgr, LPA);
     }
     llvm::dbgs() << "  End of Block\n";
   }
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp 
b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
index 680095a54177c..798812327d3ab 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
@@ -35,7 +35,8 @@ namespace internal {
 
 #ifndef NDEBUG
 static void DebugOnlyFunction(AnalysisDeclContext &AC, const CFG &Cfg,
-                              FactManager &FactMgr) {
+                              FactManager &FactMgr,
+                              const LoanPropagationAnalysis *LPA) {
   std::string Name;
   if (const Decl *D = AC.getDecl()) {
     if (const auto *ND = dyn_cast<NamedDecl>(D))
@@ -44,7 +45,7 @@ static void DebugOnlyFunction(AnalysisDeclContext &AC, const 
CFG &Cfg,
   DEBUG_WITH_TYPE(Name.c_str(), AC.getDecl()->dumpColor());
   DEBUG_WITH_TYPE(Name.c_str(), Cfg.dump(AC.getASTContext().getLangOpts(),
                                          /*ShowColors=*/true));
-  DEBUG_WITH_TYPE(Name.c_str(), FactMgr.dump(Cfg, AC));
+  DEBUG_WITH_TYPE(Name.c_str(), FactMgr.dump(Cfg, AC, LPA));
 }
 #endif
 
@@ -101,12 +102,13 @@ void LifetimeSafetyAnalysis::run() {
   DEBUG_WITH_TYPE("PrintCFG", Cfg.dump(AC.getASTContext().getLangOpts(),
                                        /*ShowColors=*/true));
 
-  DEBUG_WITH_TYPE("LifetimeFacts", FactMgr->dump(Cfg, AC));
+  DEBUG_WITH_TYPE("LifetimeFacts",
+                  FactMgr->dump(Cfg, AC, LoanPropagation.get()));
 
   // Debug print facts for a specific function using
   // -debug-only=EnableFilterByFunctionName,YourFunctionNameFoo
   DEBUG_WITH_TYPE("EnableFilterByFunctionName",
-                  DebugOnlyFunction(AC, Cfg, *FactMgr));
+                  DebugOnlyFunction(AC, Cfg, *FactMgr, LoanPropagation.get()));
   DEBUG_WITH_TYPE("LiveOrigins",
                   LiveOrigins->dump(llvm::dbgs(), FactMgr->getTestPoints()));
 }
diff --git a/clang/test/Sema/LifetimeSafety/lifetime-facts.cpp 
b/clang/test/Sema/LifetimeSafety/lifetime-facts.cpp
index d655bf7391203..028833902aa94 100644
--- a/clang/test/Sema/LifetimeSafety/lifetime-facts.cpp
+++ b/clang/test/Sema/LifetimeSafety/lifetime-facts.cpp
@@ -23,7 +23,7 @@ MyObj* return_local_addr() {
   return p;
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_RET_VAL:[0-9]+]] (Expr: ImplicitCastExpr, Type 
: MyObj *)
+// CHECK-NEXT:       Dest: [[O_RET_VAL:[0-9]+]] (Expr: ImplicitCastExpr, Type 
: MyObj *) has loans to { x }
 // CHECK-NEXT:       Src:  [[O_P]] (Decl: p, Type : MyObj *)
 // CHECK:   Expire (x)
 // CHECK:   Expire (p, Origin: [[O_P]] (Decl: p, Type : MyObj *))
@@ -37,11 +37,11 @@ void loan_expires_cpp() {
 // CHECK: Block B{{[0-9]+}}:
 // CHECK:   Issue ([[L_OBJ:[0-9]+]] (Path: obj), ToOrigin: 
[[O_DRE_OBJ:[0-9]+]] (Expr: DeclRefExpr, Decl: obj))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_ADDR_OBJ:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_ADDR_OBJ:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *) has loans to { obj }
 // CHECK-NEXT:       Src:  [[O_DRE_OBJ]] (Expr: DeclRefExpr, Decl: obj)
   MyObj* pObj = &obj;
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: pObj, Type : MyObj *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: pObj, Type : MyObj *) has loans 
to { obj }
 // CHECK-NEXT:       Src:  [[O_ADDR_OBJ]] (Expr: UnaryOperator, Type : MyObj *)
 // CHECK:   Expire (obj)
 }
@@ -53,11 +53,11 @@ void loan_expires_trivial() {
 // CHECK: Block B{{[0-9]+}}:
 // CHECK:   Issue ([[L_TRIVIAL_OBJ:[0-9]+]] (Path: trivial_obj), ToOrigin: 
[[O_DRE_TRIVIAL:[0-9]+]] (Expr: DeclRefExpr, Decl: trivial_obj))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_ADDR_TRIVIAL_OBJ:[0-9]+]] (Expr: UnaryOperator, 
Type : int *)
+// CHECK-NEXT:       Dest: [[O_ADDR_TRIVIAL_OBJ:[0-9]+]] (Expr: UnaryOperator, 
Type : int *) has loans to { trivial_obj }
 // CHECK-NEXT:       Src:  [[O_DRE_TRIVIAL]] (Expr: DeclRefExpr, Decl: 
trivial_obj)
   int* pTrivialObj = &trivial_obj;
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: pTrivialObj, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: pTrivialObj, Type : int *) has 
loans to { trivial_obj }
 // CHECK-NEXT:       Src:  [[O_ADDR_TRIVIAL_OBJ]] (Expr: UnaryOperator, Type : 
int *)
 // CHECK:   Expire (trivial_obj)
 // CHECK-NEXT: End of Block
@@ -79,12 +79,12 @@ void overwrite_origin() {
   p = &s2;
 // CHECK:   Issue ([[L_S2:[0-9]+]] (Path: s2), ToOrigin: [[O_DRE_S2:[0-9]+]] 
(Expr: DeclRefExpr, Decl: s2))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_ADDR_S2:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_ADDR_S2:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *) has loans to { s2 }
 // CHECK-NEXT:       Src:  [[O_DRE_S2]] (Expr: DeclRefExpr, Decl: s2)
 // CHECK:   Use ([[O_P]] (Decl: p, Type : MyObj *), Write)
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_P]] (Decl: p, Type : MyObj *)
+// CHECK-NEXT:       Dest: [[O_P]] (Decl: p, Type : MyObj *) has loans to { s2 
}
 // CHECK-NEXT:       Src:  [[O_ADDR_S2]] (Expr: UnaryOperator, Type : MyObj *)
 // CHECK:   Expire (s2)
 // CHECK:   Expire (s1)
@@ -106,7 +106,7 @@ void reassign_to_null() {
 // CHECK:   Use ([[O_P]] (Decl: p, Type : MyObj *), Write)
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_P]] (Decl: p, Type : MyObj *)
+// CHECK-NEXT:       Dest: [[O_P]] (Decl: p, Type : MyObj *) has no loans
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : MyObj *)
 // CHECK:   Expire (s1)
 }
@@ -120,25 +120,25 @@ void pointer_indirection() {
 // CHECK: Block B{{[0-9]+}}:
 // CHECK:   Issue ([[L_A:[0-9]+]] (Path: a), ToOrigin: [[O_DRE_A:[0-9]+]] 
(Expr: DeclRefExpr, Decl: a))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_ADDR_A:[0-9]+]] (Expr: UnaryOperator, Type : 
int *)
+// CHECK-NEXT:       Dest: [[O_ADDR_A:[0-9]+]] (Expr: UnaryOperator, Type : 
int *) has loans to { a }
 // CHECK-NEXT:       Src:  [[O_DRE_A]] (Expr: DeclRefExpr, Decl: a)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_P:[0-9]+]] (Decl: p, Type : int *)
+// CHECK-NEXT:       Dest: [[O_P:[0-9]+]] (Decl: p, Type : int *) has loans to 
{ a }
 // CHECK-NEXT:       Src:  [[O_ADDR_A]] (Expr: UnaryOperator, Type : int *)
   int **pp = &p;
 // CHECK:   Use ([[O_P]] (Decl: p, Type : int *), Read)
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int **)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int **) has 
loans to { p }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: DeclRefExpr, Decl: p)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *) has 
loans to { a }
 // CHECK-NEXT:       Src:  [[O_P]] (Decl: p, Type : int *)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_PP_OUTER:[0-9]+]] (Decl: pp, Type : int **)
+// CHECK-NEXT:       Dest: [[O_PP_OUTER:[0-9]+]] (Decl: pp, Type : int **) has 
loans to { p }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : int **)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_PP_INNER:[0-9]+]] (Decl: pp, Type : int *)
+// CHECK-NEXT:       Dest: [[O_PP_INNER:[0-9]+]] (Decl: pp, Type : int *) has 
loans to { a }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
   
   // FIXME: Propagate origins across dereference unary operator*
@@ -146,22 +146,22 @@ void pointer_indirection() {
 // CHECK:   Use ([[O_PP_OUTER]] (Decl: pp, Type : int **), [[O_PP_INNER]] 
(Decl: pp, Type : int *), Read)
 // CHECK:   Issue ({{[0-9]+}} (Path: pp), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: pp))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int **)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int **) 
has loans to { p }
 // CHECK-NEXT:       Src:  [[O_PP_OUTER]] (Decl: pp, Type : int **)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *) 
has loans to { a }
 // CHECK-NEXT:       Src:  [[O_PP_INNER]] (Decl: pp, Type : int *)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *&)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *&) has 
loans to { p }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int **)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : int *) has 
loans to { a }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *) 
has loans to { a }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : int *)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: q, Type : int *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: q, Type : int *) has loans to { a 
}
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: ImplicitCastExpr, Type : int *)
 }
 
@@ -180,30 +180,30 @@ void test_use_lifetimebound_call() {
   MyObj *q = &y;
 // CHECK:   Issue ([[L_Y:[0-9]+]] (Path: y), ToOrigin: [[O_DRE_Y:[0-9]+]] 
(Expr: DeclRefExpr, Decl: y))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_ADDR_Y:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_ADDR_Y:[0-9]+]] (Expr: UnaryOperator, Type : 
MyObj *) has loans to { y }
 // CHECK-NEXT:       Src:  [[O_DRE_Y]] (Expr: DeclRefExpr, Decl: y)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_Q:[0-9]+]] (Decl: q, Type : MyObj *)
+// CHECK-NEXT:       Dest: [[O_Q:[0-9]+]] (Decl: q, Type : MyObj *) has loans 
to { y }
 // CHECK-NEXT:       Src:  [[O_ADDR_Y]] (Expr: UnaryOperator, Type : MyObj *)
   MyObj* r = LifetimeBoundCall(p, q);
 // CHECK:   Use ([[O_P]] (Decl: p, Type : MyObj *), Read)
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_P_RVAL:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_P_RVAL:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
MyObj *) has loans to { x }
 // CHECK-NEXT:       Src:  [[O_P]] (Decl: p, Type : MyObj *)
 // CHECK:   Use ([[O_Q]] (Decl: q, Type : MyObj *), Read)
 // CHECK:   Issue ({{[0-9]+}} (Path: q), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: q))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_Q_RVAL:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_Q_RVAL:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
MyObj *) has loans to { y }
 // CHECK-NEXT:       Src:  [[O_Q]] (Decl: q, Type : MyObj *)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_CALL_EXPR:[0-9]+]] (Expr: CallExpr, Type : 
MyObj *)
+// CHECK-NEXT:       Dest: [[O_CALL_EXPR:[0-9]+]] (Expr: CallExpr, Type : 
MyObj *) has loans to { x }
 // CHECK-NEXT:       Src:  [[O_P_RVAL]] (Expr: ImplicitCastExpr, Type : MyObj 
*)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_CALL_EXPR]] (Expr: CallExpr, Type : MyObj *)
+// CHECK-NEXT:       Dest: [[O_CALL_EXPR]] (Expr: CallExpr, Type : MyObj *) 
has loans to { x y }
 // CHECK-NEXT:       Src:  [[O_Q_RVAL]] (Expr: ImplicitCastExpr, Type : MyObj 
*), Merge
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: r, Type : MyObj *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: r, Type : MyObj *) has loans to { 
x y }
 // CHECK-NEXT:       Src:  [[O_CALL_EXPR]] (Expr: CallExpr, Type : MyObj *)
 // CHECK:   Expire (y)
 // CHECK:   Expire (x)
@@ -217,23 +217,23 @@ void test_reference_variable() {
 // CHECK: Block B{{[0-9]+}}:
 // CHECK:   Issue ([[L_X:[0-9]+]] (Path: x), ToOrigin: [[O_DRE_X:[0-9]+]] 
(Expr: DeclRefExpr, Decl: x))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_CAST_Y:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
const MyObj &)
+// CHECK-NEXT:       Dest: [[O_CAST_Y:[0-9]+]] (Expr: ImplicitCastExpr, Type : 
const MyObj &) has loans to { x }
 // CHECK-NEXT:       Src:  [[O_DRE_X]] (Expr: DeclRefExpr, Decl: x)
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_Y:[0-9]+]] (Decl: y, Type : const MyObj &)
+// CHECK-NEXT:       Dest: [[O_Y:[0-9]+]] (Decl: y, Type : const MyObj &) has 
loans to { x }
 // CHECK-NEXT:       Src:  [[O_CAST_Y]] (Expr: ImplicitCastExpr, Type : const 
MyObj &)
   const MyObj& z = y;
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: [[O_Z:[0-9]+]] (Decl: z, Type : const MyObj &)
+// CHECK-NEXT:       Dest: [[O_Z:[0-9]+]] (Decl: z, Type : const MyObj &) has 
loans to { x }
 // CHECK-NEXT:       Src:  [[O_Y]] (Decl: y, Type : const MyObj &)
   p = &z;
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : const MyObj 
*)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Expr: UnaryOperator, Type : const MyObj 
*) has loans to { x }
 // CHECK-NEXT:       Src:  [[O_Z]] (Decl: z, Type : const MyObj &)
 // CHECK:   Use ({{[0-9]+}} (Decl: p, Type : const MyObj *), Write)
 // CHECK:   Issue ({{[0-9]+}} (Path: p), ToOrigin: {{[0-9]+}} (Expr: 
DeclRefExpr, Decl: p))
 // CHECK:   OriginFlow:
-// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: p, Type : const MyObj *)
+// CHECK-NEXT:       Dest: {{[0-9]+}} (Decl: p, Type : const MyObj *) has 
loans to { x }
 // CHECK-NEXT:       Src:  {{[0-9]+}} (Expr: UnaryOperator, Type : const MyObj 
*)
 // CHECK:   Expire (x)
 }

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

Reply via email to