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@-1 {{Returning value bound to 's' that will go out of scope}} + // expected-warning@-2 {{Address of stack memory associated with local variable 's' returned}} + // expected-warning@-3 {{address of stack memory associated with local variable 's' returned}} +} + +int *danglingParam(S param) { + return param.get(); + // expected-warning@-1 {{Returning value bound to 'param' that will go out of scope}} + // expected-warning@-2 {{Address of stack memory associated with local variable 'param' returned}} + // expected-warning@-3 {{address of stack memory associated with parameter 'param' returned}} +} + _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
