Author: Donát Nagy Date: 2026-08-14T20:08:54+02:00 New Revision: 08e48243b19ded3f9423913c1e0b274a3472358a
URL: https://github.com/llvm/llvm-project/commit/08e48243b19ded3f9423913c1e0b274a3472358a DIFF: https://github.com/llvm/llvm-project/commit/08e48243b19ded3f9423913c1e0b274a3472358a.diff LOG: [analyzer] Fix timing of `PostStmt<CXXDeleteExpr>` (#215828) 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. 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.) Added: Modified: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp Removed: ################################################################################ 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 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); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
