https://github.com/benedekaibas created https://github.com/llvm/llvm-project/pull/228045
None >From b65cfba070d96275efb405a26fa46596f2063b90 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Thu, 1 Oct 2026 13:29:01 +0200 Subject: [PATCH] [analyzer] Skip LifetimeEnd nodes in getNextStmtForDiagnostics --- .../lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 3 ++ .../test/Analysis/lifetime-end-path-notes.cpp | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 clang/test/Analysis/lifetime-end-path-notes.cpp diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index a73593baaa184..11f65a295a5af 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -347,6 +347,9 @@ const Stmt *ExplodedNode::getNextStmtForDiagnostics() const { for (const ExplodedNode *N = getFirstSucc(); N; N = N->getFirstSucc()) { if (N->getLocation().isPurgeKind()) continue; + if (ProgramPoint P = N->getLocation(); P.getAs<LifetimeEnd>()) + // P.dump(); + continue; if (const Stmt *S = N->getStmtForDiagnostics()) { // Check if the statement is '?' or '&&'/'||'. These are "merges", // not actual statement points. diff --git a/clang/test/Analysis/lifetime-end-path-notes.cpp b/clang/test/Analysis/lifetime-end-path-notes.cpp new file mode 100644 index 0000000000000..9fba6b7f84530 --- /dev/null +++ b/clang/test/Analysis/lifetime-end-path-notes.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection,alpha.core.DanglingPtrDeref -analyzer-config cfg-lifetime=true -analyzer-output=text -verify %s + +void clang_analyzer_warnIfReached(); + +// Enabling CFG lifetime-end elements should not cause regression in the +// path notes. The loop exit path note must point to the next executed +// statmeent and not back to the loop. +void testPathNotesWithLoopScopeEnd() { + int *p = nullptr; + for (int i = 0; i < 3; ++i) { + // expected-note@-1 3 {{Loop condition is true. Entering loop body}} + // expected-note@-2 {{The value 2 is assigned to 'i'}} + // expected-note@-3 {{Loop condition is false. Execution continues on line 17}} + p = &i; // expected-note {{Value assigned to 'p'}} + } + // expected-note@-1 {{'i' is destroyed here}} + *p = 4; + // expected-warning@-1 {{Use of 'i' after its lifetime ended}} + // expected-note@-2 {{Use of 'i' after its lifetime ended}} +} + +void testPathNotesWithBlockScopeEnd() { + int *p = nullptr; + { + int n = 0; + while (n < 3) { + // expected-note@-1 3 {{Loop condition is true. Entering loop body}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 34}} + p = &n; // expected-note {{Value assigned to 'p'}} + ++n; // expected-note {{The value 2 is assigned to 'n'}} + } + } + // expected-note@-1 {{'n' is destroyed here}} + *p = 4; + // expected-warning@-1 {{Use of 'n' after its lifetime ended}} + // expected-note@-2 {{Use of 'n' after its lifetime ended}} +} + +void testPathNotesWithWarnIfReached() { + { + int i = 0; + while (i < 3) { + // expected-note@-1 3 {{Loop condition is true. Entering loop body}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 48}} + ++i; + } + } + clang_analyzer_warnIfReached(); + // expected-warning@-1 {{REACHABLE}} + // expected-note@-2 {{REACHABLE}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
