https://github.com/suoyuan666 updated 
https://github.com/llvm/llvm-project/pull/212083

>From fc0f25bc4769204d0fdfad065bc35708d31300c4 Mon Sep 17 00:00:00 2001
From: Yuan Suo <[email protected]>
Date: Sat, 18 Jul 2026 15:06:23 +0800
Subject: [PATCH 1/5] Use buildOriginFlowChain for remaining diagnostics in
 issuePendingWarnings

Signed-off-by: Yuan Suo <[email protected]>
---
 .../Analyses/LifetimeSafety/LifetimeSafety.h  | 18 ++++--
 .../Analyses/LifetimeSafety/LoanPropagation.h |  2 +-
 clang/lib/Analysis/LifetimeSafety/Checker.cpp | 34 +++++-----
 .../LifetimeSafety/LoanPropagation.cpp        |  9 ++-
 clang/lib/Sema/SemaLifetimeSafety.h           | 34 +++++++---
 .../LifetimeSafety/annotation-suggestions.cpp | 18 ++++--
 .../Sema/LifetimeSafety/dangling-field.cpp    | 27 +++++---
 .../Sema/LifetimeSafety/dangling-global.cpp   |  2 +-
 .../Sema/LifetimeSafety/invalidations.cpp     | 19 ++++--
 clang/test/Sema/LifetimeSafety/nocfg.cpp      | 14 +++--
 clang/test/Sema/LifetimeSafety/safety-c.c     |  6 +-
 clang/test/Sema/LifetimeSafety/safety.cpp     | 63 +++++++++++++------
 12 files changed, 164 insertions(+), 82 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index f8b7d2008bd789..84fbfde19dbb80 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -86,12 +86,14 @@ class LifetimeSafetySemaHelper {
                                    const FieldDecl *Field,
                                    const Expr *MovedExpr,
                                    bool IsCapturedByLambda,
-                                   SourceLocation ExpiryLoc) {}
+                                   SourceLocation ExpiryLoc,
+                                   llvm::ArrayRef<const Expr *> ExprChain) {}
 
   virtual void reportDanglingGlobal(const Expr *IssueExpr,
                                     const VarDecl *DanglingGlobal,
                                     const Expr *MovedExpr,
                                     SourceLocation ExpiryLoc,
+                                    llvm::ArrayRef<const Expr *> ExprChain,
                                     bool IsMain = false) {}
 
   // Reports when a reference/iterator is used after the container operation
@@ -106,16 +108,22 @@ class LifetimeSafetySemaHelper {
                              llvm::ArrayRef<const Expr *> ExprChain) {}
   virtual void reportInvalidatedField(const Expr *IssueExpr,
                                       const FieldDecl *Field,
-                                      const Expr *InvalidationExpr) {}
+                                      const Expr *InvalidationExpr,
+                                      llvm::ArrayRef<const Expr *> ExprChain) 
{}
   virtual void reportInvalidatedField(const ParmVarDecl *PVD,
                                       const FieldDecl *Field,
-                                      const Expr *InvalidationExpr) {}
+                                      const Expr *InvalidationExpr,
+                                      llvm::ArrayRef<const Expr *> ExprChain) 
{}
   virtual void reportInvalidatedGlobal(const Expr *IssueExpr,
                                        const VarDecl *Global,
-                                       const Expr *InvalidationExpr) {}
+                                       const Expr *InvalidationExpr,
+                                       llvm::ArrayRef<const Expr *> ExprChain) 
{
+  }
   virtual void reportInvalidatedGlobal(const ParmVarDecl *PVD,
                                        const VarDecl *Global,
-                                       const Expr *InvalidationExpr) {}
+                                       const Expr *InvalidationExpr,
+                                       llvm::ArrayRef<const Expr *> ExprChain) 
{
+  }
 
   using EscapingTarget =
       llvm::PointerUnion<const Expr *, const FieldDecl *, const VarDecl *>;
diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
index de7eca39228ca3..d8dffb4fc1a268 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
@@ -53,7 +53,7 @@ class LoanPropagationAnalysis {
 
   /// Like the above, starting from the used origin holding \p TargetLoan. The
   /// casts that load the used variable itself are left out.
-  llvm::SmallVector<OriginID> buildOriginFlowChain(const UseFact *UF,
+  llvm::SmallVector<OriginID> buildOriginFlowChain(const Fact *F,
                                                    const LoanID TargetLoan,
                                                    const CFG *Cfg) const;
 
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp 
b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index 3d2cab92b384bf..a5fdcf677484cd 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -322,33 +322,35 @@ class LifetimeChecker {
 
       } else if (const auto *OEF =
                      dyn_cast<const OriginEscapesFact *>(CausingFact)) {
+        llvm::SmallVector<const Expr *> ExprChain =
+            getExprChain(LoanPropagation.buildOriginFlowChain(OEF, LID, Cfg));
         if (Warning.InvalidatedByExpr) {
           if (const auto *FieldEscape = dyn_cast<FieldEscapeFact>(OEF)) {
             // Invalidated object escapes to a field.
             if (IssueExpr)
               // Invalidated object on stack escapes to a field.
-              SemaHelper->reportInvalidatedField(IssueExpr,
-                                                 FieldEscape->getFieldDecl(),
-                                                 Warning.InvalidatedByExpr);
+              SemaHelper->reportInvalidatedField(
+                  IssueExpr, FieldEscape->getFieldDecl(),
+                  Warning.InvalidatedByExpr, ExprChain);
             else if (InvalidatedPVD)
               // Invalidated parameter escapes to a field.
-              SemaHelper->reportInvalidatedField(InvalidatedPVD,
-                                                 FieldEscape->getFieldDecl(),
-                                                 Warning.InvalidatedByExpr);
+              SemaHelper->reportInvalidatedField(
+                  InvalidatedPVD, FieldEscape->getFieldDecl(),
+                  Warning.InvalidatedByExpr, ExprChain);
           } else if (const auto *GlobalEscape =
                          dyn_cast<GlobalEscapeFact>(OEF)) {
             // Invalidated object escapes to global or static storage.
             if (IssueExpr)
               // Invalidated object on stack escapes to global or static
               // storage.
-              SemaHelper->reportInvalidatedGlobal(IssueExpr,
-                                                  GlobalEscape->getGlobal(),
-                                                  Warning.InvalidatedByExpr);
+              SemaHelper->reportInvalidatedGlobal(
+                  IssueExpr, GlobalEscape->getGlobal(),
+                  Warning.InvalidatedByExpr, ExprChain);
             else if (InvalidatedPVD)
               // Invalidated parameter escapes to global or static storage.
-              SemaHelper->reportInvalidatedGlobal(InvalidatedPVD,
-                                                  GlobalEscape->getGlobal(),
-                                                  Warning.InvalidatedByExpr);
+              SemaHelper->reportInvalidatedGlobal(
+                  InvalidatedPVD, GlobalEscape->getGlobal(),
+                  Warning.InvalidatedByExpr, ExprChain);
           } else if (isa<ReturnEscapeFact>(OEF)) {
             // FIXME: Diagnose invalidated return escapes separately.
           } else
@@ -356,23 +358,21 @@ class LifetimeChecker {
         } else if (const auto *RetEscape = dyn_cast<ReturnEscapeFact>(OEF)) {
           // Return stack address.
           SemaHelper->reportUseAfterReturn(
-              IssueExpr, RetEscape->getReturnExpr(), MovedExpr,
-              getExprChain(
-                  LoanPropagation.buildOriginFlowChain(OEF, LID, Cfg)));
+              IssueExpr, RetEscape->getReturnExpr(), MovedExpr, ExprChain);
         } else if (const auto *FieldEscape = dyn_cast<FieldEscapeFact>(OEF)) {
           // Dangling field.
           bool IsCapturedByLambda =
               FactMgr.isFieldCapturedByLambda(FieldEscape->getFieldDecl());
           SemaHelper->reportDanglingField(
               IssueExpr, FieldEscape->getFieldDecl(), MovedExpr,
-              IsCapturedByLambda, ExpiryLoc);
+              IsCapturedByLambda, ExpiryLoc, ExprChain);
         } else if (const auto *GlobalEscape = dyn_cast<GlobalEscapeFact>(OEF)) 
{
           // Global escape.
           bool IsMain = false;
           if (const auto *Func = dyn_cast_if_present<FunctionDecl>(FD))
             IsMain = Func->isMain();
           SemaHelper->reportDanglingGlobal(IssueExpr, 
GlobalEscape->getGlobal(),
-                                           MovedExpr, ExpiryLoc, IsMain);
+                                           MovedExpr, ExpiryLoc, ExprChain, 
IsMain);
         } else
           llvm_unreachable("Unhandled OriginEscapesFact type");
       } else
