[llvm-branch-commits] [clang] [LifetimeSafety] Detect dangling field of base class (PR #191831)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Apr 13 08:04:46 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-analysis
Author: Utkarsh Saxena (usx95)
<details>
<summary>Changes</summary>
Fixes: https://github.com/llvm/llvm-project/issues/191823
---
Full diff: https://github.com/llvm/llvm-project/pull/191831.diff
4 Files Affected:
- (modified) clang/lib/Analysis/LifetimeSafety/Origins.cpp (+1-1)
- (modified) clang/test/Sema/warn-lifetime-safety-dangling-field.cpp (+12)
- (modified) clang/test/Sema/warn-lifetime-safety-suggestions.cpp (+15)
- (modified) clang/test/Sema/warn-lifetime-safety.cpp (+15)
``````````diff
diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
index abf9890b08522..fdd2671dee2e0 100644
--- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp
@@ -236,7 +236,7 @@ OriginList *OriginManager::getOrCreateList(const Expr *E) {
ReferencedDecl = DRE->getDecl();
else if (auto *ME = dyn_cast<MemberExpr>(E))
if (auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
- Field && isa<CXXThisExpr>(ME->getBase()))
+ Field && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
ReferencedDecl = Field;
if (ReferencedDecl) {
OriginList *Head = nullptr;
diff --git a/clang/test/Sema/warn-lifetime-safety-dangling-field.cpp b/clang/test/Sema/warn-lifetime-safety-dangling-field.cpp
index fa45458371012..79b0183ed91ec 100644
--- a/clang/test/Sema/warn-lifetime-safety-dangling-field.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-dangling-field.cpp
@@ -184,3 +184,15 @@ struct IndirectEscape2 {
p = s.data();
}
};
+
+namespace DanglingPointerFieldInBaseClass {
+struct BaseWithPointer {
+ std::string_view view; // expected-note {{this field dangles}}
+};
+
+struct DerivedWithCtor : BaseWithPointer {
+ DerivedWithCtor(std::string s) {
+ view = s; // expected-warning {{address of stack memory escapes to a field}}
+ }
+};
+} // namespace DanglingPointerFieldInBaseClass
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index c96b92cfe0b5b..b3b13038dc344 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -513,4 +513,19 @@ CaptureRefToRef test_ref_to_ref() {
CaptureRefToRef x(obj); // expected-warning {{address of stack memory is returned later}}
return x; // expected-note {{returned here}}
}
+
+struct BaseWithView {
+ View v; // expected-note {{escapes to this field}}
+};
+struct CaptureRefToBaseView : BaseWithView {
+ CaptureRefToBaseView(const MyObj& obj) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+ v = obj;
+ }
+};
+
+CaptureRefToBaseView test_ref_to_base_view() {
+ MyObj obj;
+ CaptureRefToBaseView x(obj); // expected-warning {{address of stack memory is returned later}}
+ return x; // expected-note {{returned here}}
+}
} // namespace capturing_constructor
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index b1dea7f7340b3..9c8df51833a0a 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -2531,3 +2531,18 @@ int *noreturn_dead_nested(bool cond, bool cond2, int *num) {
}
} // namespace conditional_operator_control_flow
+
+namespace base_class_fields {
+struct X { int* x; }; // expected-note {{this field dangles}}
+struct Y : X {
+ int* y;
+ void bar() {
+ {
+ int a;
+ x = &a; // expected-warning {{address of stack memory escapes to a field}}
+ }
+ (void)x;
+ }
+};
+} // namespace base_class_fields
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/191831
More information about the llvm-branch-commits
mailing list