https://github.com/benedekaibas updated https://github.com/llvm/llvm-project/pull/228045
>From b65cfba070d96275efb405a26fa46596f2063b90 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Thu, 1 Oct 2026 13:29:01 +0200 Subject: [PATCH 1/6] [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 a73593baaa184e..11f65a295a5afe 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 00000000000000..9fba6b7f845307 --- /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}} +} >From 001e917e56d16b09898e4ab8928fa565aa6c6768 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Fri, 9 Oct 2026 22:55:12 +0200 Subject: [PATCH 2/6] Remove dump used for debugging. --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 11f65a295a5afe..510a3951bb5e12 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -348,7 +348,6 @@ const Stmt *ExplodedNode::getNextStmtForDiagnostics() const { 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", >From 14091be69090bbace9446e28cd1ba218de44f85a Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Fri, 9 Oct 2026 23:38:30 +0200 Subject: [PATCH 3/6] Do not assign getLocation.getAs to variable. --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 510a3951bb5e12..ef1311709cf9fe 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -347,7 +347,7 @@ 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>()) + if (N->getLocation().getAs<LifetimeEnd>()) continue; if (const Stmt *S = N->getStmtForDiagnostics()) { // Check if the statement is '?' or '&&'/'||'. These are "merges", >From aecd0a6b76e989c9015d0606eb2f00f455484a76 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Fri, 9 Oct 2026 23:44:59 +0200 Subject: [PATCH 4/6] Break RUN line and updated expected-note with correct line number. --- clang/test/Analysis/lifetime-end-path-notes.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/test/Analysis/lifetime-end-path-notes.cpp b/clang/test/Analysis/lifetime-end-path-notes.cpp index 9fba6b7f845307..aa30eb0f477548 100644 --- a/clang/test/Analysis/lifetime-end-path-notes.cpp +++ b/clang/test/Analysis/lifetime-end-path-notes.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection,alpha.core.DanglingPtrDeref -analyzer-config cfg-lifetime=true -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection,alpha.core.DanglingPtrDeref\ +// RUN: -analyzer-config cfg-lifetime=true -analyzer-output=text -verify %s void clang_analyzer_warnIfReached(); @@ -10,7 +11,7 @@ void testPathNotesWithLoopScopeEnd() { 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}} + // expected-note@-3 {{Loop condition is false. Execution continues on line 18}} p = &i; // expected-note {{Value assigned to 'p'}} } // expected-note@-1 {{'i' is destroyed here}} @@ -25,7 +26,7 @@ void testPathNotesWithBlockScopeEnd() { 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}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 35}} p = &n; // expected-note {{Value assigned to 'p'}} ++n; // expected-note {{The value 2 is assigned to 'n'}} } @@ -41,7 +42,7 @@ 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}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 49}} ++i; } } >From 2103055c81111006c46877ceae9d071893be3767 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Fri, 9 Oct 2026 23:48:31 +0200 Subject: [PATCH 5/6] Move expected-note to the enclosing brace. --- clang/test/Analysis/lifetime-end-path-notes.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/test/Analysis/lifetime-end-path-notes.cpp b/clang/test/Analysis/lifetime-end-path-notes.cpp index aa30eb0f477548..76e2b6ae91deb3 100644 --- a/clang/test/Analysis/lifetime-end-path-notes.cpp +++ b/clang/test/Analysis/lifetime-end-path-notes.cpp @@ -11,10 +11,9 @@ void testPathNotesWithLoopScopeEnd() { 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 18}} + // 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}} + } // expected-note {{'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}} @@ -26,12 +25,11 @@ void testPathNotesWithBlockScopeEnd() { 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 35}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 33}} 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}} + } // expected-note {{'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}} @@ -42,7 +40,7 @@ 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 49}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 47}} ++i; } } >From dc45a4e6c1646bad84490996407f8b0a96212605 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Fri, 9 Oct 2026 23:57:53 +0200 Subject: [PATCH 6/6] Fix indentaiton. --- clang/test/Analysis/lifetime-end-path-notes.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/Analysis/lifetime-end-path-notes.cpp b/clang/test/Analysis/lifetime-end-path-notes.cpp index 76e2b6ae91deb3..ca374ce7997558 100644 --- a/clang/test/Analysis/lifetime-end-path-notes.cpp +++ b/clang/test/Analysis/lifetime-end-path-notes.cpp @@ -24,8 +24,8 @@ void testPathNotesWithBlockScopeEnd() { { 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 33}} + // expected-note@-1 3 {{Loop condition is true. Entering loop body}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 33}} p = &n; // expected-note {{Value assigned to 'p'}} ++n; // expected-note {{The value 2 is assigned to 'n'}} } @@ -39,8 +39,8 @@ 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 47}} + // expected-note@-1 3 {{Loop condition is true. Entering loop body}} + // expected-note@-2 {{Loop condition is false. Execution continues on line 47}} ++i; } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