diff --git a/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp 
b/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
index df66f029a5400d..7db184a09a41e0 100644
--- a/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
@@ -352,8 +352,13 @@ llvm::SmallVector<OriginID> 
LoanPropagationAnalysis::buildOriginFlowChain(
 }
 
 llvm::SmallVector<OriginID> LoanPropagationAnalysis::buildOriginFlowChain(
-    const UseFact *UF, const LoanID TargetLoan, const CFG *Cfg) const {
-  return PImpl->buildOriginFlowChain(UF, TargetLoan, Cfg);
+    const Fact *F, const LoanID TargetLoan, const CFG *Cfg) const {
+  if (const auto *UF = llvm::dyn_cast<UseFact>(F))
+    return PImpl->buildOriginFlowChain(UF, TargetLoan, Cfg);
+  if (const auto *OEF = llvm::dyn_cast<OriginEscapesFact>(F))
+    return PImpl->buildOriginFlowChain(OEF, OEF->getEscapedOriginID(),
+                                       TargetLoan, Cfg);
+  llvm_unreachable("Unhandled Fact type");
 }
 llvm::SmallVector<OriginID>
 LoanPropagationAnalysis::buildOriginFlowChain(const OriginEscapesFact *OEF,
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 3db298b6fec85c..57570043610a0d 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -187,7 +187,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
   void reportDanglingField(const Expr *IssueExpr,
                            const FieldDecl *DanglingField,
                            const Expr *MovedExpr, bool IsCapturedByLambda,
-                           SourceLocation ExpiryLoc) override {
+                           SourceLocation ExpiryLoc,
+                           llvm::ArrayRef<const Expr *> ExprChain) override {
     unsigned DiagID =
         IsCapturedByLambda
             ? diag::warn_lifetime_safety_dangling_field_lambda_capture
@@ -201,6 +202,9 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
     if (MovedExpr)
       S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
           << MovedExpr->getSourceRange();
+
+    reportAliasingChain(ExprChain);
+
     S.Diag(DanglingField->getLocation(),
            diag::note_lifetime_safety_dangling_field_here)
         << DanglingField->getEndLoc();
@@ -209,6 +213,7 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
   void reportDanglingGlobal(const Expr *IssueExpr,
                             const VarDecl *DanglingGlobal,
                             const Expr *MovedExpr, SourceLocation ExpiryLoc,
+                            llvm::ArrayRef<const Expr *> ExprChain,
                             bool IsMain = false) override {
     unsigned DiagID;
     if (IsMain) {
@@ -226,6 +231,9 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
     if (MovedExpr)
       S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
           << MovedExpr->getSourceRange();
+
+    reportAliasingChain(ExprChain);
+
     if (DanglingGlobal->isStaticLocal() || 
DanglingGlobal->isStaticDataMember())
       S.Diag(DanglingGlobal->getLocation(),
              diag::note_lifetime_safety_dangling_static_here)
@@ -271,13 +279,15 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
 
   void reportInvalidatedField(const Expr *IssueExpr,
                               const FieldDecl *DanglingField,
-                              const Expr *InvalidationExpr) override {
+                              const Expr *InvalidationExpr,
+                              llvm::ArrayRef<const Expr *> ExprChain) override 
{
     std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
     S.Diag(IssueExpr->getExprLoc(),
            diag::warn_lifetime_safety_invalidated_field)
         << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
         << IssueExpr->getSourceRange();
     reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
+    reportAliasingChain(ExprChain);
     S.Diag(DanglingField->getLocation(),
            diag::note_lifetime_safety_dangling_field_here)
         << DanglingField->getEndLoc();
@@ -285,27 +295,31 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
 
   void reportInvalidatedField(const ParmVarDecl *PVD,
                               const FieldDecl *DanglingField,
-                              const Expr *InvalidationExpr) override {
+                              const Expr *InvalidationExpr,
+                              llvm::ArrayRef<const Expr *> ExprChain) override 
{
     std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
     S.Diag(PVD->getSourceRange().getBegin(),
            diag::warn_lifetime_safety_invalidated_field)
         << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
         << PVD->getSourceRange();
     reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
+    reportAliasingChain(ExprChain);
     S.Diag(DanglingField->getLocation(),
            diag::note_lifetime_safety_dangling_field_here)
         << DanglingField->getEndLoc();
   }
 
-  void reportInvalidatedGlobal(const Expr *IssueExpr,
-                               const VarDecl *DanglingGlobal,
-                               const Expr *InvalidationExpr) override {
+  void
+  reportInvalidatedGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal,
+                          const Expr *InvalidationExpr,
+                          llvm::ArrayRef<const Expr *> ExprChain) override {
     std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
     S.Diag(IssueExpr->getExprLoc(),
            diag::warn_lifetime_safety_invalidated_global)
         << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
         << IssueExpr->getSourceRange();
     reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
+    reportAliasingChain(ExprChain);
     if (DanglingGlobal->isStaticLocal() || 
DanglingGlobal->isStaticDataMember())
       S.Diag(DanglingGlobal->getLocation(),
              diag::note_lifetime_safety_dangling_static_here)
@@ -316,15 +330,17 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
           << DanglingGlobal->getEndLoc();
   }
 
-  void reportInvalidatedGlobal(const ParmVarDecl *PVD,
-                               const VarDecl *DanglingGlobal,
-                               const Expr *InvalidationExpr) override {
+  void
+  reportInvalidatedGlobal(const ParmVarDecl *PVD, const VarDecl 
*DanglingGlobal,
+                          const Expr *InvalidationExpr,
+                          llvm::ArrayRef<const Expr *> ExprChain) override {
     std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
     S.Diag(PVD->getSourceRange().getBegin(),
            diag::warn_lifetime_safety_invalidated_global)
         << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
         << PVD->getSourceRange();
     reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
+    reportAliasingChain(ExprChain);
     if (DanglingGlobal->isStaticLocal() || 
DanglingGlobal->isStaticDataMember())
       S.Diag(DanglingGlobal->getLocation(),
              diag::note_lifetime_safety_dangling_static_here)
diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp 
b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index 34f3ad4f45de1a..3769710c489886 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -528,7 +528,8 @@ struct CaptureRefToView {
 CaptureRefToView test_ref_to_view() {
   MyObj obj;
   CaptureRefToView x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}}
+  return x; // expected-note {{returned here}} \
+            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
 }
 
 struct CaptureRefToPtr {
@@ -539,7 +540,8 @@ struct CaptureRefToPtr {
 CaptureRefToPtr test_ref_to_ptr() {
   MyObj obj;
   CaptureRefToPtr x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}}
+  return x; // expected-note {{returned here}} \
+            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
 }
 
 struct CaptureViewToView {
@@ -562,7 +564,8 @@ struct CapturePtrToPtr {
 CapturePtrToPtr test_ptr_to_ptr() {
   MyObj obj;
   CapturePtrToPtr x(&obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}}
+  return x; // expected-note {{returned here}} \
+            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
 }
 
 struct CaptureRefToRef {
@@ -573,7 +576,8 @@ struct CaptureRefToRef {
 CaptureRefToRef test_ref_to_ref() {
   MyObj obj;
   CaptureRefToRef x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}}
+  return x; // expected-note {{returned here}} \
+            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
 }
 
 struct BaseWithView {
@@ -588,7 +592,8 @@ struct CaptureRefToBaseView : BaseWithView {
 CaptureRefToBaseView test_ref_to_base_view() {
   MyObj obj;
   CaptureRefToBaseView x(obj); // expected-warning {{stack memory associated 
with local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}}
+  return x; // expected-note {{returned here}} \
+            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
 }
 } // namespace capturing_constructor
 
@@ -660,7 +665,8 @@ struct HasCtorField {
 HasCtorField test_dangling_field_ctor() {
   MyObj obj;
   HasCtorField x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;            // expected-note {{returned here}}
+  return x;            // expected-note {{returned here}} \
+                       // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
 }
 
 struct HasSetterField {
diff --git a/clang/test/Sema/LifetimeSafety/dangling-field.cpp 
b/clang/test/Sema/LifetimeSafety/dangling-field.cpp
index 68ed47687b29ae..06db94d81f02c5 100644
--- a/clang/test/Sema/LifetimeSafety/dangling-field.cpp
+++ b/clang/test/Sema/LifetimeSafety/dangling-field.cpp
@@ -40,7 +40,8 @@ struct CtorSetInLoop {
 
 struct CtorInitLifetimeBound {
   std::string_view view;  // expected-note {{this field dangles}}
-  CtorInitLifetimeBound(std::string s) : view(construct_view(s)) {} // 
expected-warning {{stack memory associated with parameter 's' escapes to the 
field 'view' which will dangle}}
+  CtorInitLifetimeBound(std::string s) : view(construct_view(s)) {} // 
expected-warning {{stack memory associated with parameter 's' escapes to the 
field 'view' which will dangle}} \
+                                                                    // 
expected-note {{result of call to 'construct_view' aliases the storage of 
parameter 's'}}
 };
 
 struct CtorInitButMoved {
@@ -90,7 +91,8 @@ struct CtorRefField {
 
 struct CtorPointerField {
   const char* ptr; // expected-note {{this field dangles}}
-  CtorPointerField(std::string s) : ptr(s.data()) {}  // expected-warning 
{{stack memory associated with parameter 's' escapes to the field 'ptr' which 
will dangle}}
+  CtorPointerField(std::string s) : ptr(s.data()) {}  // expected-warning 
{{stack memory associated with parameter 's' escapes to the field 'ptr' which 
will dangle}} \
+                                                      // expected-note 
{{result of call to 'data' aliases the storage of parameter 's'}}
   CtorPointerField(Dummy<1> ok, const std::string& s) : ptr(s.data()) {}
   CtorPointerField(Dummy<2> ok, std::string_view view) : ptr(view.data()) {}
 };
@@ -101,12 +103,14 @@ struct MemberSetters {
 
   void setWithParam(std::string s) {
     view = s;     // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'view' which will dangle}}
-    p = s.data(); // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'p' which will dangle}}
+    p = s.data(); // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'p' which will dangle}} \
+                  // expected-note {{result of call to 'data' aliases the 
storage of parameter 's'}}
   }
 
   void setWithParamAndReturn(std::string s) {
     view = s;     // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'view' which will dangle}}
-    p = s.data(); // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'p' which will dangle}}
+    p = s.data(); // expected-warning {{stack memory associated with parameter 
's' escapes to the field 'p' which will dangle}} \
+                  // expected-note {{result of call to 'data' aliases the 
storage of parameter 's'}}
     return;
   }
 
@@ -124,13 +128,15 @@ struct MemberSetters {
   void setWithLocal() {
     std::string s;
     view = s;     // expected-warning {{stack memory associated with local 
variable 's' escapes to the field 'view' which will dangle}}
-    p = s.data(); // expected-warning {{stack memory associated with local 
variable 's' escapes to the field 'p' which will dangle}}
+    p = s.data(); // expected-warning {{stack memory associated with local 
variable 's' escapes to the field 'p' which will dangle}} \
+                  // expected-note {{result of call to 'data' aliases the 
storage of local variable 's'}}
   }
   
   void setWithLocalButMoved() {
     std::string s;
     view = s;                 // expected-warning-re {{stack memory associated 
with local variable 's' may escape to the field 'view' which will dangle. 
{{.*}} may have been moved}}
-    p = s.data();             // expected-warning-re {{stack memory associated 
with local variable 's' may escape to the field 'p' which will dangle. {{.*}} 
may have been moved}}
+    p = s.data();             // expected-warning-re {{stack memory associated 
with local variable 's' may escape to the field 'p' which will dangle. {{.*}} 
may have been moved}} \
+                              // expected-note {{result of call to 'data' 
aliases the storage of local variable 's'}}
     takeString(std::move(s)); // expected-note 2 {{potentially moved here}}
   }
 
@@ -154,14 +160,16 @@ struct MemberSetters {
 
     std::string local;
     view = local;     // expected-warning {{stack memory associated with local 
variable 'local' escapes to the field 'view' which will dangle}}
-    p = local.data(); // expected-warning {{stack memory associated with local 
variable 'local' escapes to the field 'p' which will dangle}}
+    p = local.data(); // expected-warning {{stack memory associated with local 
variable 'local' escapes to the field 'p' which will dangle}} \
+                      // expected-note {{result of call to 'data' aliases the 
storage of local variable 'local'}}
   }
 
   void escape_to_field() {
     {
       std::string local;
       view = local;     // expected-warning {{stack memory associated with 
local variable 'local' escapes to the field 'view' which will dangle}}
-      p = local.data(); // expected-warning {{stack memory associated with 
local variable 'local' escapes to the field 'p' which will dangle}}
+      p = local.data(); // expected-warning {{stack memory associated with 
local variable 'local' escapes to the field 'p' which will dangle}} \
+                        // expected-note {{result of call to 'data' aliases 
the storage of local variable 'local'}}
     }
     (void)view;         // Discarding the value is not a use.
     (void)p;
