[clang] [LifetimeSafety] Allow user-defined structs to have origins (PR #189240)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 29 06:46:02 PDT 2026
https://github.com/NeKon69 updated https://github.com/llvm/llvm-project/pull/189240
>From 1b89d96110ded0e6809ad0212af1d90ede0664c3 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Sun, 29 Mar 2026 15:59:07 +0300
Subject: [PATCH 1/2] [LifetimeSafety] Allow user-defined structs to have
origins
---
clang/lib/Analysis/LifetimeSafety/Origins.cpp | 11 ++++++--
.../Sema/warn-lifetime-safety-suggestions.cpp | 28 +++++++++++++++++++
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
index 0122f7a734541..ea37d2135f0d2 100644
--- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
@@ -56,10 +56,15 @@ bool hasOrigins(QualType QT) {
const auto *RD = QT->getAsCXXRecordDecl();
if (!RD)
return false;
- // TODO: Limit to lambdas for now. This will be extended to user-defined
- // structs with pointer-like fields.
- if (!RD->isLambda())
+ // Do not track record origins for types declared in namespace std.
+ if (RD->isInStdNamespace())
return false;
+ // Skip unions for now. We cannot tell which union member is active, so we do
+ // not know which field's origins the union should use.
+ // TODO: Add union support once record origins can represent active members.
+ if (RD->isUnion())
+ return false;
+
for (const auto *FD : RD->fields())
if (hasOrigins(FD->getType()))
return true;
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index 22c4222022ebf..787819cca407c 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -439,3 +439,31 @@ struct MemberArrayReturn {
};
} // namespace array
+
+namespace GH180517 {
+// https://github.com/llvm/llvm-project/issues/180517
+
+struct A {
+ int *ptr;
+};
+
+A foo(int *ptr) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+ return {ptr}; // expected-note {{param returned here}}
+}
+
+A bar(int *ptr [[clang::lifetimebound]]) { return {ptr}; }
+A baz(int *ptr) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+ return bar(ptr); // expected-note {{param returned here}}
+}
+
+struct C {
+ struct {
+ int *ptr;
+ } b;
+};
+
+C quux(int *ptr) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+ return {{ptr}}; // expected-note {{param returned here}}
+}
+
+} // namespace GH180517
>From f382365ac9181fa9cf721aee4f87243761a33d1f Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Sun, 29 Mar 2026 16:45:43 +0300
Subject: [PATCH 2/2] update test for record pointee origin
---
clang/unittests/Analysis/LifetimeSafetyTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Analysis/LifetimeSafetyTest.cpp b/clang/unittests/Analysis/LifetimeSafetyTest.cpp
index 6cf65dd64ef83..48565522402eb 100644
--- a/clang/unittests/Analysis/LifetimeSafetyTest.cpp
+++ b/clang/unittests/Analysis/LifetimeSafetyTest.cpp
@@ -1408,7 +1408,7 @@ TEST_F(LifetimeAnalysisTest, TrivialClassDestructorsUAF) {
}
)");
EXPECT_THAT(Origin("ptr"), HasLoansTo({"s"}, "p1"));
- EXPECT_THAT(Origins({"ptr"}), MustBeLiveAt("p1"));
+ EXPECT_THAT(Origins({"ptr", "s"}), MustBeLiveAt("p1"));
}
TEST_F(LifetimeAnalysisTest, SimpleReturnStackAddress) {
More information about the cfe-commits
mailing list