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 bb9ee9486afc551075c4fa0c248adef11ae67414 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 | 40 +++++-------------- 2 files changed, 15 insertions(+), 34 deletions(-) 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 index a5e26b5bdadf2..f66f6f8e00153 100644 --- a/clang/test/Sema/LifetimeSafety/lifetimebound.cpp +++ b/clang/test/Sema/LifetimeSafety/lifetimebound.cpp @@ -1,35 +1,17 @@ // 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; - } - +struct View { + View(const char* data [[clang::lifetimebound]]) : mData(data) {} + const char * data() const { + return mData; + } private: - const char* mData; - size_t mSize; + const char* mData; }; 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 + 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}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