@@ -256,7 +264,8 @@ struct HasUniquePtrField {
   std::unique_ptr<LifetimeBoundCtor> field; // tu-note {{this field dangles}}
 
   void setWithParam(MyObj obj) {
-    field = std::make_unique<LifetimeBoundCtor>(obj); // tu-warning {{stack 
memory associated with parameter 'obj' escapes to the field 'field' which will 
dangle}}
+    field = std::make_unique<LifetimeBoundCtor>(obj); // tu-warning {{stack 
memory associated with parameter 'obj' escapes to the field 'field' which will 
dangle}} \
+                                                      // tu-note {{result of 
call to 'make_unique<MakeUnique::LifetimeBoundCtor, MakeUnique::MyObj &>' 
aliases the storage of parameter 'obj'}}
   }
 };
 } // namespace MakeUnique
diff --git a/clang/test/Sema/LifetimeSafety/dangling-global.cpp 
b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
index ef00582fb9c122..7a0e03594fff64 100644
--- a/clang/test/Sema/LifetimeSafety/dangling-global.cpp
+++ b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
@@ -27,7 +27,7 @@ void invoke_function_with_side_effects() {
 void inlined() {
   int local;
   global = &local; // expected-warning {{stack memory associated with local 
variable 'local' escapes to the global variable 'global_backup' which will 
dangle}}
-  global_backup = global; 
+  global_backup = global; // expected-note {{global variable 'global' aliases 
the storage of local variable 'local'}}
   global = nullptr;
 }
 
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp 
b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index a7c62852c69892..95d33ad0a9c64e 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -578,7 +578,8 @@ struct SinkOwnerBorrow {
 struct SinkInteriorBorrow {
   const char *dest_; // expected-note {{this field dangles}}
 
-  SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // 
expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later 
invalidated}}
+  SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // 
expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later 
invalidated}} \
+                                                                       // 
expected-note {{result of call to 'data' aliases the storage of parameter 
'dest'}}
     if (n > 0)
       dest->clear(); // expected-note {{parameter 'dest' is invalidated here}}
   }
@@ -596,12 +597,16 @@ struct S {
 
   void InvalidatedFieldLocalVector() {
     std::vector<std::string> strings;
-    FieldFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the field 'FieldFromLocalVector' and is later 
invalidated}}
+    FieldFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the field 'FieldFromLocalVector' and is later 
invalidated}} \
+                                             // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
+                                             // expected-note {{expression 
aliases the storage of local variable 'strings'}}
     strings.push_back("1"); // expected-note {{local variable 'strings' is 
invalidated here}}
   }
 
   void InvalidatedFieldByValueParamVector(std::vector<std::string> strings) {
-    FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is 
later invalidated}}
+    FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is 
later invalidated}} \
+                                                    // expected-note {{result 
of call to 'begin' aliases the storage of parameter 'strings'}} \
+                                                    // expected-note 
{{expression aliases the storage of parameter 'strings'}}
     strings.push_back("1"); // expected-note {{parameter 'strings' is 
invalidated here}}
   }
 
@@ -623,7 +628,7 @@ struct S {
 
   void InvalidatedFieldDelete() {
     int *p = new int; // expected-warning {{allocated object escapes to the 
field 'FieldFromNew' and is later invalidated}}
-    FieldFromNew = p;
+    FieldFromNew = p; // expected-note {{local variable 'p' aliases the 
storage of allocated object}}
     delete p; // expected-note {{allocated object is freed here}}
   }
 
@@ -656,7 +661,9 @@ struct S {
 
 void InvalidatedGlobalLocalVector() {
   std::vector<std::string> strings;
-  GlobalFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the global variable 'GlobalFromLocalVector' and 
is later invalidated}}
+  GlobalFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the global variable 'GlobalFromLocalVector' and 
is later invalidated}} \
+                                            // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
+                                            // expected-note {{expression 
aliases the storage of local variable 'strings'}}
   strings.push_back("1"); // expected-note {{local variable 'strings' is 
invalidated here}}
 }
 
@@ -672,7 +679,7 @@ void InvalidatedGlobalRefParamString(std::string &s) { // 
expected-warning {{par
 
 void InvalidatedGlobalDelete() {
   int *p = new int; // expected-warning {{allocated object escapes to the 
global variable 'GlobalFromNew' and is later invalidated}}
-  GlobalFromNew = p;
+  GlobalFromNew = p; // expected-note {{local variable 'p' aliases the storage 
of allocated object}}
   delete p; // expected-note {{allocated object is freed here}}
 }
 
diff --git a/clang/test/Sema/LifetimeSafety/nocfg.cpp 
b/clang/test/Sema/LifetimeSafety/nocfg.cpp
index addbe9213a0ac2..405312b35eff45 100644
--- a/clang/test/Sema/LifetimeSafety/nocfg.cpp
+++ b/clang/test/Sema/LifetimeSafety/nocfg.cpp
@@ -374,8 +374,10 @@ const char *trackThroughMultiplePointer() {
 
 struct X {
   X(std::unique_ptr<int> up) :
-    pointee(*up),             // cfg-warning {{may have been moved.}}
-    pointee2(up.get()),       // cfg-warning {{may have been moved.}}
+    pointee(*up),             // cfg-warning {{may have been moved.}} \
+                              // cfg-note {{expression aliases the storage of 
parameter 'up'}}
+    pointee2(up.get()),       // cfg-warning {{may have been moved.}} \
+                              // cfg-note {{result of call to 'get' aliases 
the storage of parameter 'up'}}
     pointer(std::move(up)) {} // cfg-note 2 {{potentially moved here}}
   int &pointee;               // cfg-note {{this field dangles}}
   int *pointee2;              // cfg-note {{this field dangles}}
@@ -389,7 +391,8 @@ struct X2 {
   // A common usage that moves the passing owner to the class.
   // verify a strict warning on this case.
   X2(XOwner owner) :
-    pointee(owner.get()),       // cfg-warning {{may have been moved.}}
+    pointee(owner.get()),       // cfg-warning {{may have been moved.}} \
+                                // cfg-note {{result of call to 'get' aliases 
the storage of parameter 'owner'}}
     owner(std::move(owner)) {}  // cfg-note {{potentially moved here}}
   int* pointee;                 // cfg-note {{this field dangles}}
   XOwner owner;
@@ -610,10 +613,12 @@ FooView test3(int i, std::optional<Foo> a) {
     return *a; // expected-warning {{address of stack memory}} \
                // cfg-note {{result of call to 'operator*' aliases the storage 
of parameter 'a' because the implicit object parameter is inferred as 
lifetimebound}} \
                // cfg-warning {{stack memory associated with parameter 'a' is 
returned}} \
+               // cfg-note {{expression aliases the storage of parameter 'a'}} 
\
                // cfg-note {{returned here}}
   return a.value(); // expected-warning {{address of stack memory}} \
                     // cfg-note {{result of call to 'value' aliases the 
storage of parameter 'a' because the implicit object parameter is inferred as 
lifetimebound}} \
                     // cfg-warning {{stack memory associated with parameter 
'a' is returned}} \
+                    // cfg-note {{result of call to 'value' aliases the 
storage of parameter 'a'}} \
                     // cfg-note {{returned here}}
 }
 } // namespace GH93386
@@ -1197,7 +1202,8 @@ struct Foo2 {
 };
 
 struct Test {
-  Test(Foo2 foo) : bar(foo.bar.get()),  // cfg-warning-re {{stack memory 
associated with parameter 'foo' may escape to the field 'bar' which will 
dangle. {{.*}} may have been moved}}
+  Test(Foo2 foo) : bar(foo.bar.get()),  // cfg-warning-re {{stack memory 
associated with parameter 'foo' may escape to the field 'bar' which will 
dangle. {{.*}} may have been moved}} \
+                                        // cfg-note {{result of call to 'get' 
aliases the storage of parameter 'foo'}}
       storage(std::move(foo.bar)) {};   // cfg-note {{potentially moved here}}
 
   Bar* bar; // cfg-note {{this field dangles}}
diff --git a/clang/test/Sema/LifetimeSafety/safety-c.c 
b/clang/test/Sema/LifetimeSafety/safety-c.c
index 8e6ca521c18046..ed0b9e21eb53ee 100644
--- a/clang/test/Sema/LifetimeSafety/safety-c.c
+++ b/clang/test/Sema/LifetimeSafety/safety-c.c
@@ -181,7 +181,8 @@ void *void_pointer_dereference(void) {
 int *atomic_pointer_declref(void) {
   int value;
   _Atomic(int *) p = &value; // expected-warning {{stack memory associated 
with local variable 'value' is returned}}
-  return p;                  // expected-note {{returned here}}
+  return p;                  // expected-note {{returned here}} \
+                             // expected-note {{local variable 'p' aliases the 
storage of local variable 'value'}}
 }
 
 int *atomic_pointer_static(void) {
@@ -193,7 +194,8 @@ int *atomic_pointer_static(void) {
 int **atomic_pointer_multilevel(void) {
   int *inner;
   _Atomic(int **) p = &inner; // expected-warning {{stack memory associated 
with local variable 'inner' is returned}}
-  return p;                   // expected-note {{returned here}}
+  return p;                   // expected-note {{returned here}} \
+                              // expected-note {{local variable 'p' aliases 
the storage of local variable 'inner'}}
 }
 
 // In C, a pointer compound assignment is a prvalue; its result still carries
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index 18800830cb59f4..9ded44f6a720f6 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -530,7 +530,8 @@ View conditional_assign_both_branches(const MyObj& safe, 
bool c) {
   else {
     p = safe;
   }
-  return p;     // expected-note {{returned here}}
+  return p;     // expected-note {{returned here}} \
+                // expected-note {{local variable 'p' aliases the storage of 
local variable 's'}}
 
 }
 
@@ -538,7 +539,8 @@ View reassign_safe_to_local(const MyObj& safe) {
   MyObj local;
   View p = safe;
   p = local;    // expected-warning {{stack memory associated with local 
variable 'local' is returned}}
-  return p;     // expected-note {{returned here}}
+  return p;     // expected-note {{returned here}} \
+                // expected-note {{local variable 'p' aliases the storage of 
local variable 'local'}}
 }
 
 View pointer_chain_to_local() {
@@ -554,11 +556,13 @@ View multiple_assign_multiple_return(const MyObj& safe, 
bool c1, bool c2) {
   View p;
   if (c1) {
     p = local1;       // expected-warning {{stack memory associated with local 
variable 'local1' is returned}}
-    return p;         // expected-note {{returned here}}
+    return p;         // expected-note {{returned here}} \
+                      // expected-note {{local variable 'p' aliases the 
storage of local variable 'local1'}}
   }
   else if (c2) {
     p = local2;       // expected-warning {{stack memory associated with local 
variable 'local2' is returned}}
-    return p;         // expected-note {{returned here}}
+    return p;         // expected-note {{returned here}} \
+                      // expected-note {{local variable 'p' aliases the 
storage of local variable 'local2'}}
   }
   p = safe;
   return p;
