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

My recent commit c76a617524fa62f85c1ff825b5d47885599c6482 cleaned up the logic 
of `ExprEngine::processCFGBlockEntrance`, highlighting the fact that it 
sometimes creates an extra transition that has no relevant purpose. This commit 
removes this extra transition to simplify the code.

This is not an NFC change, because changing the number of exploded nodes can 
theoretically perturb the graph creation and traversal algorithms; but I'm 
confident that there was no logic that concretely looked for these particular 
nodes.

Also note that this commit is a no-op if loop unrolling is disabled (the 
default) and unless loop widening is also enabled, it can only remove a node 
that is directly followed by a sink as its only child.

----

I will evaluate the effects of this PR by analyzing our set of open source 
projects with loop unrolling and loop widening both enabled.

From 3f9a2ab47fa28d1f6657b5cebe5fa9fc3523d086 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Thu, 13 Aug 2026 12:56:19 +0200
Subject: [PATCH] [analyzer] Remove irrelevant transitions in
 processCFGBlockEntrance

My recent commit c76a617524fa62f85c1ff825b5d47885599c6482 cleaned up the
logic of `ExprEngine::processCFGBlockEntrance`, highlighting the fact
that it sometimes creates an extra transition that has no relevant
purpose. This commit removes this extra transition to simplify the code.

This is not an NFC change, because changing the number of exploded nodes
can theoretically perturb the graph creation and traversal algorithms;
but I'm confident that there was no logic that concretely looked for
these particular nodes.

Also note that this commit is a no-op if loop unrolling is disabled (the
default) and unless loop widening is also enabled, it can only remove a
node that is directly followed by a sink as its only child.
---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 328ed5b23dd83..f9a1fdd233bd9 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2415,14 +2415,6 @@ ExplodedNode *ExprEngine::processCFGBlockEntrance(const 
BlockEntrance &BE,
     if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
       return Engine.makeNode(BE, State, Pred);
 
-    if (State != Pred->getState()) {
-      // TODO: This intermediate transition is very likely to be irrelevant,
-      // remove it in a follow-up change.
-      Pred = Engine.makeNode(BE, State, Pred);
-      if (!Pred)
-        return nullptr;
-    }
-
     // FIXME:
     // We cannot use the CFG element from the via 
`ExprEngine::getCFGElementRef`
     // since we are currently at the block entrance and the current reference
@@ -2439,15 +2431,6 @@ ExplodedNode *ExprEngine::processCFGBlockEntrance(const 
BlockEntrance &BE,
     return Engine.makeNode(BE, State, Pred);
 
   // ... otherwise, discard this execution path.
-
-  if (State != Pred->getState()) {
-    // TODO: This intermediate transition is very likely to be irrelevant,
-    // remove it in a follow-up change.
-    Pred = Engine.makeNode(BE, State, Pred);
-    if (!Pred)
-      return nullptr;
-  }
-
   static SimpleProgramPointTag Tag(TagProviderName, "Block count exceeded");
   const ExplodedNode *Sink =
       Engine.makeNode(BE.withTag(&Tag), State, Pred, /*MarkAsSink=*/true);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to