Author: DonĂ¡t Nagy
Date: 2026-08-17T13:00:25+02:00
New Revision: e67fa5a2797064213c6f4c39844135cb4e6f969d

URL: 
https://github.com/llvm/llvm-project/commit/e67fa5a2797064213c6f4c39844135cb4e6f969d
DIFF: 
https://github.com/llvm/llvm-project/commit/e67fa5a2797064213c6f4c39844135cb4e6f969d.diff

LOG: [analyzer] Remove irrelevant transitions in processCFGBlockEntrance 
(#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.

I'm confident that there was no logic that concretely looked for these
particular nodes; and this commit is a no-op if loop unrolling is
disabled (the default). Unless loop widening is also enabled, it can
only remove a node that is directly followed by a sink as its only
child.

However, this is not a NFC change, because changing the number of
exploded nodes can perturb the graph creation and traversal. I analyzed
a dozen open source projects with loop unrolling and widening both
enabled, and among almost 20.000 bug reports these perturbations caused
one new report and three lost reports, which is negligible (0.02%) and
acceptable.

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index dd1088d1aaafb..41cc820fd547b 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