@@ -577,7 +581,9 @@ View multiple_assign_single_return(const MyObj& safe, bool 
c1, bool c2) {
   else {
     p = safe;
   }
-  return p;         // expected-note 2 {{returned here}}
+  return p;         // expected-note 2 {{returned here}} \
+                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local1'}} \
+                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local2'}}
 }
 
 View direct_return_of_local() {
@@ -645,7 +651,8 @@ const int* return_pointer_to_parameter_via_reference(int a, 
int b, bool cond) {
 
 const int& return_pointer_to_parameter_via_reference_1(int a) {
     const int* d = &a; // expected-warning {{stack memory associated with 
parameter 'a' is returned}}
-    return *d;    // expected-note {{returned here}}
+    return *d;    // expected-note {{returned here}} \
+                  // expected-note {{local variable 'd' aliases the storage of 
parameter 'a'}}
 }
 
 const int& get_ref_to_local() {
@@ -743,7 +750,8 @@ View uar_before_uaf(const MyObj& safe, bool c) {
     MyObj local_obj; 
     p = local_obj;  // expected-warning {{stack memory associated with local 
variable 'local_obj' is returned}}
     if (c) {
-      return p;     // expected-note {{returned here}}
+      return p;     // expected-note {{returned here}} \
+                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local_obj'}}
     }
   }
   p.use();
@@ -1973,7 +1981,8 @@ void bar() {
 namespace DereferenceViews {
 const MyObj& testDeref(MyObj obj) {
   View v = obj; // expected-warning {{stack memory associated with parameter 
'obj' is returned}}
-  return *v;    // expected-note {{returned here}}
+  return *v;    // expected-note {{returned here}} \
+                // expected-note {{local variable 'v' aliases the storage of 
parameter 'obj'}}
 }
 const MyObj* testDerefAddr(MyObj obj) {
   View v = obj; // expected-warning {{stack memory associated with parameter 
'obj' is returned}}
@@ -1982,7 +1991,8 @@ const MyObj* testDerefAddr(MyObj obj) {
 }
 const MyObj* testData(MyObj obj) {
   View v = obj;     // expected-warning {{stack memory associated with 
parameter 'obj' is returned}}
-  return v.data();  // expected-note {{returned here}}
+  return v.data();  // expected-note {{returned here}} \
+                    // expected-note {{local variable 'v' aliases the storage 
of parameter 'obj'}}
 }
 const int* testLifetimeboundAccessorOfMyObj(MyObj obj) {
   View v = obj;           // expected-warning {{stack memory associated with 
parameter 'obj' is returned}}
@@ -2293,7 +2303,8 @@ View test1(std::string a) {
 
 View test2(std::string a) {
   View b = View(a); // expected-warning {{stack memory associated with 
parameter 'a' is returned}}
-  return b;         // expected-note {{returned here}}
+  return b;         // expected-note {{returned here}} \
+                    // expected-note {{local variable 'b' aliases the storage 
of parameter 'a'}}
 }
 
 View test3(std::string a) {
@@ -2350,7 +2361,8 @@ namespace lambda_captures {
 auto return_ref_capture() {
   int local = 1;
   auto lambda = [&local]() { return local; }; // expected-warning {{stack 
memory associated with local variable 'local' is returned}}
-  return lambda; // expected-note {{returned here}}
+  return lambda; // expected-note {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
 }
 
 void safe_ref_capture() {
@@ -2383,7 +2395,8 @@ auto capture_pointer_by_ref() {
   MyObj obj;
   MyObj* p = &obj;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda; // expected-note {{returned here}}
+  return lambda; // expected-note {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'p'}}
 }
 
 auto capture_multiple() {
@@ -2392,7 +2405,9 @@ auto capture_multiple() {
     &a,  // expected-warning {{stack memory associated with local variable 'a' 
is returned}}
     &b   // expected-warning {{stack memory associated with local variable 'b' 
is returned}}
   ]() { return a + b; };
-  return lambda; // expected-note 2 {{returned here}}
+  return lambda; // expected-note 2 {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'a'}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'b'}}
 }
 
 auto capture_raw_pointer_by_value() {
@@ -2433,7 +2448,8 @@ auto return_copied_lambda() {
 auto implicit_ref_capture() {
   int local = 1;
   auto lambda = [&]() { return local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return lambda; // expected-note {{returned here}}
+  return lambda; // expected-note {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
 }
 
 // TODO: Include the name of the variable in the diagnostic to improve
@@ -2442,7 +2458,9 @@ auto implicit_ref_capture() {
 auto implicit_ref_capture_multiple() {
   int local = 1, local2 = 2;
   auto lambda = [&]() { return local + local2; }; // expected-warning {{stack 
memory associated with local variable 'local2' is returned}} expected-warning 
{{stack memory associated with local variable 'local' is returned}}
-  return lambda; // expected-note 2 {{returned here}}
+  return lambda; // expected-note 2 {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local2'}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
 }
 
 auto implicit_value_capture() {
@@ -2480,7 +2498,8 @@ auto capture_static_address_by_ref() {
   static int local = 1;
   int* p = &local;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda; // expected-note {{returned here}}
+  return lambda; // expected-note {{returned here}} \
+                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'p'}}
 }
 
 auto capture_multilevel_pointer() {
@@ -2885,7 +2904,8 @@ void from_template_instantiation() {
 
 struct FieldInitFromLifetimebound {
   S value; // expected-note {{this field dangles}}
-  FieldInitFromLifetimebound() : value(getS(std::string("temp"))) {} // 
expected-warning {{stack memory associated with temporary object escapes to the 
field 'value' which will dangle}}
+  FieldInitFromLifetimebound() : value(getS(std::string("temp"))) {} // 
expected-warning {{stack memory associated with temporary object escapes to the 
field 'value' which will dangle}} \
+                                                                     // 
expected-note {{result of call to 'getS' aliases the storage of temporary 
object}}
 };
 
 S S::return_self_after_registration() const {
@@ -3117,7 +3137,8 @@ void binary_conditional_throw_void(int *in) {
 int *binary_conditional_throw_dangling() {
   int x;
   int *p = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
-  return p ?: throw 1; // expected-note {{returned here}}
+  return p ?: throw 1; // expected-note {{returned here}} \
+                       // expected-note {{local variable 'p' aliases the 
storage of local variable 'x'}}
 }
 
 #endif
@@ -3800,7 +3821,8 @@ std::function<void()> reassign_safe_then_unsafe() {
   int local = 2;
   std::function<void()> f = []() { (void)safe; };
   f = [&local]() { (void)local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return f; // expected-note {{returned here}}
+  return f; // expected-note {{returned here}} \
+            // expected-note {{local variable 'f' aliases the storage of local 
variable 'local'}}
 }
 
 std::function<void()> reassign_unsafe_then_safe() {
@@ -3973,7 +3995,8 @@ View use_after_return_capture_by() {
   MyObj a;
   View res;
   setCaptureBy(res, a);   // expected-warning {{stack memory associated with 
local variable 'a' is returned}}
-  return res;     // expected-note {{returned here}}  
+  return res;     // expected-note {{returned here}} \
+                  // expected-note {{local variable 'res' aliases the storage 
of local variable 'a'}}
                    
 }
 

>From 9ab795024831150873d8fe9c1aac2aa327fc1b43 Mon Sep 17 00:00:00 2001
From: Yuan Suo <[email protected]>
Date: Sat, 1 Aug 2026 16:35:44 +0800
Subject: [PATCH 2/5] Align continuation comments

Signed-off-by: Yuan Suo <[email protected]>
Assisted-by: deepseek-v4-flash
---
 clang/test/Sema/LifetimeSafety/dangling-global.cpp | 2 +-
 clang/test/Sema/LifetimeSafety/invalidations.cpp   | 2 +-
 clang/test/Sema/LifetimeSafety/safety.cpp          | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/test/Sema/LifetimeSafety/dangling-global.cpp 
b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
index 7a0e03594fff64..3681ae9fcab669 100644
--- a/clang/test/Sema/LifetimeSafety/dangling-global.cpp
+++ b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
@@ -26,7 +26,7 @@ void invoke_function_with_side_effects() {
 // We can however catch the inlined one of course!
 void inlined() {
   int local;
-  global = &local; // expected-warning {{stack memory associated with local 
variable 'local' escapes to the global variable 'global_backup' which will 
dangle}}
+  global = &local;        // expected-warning {{stack memory associated with 
local variable 'local' escapes to the global variable 'global_backup' which 
will dangle}}
   global_backup = global; // expected-note {{global variable 'global' aliases 
the storage of local variable 'local'}}
   global = nullptr;
 }
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp 
b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index 95d33ad0a9c64e..6affbed1958322 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -678,7 +678,7 @@ void InvalidatedGlobalRefParamString(std::string &s) { // 
expected-warning {{par
 }
 
 void InvalidatedGlobalDelete() {
-  int *p = new int; // expected-warning {{allocated object escapes to the 
global variable 'GlobalFromNew' and is later invalidated}}
+  int *p = new int;  // expected-warning {{allocated object escapes to the 
global variable 'GlobalFromNew' and is later invalidated}}
   GlobalFromNew = p; // expected-note {{local variable 'p' aliases the storage 
