[clang] [analyzer] Fix fragile logic in VisitCXXNewExpr (PR #213678)

DonĂ¡t Nagy via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 3 06:54:11 PDT 2026


https://github.com/NagyDonat created https://github.com/llvm/llvm-project/pull/213678

This part of the engine code had assumed that an `evalBind` call always produced exactly one transition. This was probably always satisfied by the existing `eval::Bind` checkers (because the code is old and I don't know about any bugs caused by this), but it was still fragile and problematic to rely on this undocumented property of checkers.

This commit introduces a `for` loop to ensure that all nodes produced by `evalBind` are handled in an identical manner (the same way as the single node was handled previously).

(Note that not passing a `State` to `makeNodeWithBinding` is equivalent to passing the state of the predecessor node.)

We noticed this problem during the review of the NFC commit 53ee7b167d8aee0a75c1332ca4a6aa037e0869a0 and decided to put this (arguably non-NFC) change into a separate PR.

>From 35d531a103e88d63965aeea9871b628a87c98ce3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.nagy at ericsson.com>
Date: Mon, 3 Aug 2026 15:31:07 +0200
Subject: [PATCH] [analyzer] Fix fragile logic in VisitCXXNewExpr

This part of the engine code had assumed that an `evalBind` call always
produced exactly one transition. This was probably always satisfied by
the existing `eval::Bind` checkers (because the code is old and I don't
know about any bugs caused by this), but it was still fragile and
problematic to rely on this undocumented property of checkers.

This commit introduces a `for` loop to ensure that all nodes produced by
`evalBind` are handled in an identical manner (the same way as the
single node was handled previously).

(Note that not passing a `State` to `makeNodeWithBinding` is equivalent
to passing the state of the predecessor node.)

We noticed this problem during the review of the NFC commit
53ee7b167d8aee0a75c1332ca4a6aa037e0869a0 and decided to put this
(arguably non-NFC) change into a separate PR.
---
 clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index c9ef6df71abc5..3df2d3d9e3674 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -1018,12 +1018,12 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
         Pred = Engine.makePostStmtNode(CNE, State, Pred);
 
         SVal V = State->getSVal(Init, SF);
-        ExplodedNodeSet evaluated;
-        evalBind(evaluated, CNE, Pred, Result, V, true);
+        ExplodedNodeSet Evaluated;
+        evalBind(Evaluated, CNE, Pred, Result, V, true);
 
-        assert(evaluated.size() == 1);
-        Pred = *evaluated.begin();
-        State = Pred->getState();
+        for (ExplodedNode *N : Evaluated)
+          Dst.insert(Engine.makeNodeWithBinding(N, CNE, Result));
+        return;
       }
     }
 



More information about the cfe-commits mailing list