[clang] [analyzer] Fix timing of `PostStmt<CXXDeleteExpr>` (PR #215828)
Donát Nagy via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 13 03:48:57 PDT 2026
https://github.com/NagyDonat updated https://github.com/llvm/llvm-project/pull/215828
>From e385599548f0c3545772549d196683be72991a4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.nagy at ericsson.com>
Date: Wed, 12 Aug 2026 17:13:44 +0200
Subject: [PATCH 1/2] [analyzer] Fix timing of `PostStmt<CXXDeleteExpr>`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When `ExprEngine::Visit` visits a statement, it usually first invokes
the `PreStmt` callbacks, then performs the statement-specific visitation
logic, then finally invokes the `PostStmt` callbacks.
Before this commit, `CXXDeleteExpr` did not follow this regular pattern,
because it invoked the `PostStmt` callbacks before the
statement-specific logic. This exceptional logic was introduced in 2020
by commit 9d69072fb80755a0029a01c74892b4bf03f20f65 and I confirmed with
the author of that commit that the unusual order is not intentional --
it is just an accidental mistake.
This commit ensures that `CXXDeleteExpr` also follows the standard order
by swapping the `PostStmt` step and the `VisitCXXDeleteExpr()` call.
As no (upstream) checkers use the `PostStmt<CXXDeleteExpr>` callback,
this is -- in practice -- a non-functional change. (The inconsistency
was spotted by Gábor Tóthvári in the source code.)
---
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 328ed5b23dd83..dd1088d1aaafb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2133,12 +2133,12 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet PreVisit;
const auto *CDE = cast<CXXDeleteExpr>(S);
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
- ExplodedNodeSet PostVisit;
- getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this);
- for (const auto i : PostVisit)
- VisitCXXDeleteExpr(CDE, i, Dst);
+ ExplodedNodeSet PostVisit;
+ for (const auto i : PreVisit)
+ VisitCXXDeleteExpr(CDE, i, PostVisit);
+ getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
break;
}
// FIXME: ChooseExpr is really a constant. We need to fix
>From 3815e244eb1e19c8b680730631c9ceec536290c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.nagy at ericsson.com>
Date: Thu, 13 Aug 2026 12:48:42 +0200
Subject: [PATCH 2/2] Update the test
---
clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp b/clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp
index f28fb4593a407..6a1e81240ae91 100644
--- a/clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp
+++ b/clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp
@@ -38,9 +38,9 @@ void f() {
// CHECK-NEXT: PreStmt<CXXNewExpr>
// CHECK-NEXT: PostStmt<CXXNewExpr>
// CHECK-NEXT: PreStmt<CXXDeleteExpr>
- // CHECK-NEXT: PostStmt<CXXDeleteExpr>
// CHECK-NEXT: PreCall (operator delete) [CXXDeallocatorCall]
// CHECK-NEXT: PostCall (operator delete) [CXXDeallocatorCall]
+ // CHECK-NEXT: PostStmt<CXXDeleteExpr>
p = new int;
operator delete(p, 23542368);
@@ -90,9 +90,9 @@ void f() {
// CHECK-NEXT: PreStmt<CXXNewExpr>
// CHECK-NEXT: PostStmt<CXXNewExpr>
// CHECK-NEXT: PreStmt<CXXDeleteExpr>
- // CHECK-NEXT: PostStmt<CXXDeleteExpr>
// CHECK-NEXT: PreCall (operator delete[]) [CXXDeallocatorCall]
// CHECK-NEXT: PostCall (operator delete[]) [CXXDeallocatorCall]
+ // CHECK-NEXT: PostStmt<CXXDeleteExpr>
p = new int[2];
operator delete[](p, 23542368);
More information about the cfe-commits
mailing list