of allocated object}}
   delete p; // expected-note {{allocated object is freed here}}
 }
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index 9ded44f6a720f6..bfbe1e66f61190 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -651,8 +651,8 @@ const int* return_pointer_to_parameter_via_reference(int a, 
int b, bool cond) {
 
 const int& return_pointer_to_parameter_via_reference_1(int a) {
     const int* d = &a; // expected-warning {{stack memory associated with 
parameter 'a' is returned}}
-    return *d;    // expected-note {{returned here}} \
-                  // expected-note {{local variable 'd' aliases the storage of 
parameter 'a'}}
+    return *d;         // expected-note {{returned here}} \
+                       // expected-note {{local variable 'd' aliases the 
storage of parameter 'a'}}
 }
 
 const int& get_ref_to_local() {
@@ -3942,7 +3942,7 @@ void deref_use_after_scope() {
 namespace GH191954 {
   int* return_moved_pointer() {
     int x;
-    int* f = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
+    int* f = &x;      // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
     int* a;
     a = std::move(f); // expected-note {{result of call to 'move<int *&>' 
aliases the storage of local variable 'x'}}
     return a; // expected-note {{returned here}}

>From 312b2f5b135b860ee9795eddeba282bd252072a8 Mon Sep 17 00:00:00 2001
From: Yuan Suo <[email protected]>
Date: Sat, 22 Aug 2026 16:34:54 +0800
Subject: [PATCH 3/5] Rebase and resolve some conflicts

Signed-off-by: Yuan Suo <[email protected]>
---
 clang/test/Sema/LifetimeSafety/capture-by.cpp               | 2 +-
 .../Sema/LifetimeSafety/explicit-object-param-no-crash.cpp  | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/test/Sema/LifetimeSafety/capture-by.cpp 
b/clang/test/Sema/LifetimeSafety/capture-by.cpp
index 99924bed821457..8331c6a5437d4a 100644
--- a/clang/test/Sema/LifetimeSafety/capture-by.cpp
+++ b/clang/test/Sema/LifetimeSafety/capture-by.cpp
@@ -196,7 +196,7 @@ void temporary_pointer_lifetimebound_capture() {
 }
 
 void temporary_nested_lifetimebound_capture() {
-  capturePointer(getLifetimeBoundPointer(*getLifetimeBoundPointer(
+  capturePointer(getLifetimeBoundPointer(*getLifetimeBoundPointer( // cfg-note 
2 {{result of call to 'getLifetimeBoundPointer' aliases the storage of 
temporary object because parameter 's' is lifetimebound}}
     std::string())), x);  // expected-warning {{object whose reference is 
captured by 'x' will be destroyed at the end of the full-expression}} \
                           // cfg-warning {{stack memory associated with 
temporary object escapes to the global variable 'x' which will dangle}}
 }
diff --git a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp 
b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
index 31c07d9d7f1028..4437ba773ffffc 100644
--- a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
+++ b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
@@ -78,14 +78,16 @@ const int *t1(Holder h) {
   const int *ptr = h.borrow(); // expected-warning {{stack memory associated 
with parameter 'h' is returned}} \
                                // expected-note {{result of call to 'borrow' 
aliases the storage of parameter 'h' because the implicit object parameter is 
marked as lifetimebound}}
   static_cast<Holder &&>(h).consume();
-  return ptr; // expected-note {{returned here}}
+  return ptr; // expected-note {{returned here}} \
+              // expected-note {{local variable 'ptr' aliases the storage of 
parameter 'h'}}
 }
 
 const int *t2(Holder h) {
   const int *ptr = h.borrow(); // expected-warning {{stack memory associated 
with parameter 'h' is returned}} \
                                // expected-note {{result of call to 'borrow' 
aliases the storage of parameter 'h' because the implicit object parameter is 
marked as lifetimebound}}
   std::move(h).consume();
-  return ptr; // expected-note {{returned here}}
+  return ptr; // expected-note {{returned here}} \
+              // expected-note {{local variable 'ptr' aliases the storage of 
parameter 'h'}}
 }
 
 struct Set {

>From 54a3e2e7317cf56e6aae9254dea33ff6c8086893 Mon Sep 17 00:00:00 2001
From: Yuan Suo <[email protected]>
Date: Sun, 30 Aug 2026 10:55:18 +0800
Subject: [PATCH 4/5] Align something

Signed-off-by: Yuan Suo <[email protected]>
---
 .../LifetimeSafety/annotation-suggestions.cpp | 22 +++----
 .../Sema/LifetimeSafety/invalidations.cpp     | 10 ++--
 clang/test/Sema/LifetimeSafety/safety.cpp     | 60 +++++++++----------
 3 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp 
b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index 3769710c489886..2ca3a94f41b7ac 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -528,8 +528,8 @@ struct CaptureRefToView {
 CaptureRefToView test_ref_to_view() {
   MyObj obj;
   CaptureRefToView x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}} \
-            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
+  return x;                // expected-note {{returned here}} \
+                           // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
 }
 
 struct CaptureRefToPtr {
@@ -540,8 +540,8 @@ struct CaptureRefToPtr {
 CaptureRefToPtr test_ref_to_ptr() {
   MyObj obj;
   CaptureRefToPtr x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}} \
-            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
+  return x;               // expected-note {{returned here}} \
+                          // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
 }
 
 struct CaptureViewToView {
@@ -551,7 +551,7 @@ struct CaptureViewToView {
 
 CaptureViewToView test_view_to_view() {
   MyObj obj;
-  View v(obj); // expected-warning {{stack memory associated with local 
variable 'obj' is returned}}
+  View v(obj);            // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
   CaptureViewToView x(v); // expected-note {{local variable 'v' aliases the 
storage of local variable 'obj'}}
   return x; // expected-note {{returned here}}
 }
@@ -564,8 +564,8 @@ struct CapturePtrToPtr {
 CapturePtrToPtr test_ptr_to_ptr() {
   MyObj obj;
   CapturePtrToPtr x(&obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}} \
-            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
+  return x;                // expected-note {{returned here}} \
+                           // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
 }
 
 struct CaptureRefToRef {
@@ -576,8 +576,8 @@ struct CaptureRefToRef {
 CaptureRefToRef test_ref_to_ref() {
   MyObj obj;
   CaptureRefToRef x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}} \
-            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
+  return x;               // expected-note {{returned here}} \
+                          // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
 }
 
 struct BaseWithView {
@@ -592,8 +592,8 @@ struct CaptureRefToBaseView : BaseWithView {
 CaptureRefToBaseView test_ref_to_base_view() {
   MyObj obj;
   CaptureRefToBaseView x(obj); // expected-warning {{stack memory associated 
with local variable 'obj' is returned}}
-  return x; // expected-note {{returned here}} \
-            // expected-note {{local variable 'x' aliases the storage of local 
variable 'obj'}}
+  return x;                    // expected-note {{returned here}} \
+                               // expected-note {{local variable 'x' aliases 
the storage of local variable 'obj'}}
 }
 } // namespace capturing_constructor
 
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp 
b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index 6affbed1958322..af09676981d0db 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -600,14 +600,14 @@ struct S {
     FieldFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the field 'FieldFromLocalVector' and is later 
invalidated}} \
                                              // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
                                              // expected-note {{expression 
aliases the storage of local variable 'strings'}}
-    strings.push_back("1"); // expected-note {{local variable 'strings' is 
invalidated here}}
+    strings.push_back("1");                  // expected-note {{local variable 
'strings' is invalidated here}}
   }
 
   void InvalidatedFieldByValueParamVector(std::vector<std::string> strings) {
     FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is 
later invalidated}} \
                                                     // expected-note {{result 
of call to 'begin' aliases the storage of parameter 'strings'}} \
                                                     // expected-note 
{{expression aliases the storage of parameter 'strings'}}
-    strings.push_back("1"); // expected-note {{parameter 'strings' is 
invalidated here}}
+    strings.push_back("1");                         // expected-note 
{{parameter 'strings' is invalidated here}}
   }
 
   void InvalidatedFieldLocalString() {
@@ -629,7 +629,7 @@ struct S {
   void InvalidatedFieldDelete() {
     int *p = new int; // expected-warning {{allocated object escapes to the 
field 'FieldFromNew' and is later invalidated}}
     FieldFromNew = p; // expected-note {{local variable 'p' aliases the 
storage of allocated object}}
-    delete p; // expected-note {{allocated object is freed here}}
+    delete p;         // expected-note {{allocated object is freed here}}
   }
 
   void InvalidatedFieldDeleteParam(int *p) { // expected-warning {{parameter 
'p' escapes to the field 'FieldFromPointerParam' and is later invalidated}}
@@ -664,7 +664,7 @@ void InvalidatedGlobalLocalVector() {
   GlobalFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the global variable 'GlobalFromLocalVector' and 
is later invalidated}} \
                                             // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
                                             // expected-note {{expression 
aliases the storage of local variable 'strings'}}
-  strings.push_back("1"); // expected-note {{local variable 'strings' is 
invalidated here}}
+  strings.push_back("1");                   // expected-note {{local variable 
'strings' is invalidated here}}
 }
 
 void InvalidatedGlobalByValueParamString(std::string s) {
@@ -680,7 +680,7 @@ void InvalidatedGlobalRefParamString(std::string &s) { // 
expected-warning {{par
 void InvalidatedGlobalDelete() {
   int *p = new int;  // expected-warning {{allocated object escapes to the 
global variable 'GlobalFromNew' and is later invalidated}}
   GlobalFromNew = p; // expected-note {{local variable 'p' aliases the storage 
of allocated object}}
-  delete p; // expected-note {{allocated object is freed here}}
+  delete p;          // expected-note {{allocated object is freed here}}
 }
 
 void InvalidatedGlobalDeleteParam(int *p) { // expected-warning {{parameter 
'p' escapes to the global variable 'GlobalFromPointerParam' and is later 
invalidated}}
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index bfbe1e66f61190..2abd81eb2b0bc8 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -1642,7 +1642,7 @@ View range_based_for_use_after_return() {
   MyObjStorage s;
   for (const MyObj &o : s) { // expected-warning {{stack memory associated 
with local variable 's' is returned}} \
                              // expected-note {{local variable '__range1' 
aliases the storage of local variable 's'}}
-    return o;  // expected-note {{returned here}}
+    return o;                // expected-note {{returned here}}
   }
   return *s.begin();  // expected-warning {{stack memory associated with local 
variable 's' is returned}} \
                       // expected-note {{result of call to 'begin' aliases the 
storage of local variable 's' because the implicit object parameter is marked 
as lifetimebound}} \
@@ -1995,7 +1995,7 @@ const MyObj* testData(MyObj obj) {
                     // expected-note {{local variable 'v' aliases the storage 
of parameter 'obj'}}
 }
 const int* testLifetimeboundAccessorOfMyObj(MyObj obj) {
-  View v = obj;           // expected-warning {{stack memory associated with 
parameter 'obj' is returned}}
+  View v = obj;                // expected-warning {{stack memory associated 
with parameter 'obj' is returned}}
   const MyObj* ptr = v.data(); // expected-note {{local variable 'v' aliases 
the storage of parameter 'obj'}} \
                                // expected-note {{result of call to 'data' 
aliases the storage of parameter 'obj' because the implicit object parameter is 
inferred as lifetimebound}}
   return ptr->getData();  // expected-note {{returned here}}
@@ -2361,8 +2361,8 @@ namespace lambda_captures {
 auto return_ref_capture() {
   int local = 1;
   auto lambda = [&local]() { return local; }; // expected-warning {{stack 
memory associated with local variable 'local' is returned}}
-  return lambda; // expected-note {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
+  return lambda;                              // expected-note {{returned 
here}} \
+                                              // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local'}}
 }
 
 void safe_ref_capture() {
@@ -2379,7 +2379,7 @@ auto capture_int_by_value() {
 
 auto capture_view_by_value() {
   MyObj obj;
-  View v(obj); // expected-warning {{stack memory associated with local 
variable 'obj' is returned}}
+  View v(obj);                       // expected-warning {{stack memory 
associated with local variable 'obj' is returned}}
   auto lambda = [v]() { return v; }; // expected-note {{local variable 'v' 
