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
