https://github.com/heturing updated 
https://github.com/llvm/llvm-project/pull/204797

>From a53fd784c5cc4e8e7808d547196f00b094889f0e Mon Sep 17 00:00:00 2001
From: Jiaqi He <[email protected]>
Date: Fri, 19 Jun 2026 18:48:23 +0800
Subject: [PATCH 1/2] [LifetimeSafety] resolved lifetimeBound violation in
 constructor

---
 clang/lib/Analysis/LifetimeSafety/Checker.cpp |  5 ++-
 .../Sema/LifetimeSafety/lifetimebound.cpp     | 35 +++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Sema/LifetimeSafety/lifetimebound.cpp

diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp 
b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index d41d6f43f837b..595f9a1d32eba 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -135,7 +135,10 @@ class LifetimeChecker {
         return;
       if (PVD->hasAttr<LifetimeBoundAttr>()) {
         // Track that this lifetimebound parameter correctly escapes.
-        if (isa<ReturnEscapeFact>(OEF))
+        bool isVerifiedEscape =
+            isa<ReturnEscapeFact>(OEF) ||
+            (isa<FieldEscapeFact>(OEF) && isa<CXXConstructorDecl>(FD));
+        if (isVerifiedEscape)
           VerifiedLiftimeboundEscapes.insert(PVD);
       } else {
         // Otherwise, suggest lifetimebound for parameter escaping through
diff --git a/clang/test/Sema/LifetimeSafety/lifetimebound.cpp 
b/clang/test/Sema/LifetimeSafety/lifetimebound.cpp
new file mode 100644
index 0000000000000..a5e26b5bdadf2
--- /dev/null
+++ b/clang/test/Sema/LifetimeSafety/lifetimebound.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety-all -verify %s
+
+
+using size_t = decltype(sizeof(0));
+extern "C" size_t strlen(const char *);
+
+#define LIFETIMEBOUND [[clang::lifetimebound]]
+
+struct View
+{
+    View(const char* data LIFETIMEBOUND)
+        : mData(data)
+        , mSize(strlen(data))
+    {}
+
+    const char* data() const {
+        return mData;
+    }
+
+    size_t size() const {
+        return mSize;
+    }
+
+private:
+    const char* mData;
+    size_t mSize;
+};
+
+void test() {
+  char *c = new char[5]; //expected-warning {{allocated object does not live 
long enough}}
+  View v(c); 
+  delete[] c;  // expected-note {{freed here}}
+  const char *c1 = v.data(); // expected-note {{later used here}}
+  return;
+}
\ No newline at end of file

>From fb7ea568eaef981d2a1b0124f491e594c299de74 Mon Sep 17 00:00:00 2001
From: Jiaqi He <[email protected]>
Date: Mon, 22 Jun 2026 16:05:51 +0800
Subject: [PATCH 2/2] refactor code and test case

---
 clang/lib/Analysis/LifetimeSafety/Checker.cpp |  9 +++--
 .../Sema/LifetimeSafety/lifetimebound.cpp     | 35 -------------------
 .../misplaced-lifetimebound-intra-tu.cpp      |  6 ++++
 3 files changed, 10 insertions(+), 40 deletions(-)
 delete mode 100644 clang/test/Sema/LifetimeSafety/lifetimebound.cpp

diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp 
b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index 595f9a1d32eba..c258a1dc3596c 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -134,11 +134,10 @@ class LifetimeChecker {
       if (IsMoved)
         return;
       if (PVD->hasAttr<LifetimeBoundAttr>()) {
-        // Track that this lifetimebound parameter correctly escapes.
-        bool isVerifiedEscape =
-            isa<ReturnEscapeFact>(OEF) ||
-            (isa<FieldEscapeFact>(OEF) && isa<CXXConstructorDecl>(FD));
-        if (isVerifiedEscape)
+        // Track that this lifetimebound parameter correctly escapes
+        // (via return or via field assignment in a constructor).
+        if (isa<ReturnEscapeFact>(OEF) ||
+            (isa<FieldEscapeFact>(OEF) && isa<CXXConstructorDecl>(FD)))
           VerifiedLiftimeboundEscapes.insert(PVD);
       } else {
         // Otherwise, suggest lifetimebound for parameter escaping through
diff --git a/clang/test/Sema/LifetimeSafety/lifetimebound.cpp 
b/clang/test/Sema/LifetimeSafety/lifetimebound.cpp
deleted file mode 100644
index a5e26b5bdadf2..0000000000000
--- a/clang/test/Sema/LifetimeSafety/lifetimebound.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety-all -verify %s
-
-
-using size_t = decltype(sizeof(0));
-extern "C" size_t strlen(const char *);
-
-#define LIFETIMEBOUND [[clang::lifetimebound]]
-
-struct View
-{
-    View(const char* data LIFETIMEBOUND)
-        : mData(data)
-        , mSize(strlen(data))
-    {}
-
-    const char* data() const {
-        return mData;
-    }
-
-    size_t size() const {
-        return mSize;
-    }
-
-private:
-    const char* mData;
-    size_t mSize;
-};
-
-void test() {
-  char *c = new char[5]; //expected-warning {{allocated object does not live 
long enough}}
-  View v(c); 
-  delete[] c;  // expected-note {{freed here}}
-  const char *c1 = v.data(); // expected-note {{later used here}}
-  return;
-}
\ No newline at end of file
diff --git 
a/clang/test/Sema/LifetimeSafety/misplaced-lifetimebound-intra-tu.cpp 
b/clang/test/Sema/LifetimeSafety/misplaced-lifetimebound-intra-tu.cpp
index 7fa4cae100509..329d06fec80af 100644
--- a/clang/test/Sema/LifetimeSafety/misplaced-lifetimebound-intra-tu.cpp
+++ b/clang/test/Sema/LifetimeSafety/misplaced-lifetimebound-intra-tu.cpp
@@ -167,3 +167,9 @@ struct Derived : Base {
 auto Derived::virtual_get(const MyObj& obj [[clang::lifetimebound]]) const -> 
const MyObj& { // expected-note {{'lifetimebound' attribute appears here on the 
definition}}
   return obj;
 }
+
+struct ViewWithMember {
+  // No warning. A lifetimebound constructor parameter may escape into a field 
of the constructed object.
+  ViewWithMember(const char *data [[clang::lifetimebound]]) : mData(data) {}
+  const char *mData;
+};

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

Reply via email to