aliases the storage of local variable 'obj'}}
   return lambda; // expected-note {{returned here}}
 }
@@ -2395,8 +2395,8 @@ auto capture_pointer_by_ref() {
   MyObj obj;
   MyObj* p = &obj;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda; // expected-note {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'p'}}
+  return lambda;                      // expected-note {{returned here}} \
+                                      // expected-note {{local variable 
'lambda' aliases the storage of local variable 'p'}}
 }
 
 auto capture_multiple() {
@@ -2412,28 +2412,28 @@ auto capture_multiple() {
 
 auto capture_raw_pointer_by_value() {
   int x;
-  int* p = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
+  int* p = &x;                       // expected-warning {{stack memory 
associated with local variable 'x' is returned}}
   auto lambda = [p]() { return p; }; // expected-note {{local variable 'p' 
aliases the storage of local variable 'x'}}
   return lambda; // expected-note {{returned here}}
 }
 
 auto capture_raw_pointer_init_capture() {
   int x;
-  int* p = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
+  int* p = &x;                           // expected-warning {{stack memory 
associated with local variable 'x' is returned}}
   auto lambda = [q = p]() { return q; }; // expected-note {{local variable 'p' 
aliases the storage of local variable 'x'}}
   return lambda; // expected-note {{returned here}}
 }
 
 auto capture_view_init_capture() {
   MyObj obj;
-  View v(obj); // expected-warning {{stack memory associated with local 
variable 'obj' is returned}}
+  View v(obj);                           // expected-warning {{stack memory 
associated with local variable 'obj' is returned}}
   auto lambda = [w = v]() { return w; }; // expected-note {{local variable 'v' 
aliases the storage of local variable 'obj'}}
   return lambda; // expected-note {{returned here}}
 }
 
 auto capture_lambda() {
   int x;
-  auto inner = [&x]() { return x; }; // expected-warning {{stack memory 
associated with local variable 'x' is returned}}
+  auto inner = [&x]() { return x; };          // expected-warning {{stack 
memory associated with local variable 'x' is returned}}
   auto outer = [inner]() { return inner(); }; // expected-note {{local 
variable 'inner' aliases the storage of local variable 'x'}}
   return outer; // expected-note {{returned here}}
 }
@@ -2448,8 +2448,8 @@ auto return_copied_lambda() {
 auto implicit_ref_capture() {
   int local = 1;
   auto lambda = [&]() { return local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return lambda; // expected-note {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
+  return lambda;                         // expected-note {{returned here}} \
+                                         // expected-note {{local variable 
'lambda' aliases the storage of local variable 'local'}}
 }
 
 // TODO: Include the name of the variable in the diagnostic to improve
@@ -2458,14 +2458,14 @@ auto implicit_ref_capture() {
 auto implicit_ref_capture_multiple() {
   int local = 1, local2 = 2;
   auto lambda = [&]() { return local + local2; }; // expected-warning {{stack 
memory associated with local variable 'local2' is returned}} expected-warning 
{{stack memory associated with local variable 'local' is returned}}
-  return lambda; // expected-note 2 {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local2'}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'local'}}
+  return lambda;                                  // expected-note 2 
{{returned here}} \
+                                                  // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local2'}} \
+                                                  // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local'}}
 }
 
 auto implicit_value_capture() {
   MyObj obj;
-  View v(obj); // expected-warning {{stack memory associated with local 
variable 'obj' is returned}}
+  View v(obj);                       // expected-warning {{stack memory 
associated with local variable 'obj' is returned}}
   auto lambda = [=]() { return v; }; // expected-note {{local variable 'v' 
aliases the storage of local variable 'obj'}}
   return lambda; // expected-note {{returned here}}
 }
@@ -2498,15 +2498,15 @@ auto capture_static_address_by_ref() {
   static int local = 1;
   int* p = &local;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda; // expected-note {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'p'}}
+  return lambda;                      // expected-note {{returned here}} \
+                                      // expected-note {{local variable 
'lambda' aliases the storage of local variable 'p'}}
 }
 
 auto capture_multilevel_pointer() {
   int x;
-  int *p = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
-  int **q = &p; // expected-warning {{stack memory associated with local 
variable 'p' is returned}}
-  int ***r = &q; // expected-warning {{stack memory associated with local 
variable 'q' is returned}}
+  int *p = &x;                                     // expected-warning {{stack 
memory associated with local variable 'x' is returned}}
+  int **q = &p;                                    // expected-warning {{stack 
memory associated with local variable 'p' is returned}}
+  int ***r = &q;                                   // expected-warning {{stack 
memory associated with local variable 'q' is returned}}
   auto lambda = [=]() { return *p + **q + ***r; }; // expected-note {{local 
variable 'p' aliases the storage of local variable 'x'}} \
                                                    // expected-note {{local 
variable 'r' aliases the storage of local variable 'q'}} \
                                                    // expected-note {{local 
variable 'q' aliases the storage of local variable 'p'}}
@@ -3136,7 +3136,7 @@ void binary_conditional_throw_void(int *in) {
 
 int *binary_conditional_throw_dangling() {
   int x;
-  int *p = &x; // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
+  int *p = &x;         // expected-warning {{stack memory associated with 
local variable 'x' is returned}}
   return p ?: throw 1; // expected-note {{returned here}} \
                        // expected-note {{local variable 'p' aliases the 
storage of local variable 'x'}}
 }
@@ -3821,8 +3821,8 @@ std::function<void()> reassign_safe_then_unsafe() {
   int local = 2;
   std::function<void()> f = []() { (void)safe; };
   f = [&local]() { (void)local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return f; // expected-note {{returned here}} \
-            // expected-note {{local variable 'f' aliases the storage of local 
variable 'local'}}
+  return f;                        // expected-note {{returned here}} \
+                                   // expected-note {{local variable 'f' 
aliases the storage of local variable 'local'}}
 }
 
 std::function<void()> reassign_unsafe_then_safe() {
@@ -3942,10 +3942,10 @@ void deref_use_after_scope() {
 namespace GH191954 {
   int* return_moved_pointer() {
     int x;
-    int* f = &x;      // expected-warning {{stack memory associated with local 
variable 'x' is returned}}
+    int* f = &x;       // expected-warning {{stack memory associated with 
local variable 'x' is returned}}
     int* a;
     a = std::move(f); // expected-note {{result of call to 'move<int *&>' 
aliases the storage of local variable 'x'}}
-    return a; // expected-note {{returned here}}
+    return a;         // expected-note {{returned here}}
   }
 
   int* return_moved_pointer2() {
@@ -3957,7 +3957,7 @@ namespace GH191954 {
 
   View return_moved_view() {
     MyObj o;
-    View v(o); // expected-warning {{stack memory associated with local 
variable 'o' is returned}}
+    View v(o);              // expected-warning {{stack memory associated with 
local variable 'o' is returned}}
     View v2 = std::move(v); // expected-note {{result of call to 'move<View 
&>' aliases the storage of local variable 'o'}}
     return v2; // expected-note {{returned here}}
   }
@@ -3995,8 +3995,8 @@ View use_after_return_capture_by() {
   MyObj a;
   View res;
   setCaptureBy(res, a);   // expected-warning {{stack memory associated with 
local variable 'a' is returned}}
-  return res;     // expected-note {{returned here}} \
-                  // expected-note {{local variable 'res' aliases the storage 
of local variable 'a'}}
+  return res;             // expected-note {{returned here}} \
+                          // expected-note {{local variable 'res' aliases the 
storage of local variable 'a'}}
                    
 }
 

>From 84f66d030285c2301eece2217f02119cfee52638 Mon Sep 17 00:00:00 2001
From: Yuan Suo <[email protected]>
Date: Sun, 18 Oct 2026 09:35:54 +0800
Subject: [PATCH 5/5] Rebase and resolve some conflicts

Signed-off-by: Yuan Suo <[email protected]>
---
 .../Analyses/LifetimeSafety/LoanPropagation.h |  6 --
 .../LifetimeSafety/LoanPropagation.cpp        |  9 +--
 .../LifetimeSafety/annotation-suggestions.cpp | 18 ++----
 clang/test/Sema/LifetimeSafety/capture-by.cpp |  2 +-
 .../Sema/LifetimeSafety/dangling-global.cpp   |  2 +-
 .../explicit-object-param-no-crash.cpp        |  6 +-
 .../Sema/LifetimeSafety/invalidations.cpp     | 13 ++--
 clang/test/Sema/LifetimeSafety/nocfg.cpp      |  4 +-
 clang/test/Sema/LifetimeSafety/safety-c.c     |  6 +-
 clang/test/Sema/LifetimeSafety/safety.cpp     | 60 ++++++-------------
 10 files changed, 39 insertions(+), 87 deletions(-)

diff --git 
a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h 
b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
index d8dffb4fc1a268..d410adb1caef03 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h
@@ -57,12 +57,6 @@ class LoanPropagationAnalysis {
                                                    const LoanID TargetLoan,
                                                    const CFG *Cfg) const;
 
-  /// Like the above, starting from the origin \p OEF lets escape. Empty if it
-  /// does not hold \p TargetLoan.
-  llvm::SmallVector<OriginID> buildOriginFlowChain(const OriginEscapesFact 
*OEF,
-                                                   const LoanID TargetLoan,
-                                                   const CFG *Cfg) const;
-
 private:
   class Impl;
   std::unique_ptr<Impl> PImpl;
diff --git a/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp 
b/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
index 7db184a09a41e0..4f3ee8c7dab8a7 100644
--- a/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp
@@ -356,14 +356,7 @@ llvm::SmallVector<OriginID> 
LoanPropagationAnalysis::buildOriginFlowChain(
   if (const auto *UF = llvm::dyn_cast<UseFact>(F))
     return PImpl->buildOriginFlowChain(UF, TargetLoan, Cfg);
   if (const auto *OEF = llvm::dyn_cast<OriginEscapesFact>(F))
-    return PImpl->buildOriginFlowChain(OEF, OEF->getEscapedOriginID(),
-                                       TargetLoan, Cfg);
+    return PImpl->buildOriginFlowChain(OEF, TargetLoan, Cfg);
   llvm_unreachable("Unhandled Fact type");
 }
-llvm::SmallVector<OriginID>
-LoanPropagationAnalysis::buildOriginFlowChain(const OriginEscapesFact *OEF,
-                                              const LoanID TargetLoan,
-                                              const CFG *Cfg) const {
-  return PImpl->buildOriginFlowChain(OEF, TargetLoan, Cfg);
-}
 } // namespace clang::lifetimes::internal
diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp 
b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index 2ca3a94f41b7ac..70ef67ceacd916 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -528,8 +528,7 @@ struct CaptureRefToView {
 CaptureRefToView test_ref_to_view() {
   MyObj obj;
   CaptureRefToView x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;                // expected-note {{returned here}} \
-                           // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
+  return x;                // expected-note {{returned here}}
 }
 
 struct CaptureRefToPtr {
@@ -540,8 +539,7 @@ struct CaptureRefToPtr {
 CaptureRefToPtr test_ref_to_ptr() {
   MyObj obj;
   CaptureRefToPtr x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;               // expected-note {{returned here}} \
-                          // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
+  return x;               // expected-note {{returned here}}
 }
 
 struct CaptureViewToView {
@@ -564,8 +562,7 @@ struct CapturePtrToPtr {
 CapturePtrToPtr test_ptr_to_ptr() {
   MyObj obj;
   CapturePtrToPtr x(&obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;                // expected-note {{returned here}} \
-                           // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
+  return x;                // expected-note {{returned here}}
 }
 
 struct CaptureRefToRef {
@@ -576,8 +573,7 @@ struct CaptureRefToRef {
 CaptureRefToRef test_ref_to_ref() {
   MyObj obj;
   CaptureRefToRef x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;               // expected-note {{returned here}} \
-                          // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
+  return x;               // expected-note {{returned here}}
 }
 
 struct BaseWithView {
@@ -592,8 +588,7 @@ struct CaptureRefToBaseView : BaseWithView {
 CaptureRefToBaseView test_ref_to_base_view() {
   MyObj obj;
   CaptureRefToBaseView x(obj); // expected-warning {{stack memory associated 
with local variable 'obj' is returned}}
-  return x;                    // expected-note {{returned here}} \
-                               // expected-note {{local variable 'x' aliases 
the storage of local variable 'obj'}}
+  return x;                    // expected-note {{returned here}}
 }
 } // namespace capturing_constructor
 
@@ -665,8 +660,7 @@ struct HasCtorField {
 HasCtorField test_dangling_field_ctor() {
   MyObj obj;
   HasCtorField x(obj); // expected-warning {{stack memory associated with 
local variable 'obj' is returned}}
-  return x;            // expected-note {{returned here}} \
-                       // expected-note {{local variable 'x' aliases the 
storage of local variable 'obj'}}
+  return x;            // expected-note {{returned here}}
 }
 
 struct HasSetterField {
diff --git a/clang/test/Sema/LifetimeSafety/capture-by.cpp 
b/clang/test/Sema/LifetimeSafety/capture-by.cpp
index 8331c6a5437d4a..f6bf9d71d4c903 100644
--- a/clang/test/Sema/LifetimeSafety/capture-by.cpp
+++ b/clang/test/Sema/LifetimeSafety/capture-by.cpp
@@ -196,7 +196,7 @@ void temporary_pointer_lifetimebound_capture() {
 }
 
 void temporary_nested_lifetimebound_capture() {
-  capturePointer(getLifetimeBoundPointer(*getLifetimeBoundPointer( // cfg-note 
2 {{result of call to 'getLifetimeBoundPointer' aliases the storage of 
temporary object because parameter 's' is lifetimebound}}
+  capturePointer(getLifetimeBoundPointer(*getLifetimeBoundPointer( // cfg-note 
2 {{result of call to 'getLifetimeBoundPointer' aliases the storage of 
temporary object because parameter 's' is marked as lifetimebound}}
     std::string())), x);  // expected-warning {{object whose reference is 
captured by 'x' will be destroyed at the end of the full-expression}} \
                           // cfg-warning {{stack memory associated with 
temporary object escapes to the global variable 'x' which will dangle}}
 }
diff --git a/clang/test/Sema/LifetimeSafety/dangling-global.cpp 
b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
index 3681ae9fcab669..2013f9479a7842 100644
--- a/clang/test/Sema/LifetimeSafety/dangling-global.cpp
+++ b/clang/test/Sema/LifetimeSafety/dangling-global.cpp
@@ -27,7 +27,7 @@ void invoke_function_with_side_effects() {
 void inlined() {
   int local;
   global = &local;        // expected-warning {{stack memory associated with 
local variable 'local' escapes to the global variable 'global_backup' which 
will dangle}}
-  global_backup = global; // expected-note {{global variable 'global' aliases 
the storage of local variable 'local'}}
+  global_backup = global;
   global = nullptr;
 }
 
diff --git a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp 
b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
index 4437ba773ffffc..31c07d9d7f1028 100644
--- a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
+++ b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
@@ -78,16 +78,14 @@ const int *t1(Holder h) {
   const int *ptr = h.borrow(); // expected-warning {{stack memory associated 
with parameter 'h' is returned}} \
                                // expected-note {{result of call to 'borrow' 
aliases the storage of parameter 'h' because the implicit object parameter is 
marked as lifetimebound}}
   static_cast<Holder &&>(h).consume();
-  return ptr; // expected-note {{returned here}} \
-              // expected-note {{local variable 'ptr' aliases the storage of 
parameter 'h'}}
+  return ptr; // expected-note {{returned here}}
 }
 
 const int *t2(Holder h) {
   const int *ptr = h.borrow(); // expected-warning {{stack memory associated 
with parameter 'h' is returned}} \
                                // expected-note {{result of call to 'borrow' 
aliases the storage of parameter 'h' because the implicit object parameter is 
marked as lifetimebound}}
   std::move(h).consume();
-  return ptr; // expected-note {{returned here}} \
-              // expected-note {{local variable 'ptr' aliases the storage of 
parameter 'h'}}
+  return ptr; // expected-note {{returned here}}
 }
 
 struct Set {
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp 
b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index af09676981d0db..3d9eb493cfdb43 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -578,8 +578,7 @@ struct SinkOwnerBorrow {
 struct SinkInteriorBorrow {
   const char *dest_; // expected-note {{this field dangles}}
 
-  SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // 
expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later 
invalidated}} \
-                                                                       // 
expected-note {{result of call to 'data' aliases the storage of parameter 
'dest'}}
+  SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // 
expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later 
invalidated}}
     if (n > 0)
       dest->clear(); // expected-note {{parameter 'dest' is invalidated here}}
   }
@@ -599,14 +598,14 @@ struct S {
     std::vector<std::string> strings;
     FieldFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the field 'FieldFromLocalVector' and is later 
invalidated}} \
                                              // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
-                                             // expected-note {{expression 
aliases the storage of local variable 'strings'}}
+                                             // expected-note {{result of call 
to 'operator*' aliases the storage of local variable 'strings' because the 
implicit object parameter is inferred as lifetimebound}}
     strings.push_back("1");                  // expected-note {{local variable 
'strings' is invalidated here}}
   }
 
   void InvalidatedFieldByValueParamVector(std::vector<std::string> strings) {
     FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is 
later invalidated}} \
                                                     // expected-note {{result 
of call to 'begin' aliases the storage of parameter 'strings'}} \
-                                                    // expected-note 
{{expression aliases the storage of parameter 'strings'}}
+                                                    // expected-note {{result 
of call to 'operator*' aliases the storage of parameter 'strings' because the 
implicit object parameter is inferred as lifetimebound}}
     strings.push_back("1");                         // expected-note 
{{parameter 'strings' is invalidated here}}
   }
 
@@ -628,7 +627,7 @@ struct S {
 
   void InvalidatedFieldDelete() {
     int *p = new int; // expected-warning {{allocated object escapes to the 
field 'FieldFromNew' and is later invalidated}}
-    FieldFromNew = p; // expected-note {{local variable 'p' aliases the 
storage of allocated object}}
+    FieldFromNew = p;
     delete p;         // expected-note {{allocated object is freed here}}
   }
 
@@ -663,7 +662,7 @@ void InvalidatedGlobalLocalVector() {
   std::vector<std::string> strings;
   GlobalFromLocalVector = *strings.begin(); // expected-warning {{local 
variable 'strings' escapes to the global variable 'GlobalFromLocalVector' and 
is later invalidated}} \
                                             // expected-note {{result of call 
to 'begin' aliases the storage of local variable 'strings'}} \
-                                            // expected-note {{expression 
aliases the storage of local variable 'strings'}}
+                                            // expected-note {{result of call 
to 'operator*' aliases the storage of local variable 'strings' because the 
implicit object parameter is inferred as lifetimebound}}
   strings.push_back("1");                   // expected-note {{local variable 
'strings' is invalidated here}}
 }
 
@@ -679,7 +678,7 @@ void InvalidatedGlobalRefParamString(std::string &s) { // 
expected-warning {{par
 
 void InvalidatedGlobalDelete() {
   int *p = new int;  // expected-warning {{allocated object escapes to the 
global variable 'GlobalFromNew' and is later invalidated}}
-  GlobalFromNew = p; // expected-note {{local variable 'p' aliases the storage 
of allocated object}}
+  GlobalFromNew = p;
   delete p;          // expected-note {{allocated object is freed here}}
 }
 
diff --git a/clang/test/Sema/LifetimeSafety/nocfg.cpp 
b/clang/test/Sema/LifetimeSafety/nocfg.cpp
index 405312b35eff45..82aec5d3b279df 100644
--- a/clang/test/Sema/LifetimeSafety/nocfg.cpp
+++ b/clang/test/Sema/LifetimeSafety/nocfg.cpp
@@ -375,7 +375,7 @@ const char *trackThroughMultiplePointer() {
 struct X {
   X(std::unique_ptr<int> up) :
     pointee(*up),             // cfg-warning {{may have been moved.}} \
-                              // cfg-note {{expression aliases the storage of 
parameter 'up'}}
+                              // cfg-note {{result of call to 'operator*' 
aliases the storage of parameter 'up' because the implicit object parameter is 
inferred as lifetimebound}}
     pointee2(up.get()),       // cfg-warning {{may have been moved.}} \
                               // cfg-note {{result of call to 'get' aliases 
the storage of parameter 'up'}}
     pointer(std::move(up)) {} // cfg-note 2 {{potentially moved here}}
@@ -613,12 +613,10 @@ FooView test3(int i, std::optional<Foo> a) {
     return *a; // expected-warning {{address of stack memory}} \
                // cfg-note {{result of call to 'operator*' aliases the storage 
of parameter 'a' because the implicit object parameter is inferred as 
lifetimebound}} \
                // cfg-warning {{stack memory associated with parameter 'a' is 
returned}} \
-               // cfg-note {{expression aliases the storage of parameter 'a'}} 
\
                // cfg-note {{returned here}}
   return a.value(); // expected-warning {{address of stack memory}} \
                     // cfg-note {{result of call to 'value' aliases the 
storage of parameter 'a' because the implicit object parameter is inferred as 
lifetimebound}} \
                     // cfg-warning {{stack memory associated with parameter 
