diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/internal/PrimitiveBasicBlocks.qll b/cpp/ql/src/semmle/code/cpp/controlflow/internal/PrimitiveBasicBlocks.qll index aaba64a83fa2..babed5d10e15 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/internal/PrimitiveBasicBlocks.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/internal/PrimitiveBasicBlocks.qll @@ -43,15 +43,28 @@ private cached module Cached { (not successors_extended(_, node) and successors_extended(node, _)) } + /** Holds if `n2` follows `n1` in a `PrimitiveBasicBlock`. */ + private predicate member_step(Node n1, Node n2) { + successors_extended(n1, n2) and + not n2 instanceof PrimitiveBasicBlock + } + + /** Returns the index of `node` in its `PrimitiveBasicBlock`. */ + private int getMemberIndex(Node node) { + primitive_basic_block_entry_node(node) and + result = 0 + or + exists(Node prev | + member_step(prev, node) and + result = getMemberIndex(prev) + 1 + ) + } + /** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */ cached predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) { - (node = bb and pos = 0) - or - (not (node instanceof PrimitiveBasicBlock) and - exists (Node pred - | successors_extended(pred, node) - | primitive_basic_block_member(pred, bb, pos - 1))) + pos = getMemberIndex(node) and + member_step*(bb, node) } /** Gets the number of control-flow nodes in the primitive basic block `bb`. */