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

Reply via email to