'a' is returned}} \
-                    // cfg-note {{result of call to 'value' aliases the 
storage of parameter 'a'}} \
                     // cfg-note {{returned here}}
 }
 } // namespace GH93386
diff --git a/clang/test/Sema/LifetimeSafety/safety-c.c 
b/clang/test/Sema/LifetimeSafety/safety-c.c
index ed0b9e21eb53ee..8e6ca521c18046 100644
--- a/clang/test/Sema/LifetimeSafety/safety-c.c
+++ b/clang/test/Sema/LifetimeSafety/safety-c.c
@@ -181,8 +181,7 @@ void *void_pointer_dereference(void) {
 int *atomic_pointer_declref(void) {
   int value;
   _Atomic(int *) p = &value; // expected-warning {{stack memory associated 
with local variable 'value' is returned}}
-  return p;                  // expected-note {{returned here}} \
-                             // expected-note {{local variable 'p' aliases the 
storage of local variable 'value'}}
+  return p;                  // expected-note {{returned here}}
 }
 
 int *atomic_pointer_static(void) {
@@ -194,8 +193,7 @@ int *atomic_pointer_static(void) {
 int **atomic_pointer_multilevel(void) {
   int *inner;
   _Atomic(int **) p = &inner; // expected-warning {{stack memory associated 
with local variable 'inner' is returned}}
-  return p;                   // expected-note {{returned here}} \
-                              // expected-note {{local variable 'p' aliases 
the storage of local variable 'inner'}}
+  return p;                   // expected-note {{returned here}}
 }
 
 // In C, a pointer compound assignment is a prvalue; its result still carries
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index 2abd81eb2b0bc8..63f79324cd8696 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -530,8 +530,7 @@ View conditional_assign_both_branches(const MyObj& safe, 
bool c) {
   else {
     p = safe;
   }
-  return p;     // expected-note {{returned here}} \
-                // expected-note {{local variable 'p' aliases the storage of 
local variable 's'}}
+  return p;     // expected-note {{returned here}}
 
 }
 
@@ -539,8 +538,7 @@ View reassign_safe_to_local(const MyObj& safe) {
   MyObj local;
   View p = safe;
   p = local;    // expected-warning {{stack memory associated with local 
variable 'local' is returned}}
-  return p;     // expected-note {{returned here}} \
-                // expected-note {{local variable 'p' aliases the storage of 
local variable 'local'}}
+  return p;     // expected-note {{returned here}}
 }
 
 View pointer_chain_to_local() {
@@ -556,13 +554,11 @@ View multiple_assign_multiple_return(const MyObj& safe, 
bool c1, bool c2) {
   View p;
   if (c1) {
     p = local1;       // expected-warning {{stack memory associated with local 
variable 'local1' is returned}}
-    return p;         // expected-note {{returned here}} \
-                      // expected-note {{local variable 'p' aliases the 
storage of local variable 'local1'}}
+    return p;         // expected-note {{returned here}}
   }
   else if (c2) {
     p = local2;       // expected-warning {{stack memory associated with local 
variable 'local2' is returned}}
-    return p;         // expected-note {{returned here}} \
-                      // expected-note {{local variable 'p' aliases the 
storage of local variable 'local2'}}
+    return p;         // expected-note {{returned here}}
   }
   p = safe;
   return p;
@@ -581,9 +577,7 @@ View multiple_assign_single_return(const MyObj& safe, bool 
c1, bool c2) {
   else {
     p = safe;
   }
-  return p;         // expected-note 2 {{returned here}} \
-                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local1'}} \
-                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local2'}}
+  return p;         // expected-note 2 {{returned here}}
 }
 
 View direct_return_of_local() {
@@ -651,8 +645,7 @@ const int* return_pointer_to_parameter_via_reference(int a, 
int b, bool cond) {
 
 const int& return_pointer_to_parameter_via_reference_1(int a) {
     const int* d = &a; // expected-warning {{stack memory associated with 
parameter 'a' is returned}}
-    return *d;         // expected-note {{returned here}} \
-                       // expected-note {{local variable 'd' aliases the 
storage of parameter 'a'}}
+    return *d;         // expected-note {{returned here}}
 }
 
 const int& get_ref_to_local() {
@@ -750,8 +743,7 @@ View uar_before_uaf(const MyObj& safe, bool c) {
     MyObj local_obj; 
     p = local_obj;  // expected-warning {{stack memory associated with local 
variable 'local_obj' is returned}}
     if (c) {
-      return p;     // expected-note {{returned here}} \
-                    // expected-note {{local variable 'p' aliases the storage 
of local variable 'local_obj'}}
+      return p;     // expected-note {{returned here}}
     }
   }
   p.use();
@@ -1981,8 +1973,7 @@ void bar() {
 namespace DereferenceViews {
 const MyObj& testDeref(MyObj obj) {
   View v = obj; // expected-warning {{stack memory associated with parameter 
'obj' is returned}}
-  return *v;    // expected-note {{returned here}} \
-                // expected-note {{local variable 'v' aliases the storage of 
parameter 'obj'}}
+  return *v;    // expected-note {{returned here}}
 }
 const MyObj* testDerefAddr(MyObj obj) {
   View v = obj; // expected-warning {{stack memory associated with parameter 
'obj' is returned}}
@@ -1991,8 +1982,7 @@ const MyObj* testDerefAddr(MyObj obj) {
 }
 const MyObj* testData(MyObj obj) {
   View v = obj;     // expected-warning {{stack memory associated with 
parameter 'obj' is returned}}
-  return v.data();  // expected-note {{returned here}} \
-                    // expected-note {{local variable 'v' aliases the storage 
of parameter 'obj'}}
+  return v.data();  // expected-note {{returned here}}
 }
 const int* testLifetimeboundAccessorOfMyObj(MyObj obj) {
   View v = obj;                // expected-warning {{stack memory associated 
with parameter 'obj' is returned}}
@@ -2303,8 +2293,7 @@ View test1(std::string a) {
 
 View test2(std::string a) {
   View b = View(a); // expected-warning {{stack memory associated with 
parameter 'a' is returned}}
-  return b;         // expected-note {{returned here}} \
-                    // expected-note {{local variable 'b' aliases the storage 
of parameter 'a'}}
+  return b;         // expected-note {{returned here}}
 }
 
 View test3(std::string a) {
@@ -2361,8 +2350,7 @@ namespace lambda_captures {
 auto return_ref_capture() {
   int local = 1;
   auto lambda = [&local]() { return local; }; // expected-warning {{stack 
memory associated with local variable 'local' is returned}}
-  return lambda;                              // expected-note {{returned 
here}} \
-                                              // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local'}}
+  return lambda;                              // expected-note {{returned 
here}}
 }
 
 void safe_ref_capture() {
@@ -2395,8 +2383,7 @@ auto capture_pointer_by_ref() {
   MyObj obj;
   MyObj* p = &obj;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda;                      // expected-note {{returned here}} \
-                                      // expected-note {{local variable 
'lambda' aliases the storage of local variable 'p'}}
+  return lambda;                      // expected-note {{returned here}}
 }
 
 auto capture_multiple() {
@@ -2405,9 +2392,7 @@ auto capture_multiple() {
     &a,  // expected-warning {{stack memory associated with local variable 'a' 
is returned}}
     &b   // expected-warning {{stack memory associated with local variable 'b' 
is returned}}
   ]() { return a + b; };
-  return lambda; // expected-note 2 {{returned here}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'a'}} \
-                 // expected-note {{local variable 'lambda' aliases the 
storage of local variable 'b'}}
+  return lambda; // expected-note 2 {{returned here}}
 }
 
 auto capture_raw_pointer_by_value() {
@@ -2448,8 +2433,7 @@ auto return_copied_lambda() {
 auto implicit_ref_capture() {
   int local = 1;
   auto lambda = [&]() { return local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return lambda;                         // expected-note {{returned here}} \
-                                         // expected-note {{local variable 
'lambda' aliases the storage of local variable 'local'}}
+  return lambda;                         // expected-note {{returned here}}
 }
 
 // TODO: Include the name of the variable in the diagnostic to improve
@@ -2458,9 +2442,7 @@ auto implicit_ref_capture() {
 auto implicit_ref_capture_multiple() {
   int local = 1, local2 = 2;
   auto lambda = [&]() { return local + local2; }; // expected-warning {{stack 
memory associated with local variable 'local2' is returned}} expected-warning 
{{stack memory associated with local variable 'local' is returned}}
-  return lambda;                                  // expected-note 2 
{{returned here}} \
-                                                  // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local2'}} \
-                                                  // expected-note {{local 
variable 'lambda' aliases the storage of local variable 'local'}}
+  return lambda;                                  // expected-note 2 
{{returned here}}
 }
 
 auto implicit_value_capture() {
@@ -2498,8 +2480,7 @@ auto capture_static_address_by_ref() {
   static int local = 1;
   int* p = &local;
   auto lambda = [&p]() { return p; }; // expected-warning {{stack memory 
associated with local variable 'p' is returned}}
-  return lambda;                      // expected-note {{returned here}} \
-                                      // expected-note {{local variable 
'lambda' aliases the storage of local variable 'p'}}
+  return lambda;                      // expected-note {{returned here}}
 }
 
 auto capture_multilevel_pointer() {
@@ -3137,8 +3118,7 @@ void binary_conditional_throw_void(int *in) {
 int *binary_conditional_throw_dangling() {
   int x;
   int *p = &x;         // expected-warning {{stack memory associated with 
local variable 'x' is returned}}
-  return p ?: throw 1; // expected-note {{returned here}} \
-                       // expected-note {{local variable 'p' aliases the 
storage of local variable 'x'}}
+  return p ?: throw 1; // expected-note {{returned here}}
 }
 
 #endif
@@ -3821,8 +3801,7 @@ std::function<void()> reassign_safe_then_unsafe() {
   int local = 2;
   std::function<void()> f = []() { (void)safe; };
   f = [&local]() { (void)local; }; // expected-warning {{stack memory 
associated with local variable 'local' is returned}}
-  return f;                        // expected-note {{returned here}} \
-                                   // expected-note {{local variable 'f' 
aliases the storage of local variable 'local'}}
+  return f;                        // expected-note {{returned here}}
 }
 
 std::function<void()> reassign_unsafe_then_safe() {
@@ -3995,8 +3974,7 @@ View use_after_return_capture_by() {
   MyObj a;
   View res;
   setCaptureBy(res, a);   // expected-warning {{stack memory associated with 
local variable 'a' is returned}}
-  return res;             // expected-note {{returned here}} \
-                          // expected-note {{local variable 'res' aliases the 
storage of local variable 'a'}}
+  return res;             // expected-note {{returned here}}
                    
 }
 

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

Reply via email to