diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached