From 924a8eac5cb82daf8b4e5891d8e2a2e20c597f22 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 2 Sep 2025 14:50:40 +0200 Subject: [PATCH] Java: Improve precision of SuccessorType labels in CFG. --- .../lib/semmle/code/java/ControlFlowGraph.qll | 23 +++++++++++++++++++ .../code/java/controlflow/BasicBlocks.qll | 14 +---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index d98395b49e5..a31101888da 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -82,6 +82,7 @@ module; */ import java +private import codeql.controlflow.SuccessorType private import codeql.util.Boolean private import Completion private import controlflow.internal.Preconditions @@ -124,6 +125,28 @@ module ControlFlow { result = succ(this, NormalCompletion()) } + /** Gets an immediate successor of this node of a given type, if any. */ + Node getASuccessor(SuccessorType t) { + result = branchSuccessor(this, t.(BooleanSuccessor).getValue()) + or + exists(Completion completion | + result = succ(this, completion) and + not result = branchSuccessor(this, _) + | + completion = NormalCompletion() and t instanceof DirectSuccessor + or + completion = ReturnCompletion() and t instanceof ReturnSuccessor + or + completion = BreakCompletion(_) and t instanceof BreakSuccessor + or + completion = YieldCompletion(_) and t instanceof BreakSuccessor + or + completion = ContinueCompletion(_) and t instanceof ContinueSuccessor + or + completion = ThrowCompletion(_) and t instanceof ExceptionSuccessor + ) + } + /** Gets the basic block that contains this node. */ BasicBlock getBasicBlock() { result.getANode() = this } diff --git a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll index b08c59d4630..f214cbbd0b1 100644 --- a/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll +++ b/java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll @@ -22,20 +22,8 @@ private module Input implements BB::InputSig { /** Gets the CFG scope in which this node occurs. */ CfgScope nodeGetCfgScope(Node node) { node.getEnclosingCallable() = result } - private Node getASpecificSuccessor(Node node, SuccessorType t) { - node.(ConditionNode).getABranchSuccessor(t.(BooleanSuccessor).getValue()) = result - or - node.getAnExceptionSuccessor() = result and t instanceof ExceptionSuccessor - } - /** Gets an immediate successor of this node. */ - Node nodeGetASuccessor(Node node, SuccessorType t) { - result = getASpecificSuccessor(node, t) - or - node.getASuccessor() = result and - t instanceof DirectSuccessor and - not result = getASpecificSuccessor(node, _) - } + Node nodeGetASuccessor(Node node, SuccessorType t) { result = node.getASuccessor(t) } /** * Holds if `node` represents an entry node to be used when calculating