[clang] feabbb0 - [analyzer] Fix false positive when a lifetimebound method is called during destruction (#210801)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 21 02:16:02 PDT 2026
Author: Benedek Kaibas
Date: 2026-07-21T11:15:57+02:00
New Revision: feabbb0f4611a9c26d6ae694232bfca7964e6233
URL: https://github.com/llvm/llvm-project/commit/feabbb0f4611a9c26d6ae694232bfca7964e6233
DIFF: https://github.com/llvm/llvm-project/commit/feabbb0f4611a9c26d6ae694232bfca7964e6233.diff
LOG: [analyzer] Fix false positive when a lifetimebound method is called during destruction (#210801)
When a `lifetimebound` method is called during destruction the checker
emits warnings which leads to false positives. To avoid this a dangling
stack source is not reported if any frame on the current stack belongs
to a destructor.
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/LifetimeModeling.cpp
clang/test/Analysis/lifetime-bound.cpp
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/LifetimeModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/LifetimeModeling.cpp
index 42219edc5cceb..2b6f5dae4243f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LifetimeModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LifetimeModeling.cpp
@@ -43,6 +43,16 @@ static bool isDanglingStackSource(const MemRegion *Source,
Source->getMemorySpaceAs<StackSpaceRegion>(State)) {
const StackFrame *SF = StackSpace->getStackFrame();
const StackFrame *CurrentSF = C.getStackFrame();
+ // If any frame on the current stack belongs to a destructor
+ // the warning should be suppressed. When a lifetimebound method
+ // is called from a destructor then its return value is not expected
+ // to outlive the object being destroyed.
+ for (const StackFrame *DtorSF = CurrentSF; DtorSF;
+ DtorSF = DtorSF->getParent()) {
+ if (isa<CXXDestructorDecl>(DtorSF->getDecl()))
+ return false;
+ }
+
if (SF == CurrentSF || !SF->isParentOf(CurrentSF))
return true;
}
diff --git a/clang/test/Analysis/lifetime-bound.cpp b/clang/test/Analysis/lifetime-bound.cpp
index f8519b76798fd..4920a3c928fb8 100644
--- a/clang/test/Analysis/lifetime-bound.cpp
+++ b/clang/test/Analysis/lifetime-bound.cpp
@@ -217,3 +217,35 @@ int *one_dangling_source_ptr(int *a [[clang::lifetimebound]]) {
return multi_param_test_ptr(a, x_ptr); // expected-warning {{Returning value bound to 'x' that will go out of scope}}
}
+struct S {
+ int x;
+ int* get() [[clang::lifetimebound]] { return &x; }
+ S() = default;
+ S(S&& other) { (void)other.get(); }
+ ~S() { get(); }
+};
+
+S make() { return S(); }
+
+S passThrough(S param) { return param; }
+
+void outer() {
+ auto f = passThrough(make());
+ (void)f; // no-warning
+}
+
+int *danglingLocal() {
+ S s;
+ return s.get();
+ // expected-warning at -1 {{Returning value bound to 's' that will go out of scope}}
+ // expected-warning at -2 {{Address of stack memory associated with local variable 's' returned}}
+ // expected-warning at -3 {{address of stack memory associated with local variable 's' returned}}
+}
+
+int *danglingParam(S param) {
+ return param.get();
+ // expected-warning at -1 {{Returning value bound to 'param' that will go out of scope}}
+ // expected-warning at -2 {{Address of stack memory associated with local variable 'param' returned}}
+ // expected-warning at -3 {{address of stack memory associated with parameter 'param' returned}}
+}
+
More information about the cfe-commits
mailing list