https://github.com/aeft updated https://github.com/llvm/llvm-project/pull/184295

>From 746e45f465c57d7503de664f8239cdc2eebf39d9 Mon Sep 17 00:00:00 2001
From: Alex Wang <[email protected]>
Date: Mon, 2 Mar 2026 23:34:35 -0800
Subject: [PATCH 1/2] [LifetimeSafety] Detect use of a reference type as a use
 of underlying origin

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp   | 3 ++-
 clang/test/Sema/warn-lifetime-safety-invalidations.cpp | 8 +++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 80a73a2bf687e..90d604100438b 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -366,7 +366,8 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr,
   // assigned.
   RHSList = getRValueOrigins(RHSExpr, RHSList);
 
-  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr))
+  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr);
+      DRE_LHS && !DRE_LHS->getDecl()->getType()->isReferenceType())
     markUseAsWrite(DRE_LHS);
   // Kill the old loans of the destination origin and flow the new loans
   // from the source origin.
diff --git a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp 
b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
index 486edd7a1a023..6820823bd7f7f 100644
--- a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
@@ -259,11 +259,9 @@ namespace ElementReferences {
 
 void ReferenceToVectorElement() {
   std::vector<int> v = {1, 2, 3};
-  int& ref = v[0];
-  v.push_back(4);
-  // FIXME: Detect this as a use of 'ref'.
-  // https://github.com/llvm/llvm-project/issues/180187
-  ref = 10;
+  int& ref = v[0]; // expected-warning {{object whose reference is captured is 
later invalidated}}
+  v.push_back(4);  // expected-note {{invalidated here}}
+  ref = 10;        // expected-note {{later used here}}
   (void)ref;
 }
 

>From 3cd496a35b4a46f341911250f0346026ab71968d Mon Sep 17 00:00:00 2001
From: Alex Wang <[email protected]>
Date: Tue, 3 Mar 2026 12:49:12 -0800
Subject: [PATCH 2/2] fix reference to pointer

---
 clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp |  8 +++++---
 .../test/Sema/warn-lifetime-safety-invalidations.cpp | 12 ++++++++++++
 clang/test/Sema/warn-lifetime-safety.cpp             | 12 ++++++++++++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 90d604100438b..b6afecfe55281 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -366,9 +366,11 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr,
   // assigned.
   RHSList = getRValueOrigins(RHSExpr, RHSList);
 
-  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr);
-      DRE_LHS && !DRE_LHS->getDecl()->getType()->isReferenceType())
-    markUseAsWrite(DRE_LHS);
+  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr)) {
+    QualType QT = DRE_LHS->getDecl()->getType();
+    if (!QT->isReferenceType() || hasOrigins(QT->getPointeeType()))
+      markUseAsWrite(DRE_LHS);
+  }
   // Kill the old loans of the destination origin and flow the new loans
   // from the source origin.
   flow(LHSList->peelOuterOrigin(), RHSList, /*Kill=*/true);
diff --git a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp 
b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
index 6820823bd7f7f..bab4b28a9e172 100644
--- a/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-invalidations.cpp
@@ -265,6 +265,18 @@ void ReferenceToVectorElement() {
   (void)ref;
 }
 
+void PointerRefToVectorElement() {
+  std::vector<int*> v = {nullptr, nullptr};
+  int*& ref = v[0];
+  v.push_back(nullptr);
+  // FIXME: Writing through a reference to an invalidated vector element
+  // should be detected. Origin_outer (reference binding) is incorrectly
+  // killed by markUseAsWrite.
+  int y;
+  ref = &y;
+  (void)*ref;
+}
+
 void PointerToVectorElement() {
   std::vector<int> v = {1, 2, 3};
   int* ptr = &v[0];  // expected-warning {{object whose reference is captured 
is later invalidated}}
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp 
b/clang/test/Sema/warn-lifetime-safety.cpp
index 76d43445f8636..866542303414a 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -752,6 +752,18 @@ void no_error_if_dangle_then_rescue_gsl() {
   v.use();     // This is safe.
 }
 
+void no_error_if_dangle_then_rescue_via_ref() {
+  MyObj safe;
+  MyObj* p;
+  MyObj*& ref = p;
+  {
+    MyObj temp;
+    ref = &temp;  // p temporarily points to temp via ref.
+  }
+  ref = &safe;    // p is "rescued" via ref before use.
+  (void)*ref;     // This is safe.
+}
+
 void no_error_loan_from_current_iteration(bool cond) {
   // See https://github.com/llvm/llvm-project/issues/156959.
   MyObj b;

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

Reply via email to