[clang] [LifetimeSafety] Allow user-defined structs to have origins (PR #189240)

via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 29 06:15:53 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-analysis

Author: NeKon69

<details>
<summary>Changes</summary>

This PR allows user-defined types (structs, classes) to have origins

Fixes #<!-- -->180517

<details>
<summary>Feature Implementation details</summary>

Types declared in namespace std are excluded because the analysis is not intended to track origins through their internal layout. Allowing that would cause incorrect behavior in later analysis stages, for example with interactions between 
`std::string` and `std::string_view`.

Unions needed a separate guard because enabling origins for them caused the analysis to treat the union as origin-carrying without tracking which member is active. In my testing, this broke single-element union initialization ([example](https://github.com/llvm/llvm-project/blob/2e6e36b1734fa6fd3b45405a63efcbeea2a3d795/clang/test/Sema/warn-lifetime-safety.cpp#L1639-L1647)).
</details>

---
Full diff: https://github.com/llvm/llvm-project/pull/189240.diff


2 Files Affected:

- (modified) clang/lib/Analysis/LifetimeSafety/Origins.cpp (+8-3) 
- (modified) clang/test/Sema/warn-lifetime-safety-suggestions.cpp (+28) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/189240


More information about the cfe-commits mailing list