mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C++: recompute IRBlock membership at each stage
This enables the addition of new instructions in later phases of IR construction; in particular, aliasing write instructions and inference instructions.
This commit is contained in:
committed by
Dave Bartolomeo
parent
7aef8fa945
commit
f9ed39915f
@@ -47,10 +47,6 @@
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SimpleSSA.qll"
|
||||
],
|
||||
"C++ SSA IRBlockConstruction": [
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockConstruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockConstruction.qll"
|
||||
],
|
||||
"C++ SSA SSAConstruction": [
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
private import internal.IRInternal
|
||||
import Instruction
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind
|
||||
private import Construction::BlockConstruction
|
||||
import Cached
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
final string toString() {
|
||||
@@ -98,3 +98,82 @@ class IRBlock extends TIRBlock {
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
private predicate startsBasicBlock(Instruction instr) {
|
||||
not instr instanceof PhiInstruction and
|
||||
(
|
||||
count(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor()
|
||||
) != 1 or // Multiple predecessors or no predecessor
|
||||
exists(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor() and
|
||||
strictcount(Instruction other |
|
||||
other = predecessor.getASuccessor()
|
||||
) > 1
|
||||
) or // Predecessor has multiple successors
|
||||
exists(Instruction predecessor, EdgeKind kind |
|
||||
instr = predecessor.getSuccessor(kind) and
|
||||
not kind instanceof GotoEdge
|
||||
) // Incoming edge is not a GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isEntryBlock(TIRBlock block) {
|
||||
block = MkIRBlock(any(EnterFunctionInstruction enter))
|
||||
}
|
||||
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock =
|
||||
MkIRBlock(Instruction firstInstr) {
|
||||
startsBasicBlock(firstInstr)
|
||||
}
|
||||
|
||||
/** Holds if `i2` follows `i1` in a `IRBlock`. */
|
||||
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
|
||||
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
|
||||
not startsBasicBlock(i2)
|
||||
}
|
||||
|
||||
/** 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
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `i` is the `index`th instruction in `block`. */
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
exists(Instruction first |
|
||||
block = MkIRBlock(first) and
|
||||
index = getMemberIndex(result) and
|
||||
adjacentInBlock*(first, result)
|
||||
)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = strictcount(getInstruction(block, _))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
exists(Instruction predLast, Instruction succFirst |
|
||||
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
|
||||
succFirst = predLast.getSuccessor(kind) and
|
||||
succ = MkIRBlock(succFirst)
|
||||
)
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
|
||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
||||
}
|
||||
|
||||
Instruction getFirstInstruction(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import SSAConstructionInternal
|
||||
private import SSAConstruction as Construction
|
||||
private import NewIR
|
||||
|
||||
import Cached
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||
|
||||
private OldIR::IRBlock getOldBlock(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
Construction::getOldInstruction(result) =
|
||||
getOldBlock(block).getInstruction(index)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = getOldBlock(block).getInstructionCount()
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
succ = MkIRBlock(getOldBlock(pred).getSuccessor(kind))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) {
|
||||
getOldBlock(dominator).immediatelyDominates(getOldBlock(block))
|
||||
}
|
||||
|
||||
cached Instruction getFirstInstruction(TIRBlock block) {
|
||||
Construction::getOldInstruction(result) =
|
||||
getOldBlock(block).getFirstInstruction()
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import cpp
|
||||
private import semmle.code.cpp.ir.implementation.Opcode
|
||||
private import semmle.code.cpp.ir.internal.OperandTag
|
||||
private import NewIR
|
||||
import IRBlockConstruction as BlockConstruction
|
||||
|
||||
import Cached
|
||||
cached private module Cached {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
private import internal.IRInternal
|
||||
import Instruction
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind
|
||||
private import Construction::BlockConstruction
|
||||
import Cached
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
final string toString() {
|
||||
@@ -98,3 +98,82 @@ class IRBlock extends TIRBlock {
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
private predicate startsBasicBlock(Instruction instr) {
|
||||
not instr instanceof PhiInstruction and
|
||||
(
|
||||
count(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor()
|
||||
) != 1 or // Multiple predecessors or no predecessor
|
||||
exists(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor() and
|
||||
strictcount(Instruction other |
|
||||
other = predecessor.getASuccessor()
|
||||
) > 1
|
||||
) or // Predecessor has multiple successors
|
||||
exists(Instruction predecessor, EdgeKind kind |
|
||||
instr = predecessor.getSuccessor(kind) and
|
||||
not kind instanceof GotoEdge
|
||||
) // Incoming edge is not a GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isEntryBlock(TIRBlock block) {
|
||||
block = MkIRBlock(any(EnterFunctionInstruction enter))
|
||||
}
|
||||
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock =
|
||||
MkIRBlock(Instruction firstInstr) {
|
||||
startsBasicBlock(firstInstr)
|
||||
}
|
||||
|
||||
/** Holds if `i2` follows `i1` in a `IRBlock`. */
|
||||
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
|
||||
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
|
||||
not startsBasicBlock(i2)
|
||||
}
|
||||
|
||||
/** 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
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `i` is the `index`th instruction in `block`. */
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
exists(Instruction first |
|
||||
block = MkIRBlock(first) and
|
||||
index = getMemberIndex(result) and
|
||||
adjacentInBlock*(first, result)
|
||||
)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = strictcount(getInstruction(block, _))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
exists(Instruction predLast, Instruction succFirst |
|
||||
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
|
||||
succFirst = predLast.getSuccessor(kind) and
|
||||
succ = MkIRBlock(succFirst)
|
||||
)
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
|
||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
||||
}
|
||||
|
||||
Instruction getFirstInstruction(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import semmle.code.cpp.ir.implementation.raw.Instruction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind
|
||||
|
||||
private predicate startsBasicBlock(Instruction instr) {
|
||||
not instr instanceof PhiInstruction and
|
||||
(
|
||||
count(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor()
|
||||
) != 1 or // Multiple predecessors or no predecessor
|
||||
exists(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor() and
|
||||
strictcount(Instruction other |
|
||||
other = predecessor.getASuccessor()
|
||||
) > 1
|
||||
) or // Predecessor has multiple successors
|
||||
exists(Instruction predecessor, EdgeKind kind |
|
||||
instr = predecessor.getSuccessor(kind) and
|
||||
not kind instanceof GotoEdge
|
||||
) // Incoming edge is not a GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isEntryBlock(TIRBlock block) {
|
||||
block = MkIRBlock(any(EnterFunctionInstruction enter))
|
||||
}
|
||||
|
||||
import Cached
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock =
|
||||
MkIRBlock(Instruction firstInstr) {
|
||||
startsBasicBlock(firstInstr)
|
||||
}
|
||||
|
||||
/** Holds if `i2` follows `i1` in a `IRBlock`. */
|
||||
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
|
||||
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
|
||||
not startsBasicBlock(i2)
|
||||
}
|
||||
|
||||
/** 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
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `i` is the `index`th instruction in `block`. */
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
exists(Instruction first |
|
||||
block = MkIRBlock(first) and
|
||||
index = getMemberIndex(result) and
|
||||
adjacentInBlock*(first, result)
|
||||
)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = strictcount(getInstruction(block, _))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
exists(Instruction predLast, Instruction succFirst |
|
||||
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
|
||||
succFirst = predLast.getSuccessor(kind) and
|
||||
succ = MkIRBlock(succFirst)
|
||||
)
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
|
||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
||||
}
|
||||
|
||||
Instruction getFirstInstruction(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.raw.IR
|
||||
import IRBlockConstruction as BlockConstruction
|
||||
private import semmle.code.cpp.ir.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.TempVariableTag
|
||||
private import InstructionTag
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
private import internal.IRInternal
|
||||
import Instruction
|
||||
import semmle.code.cpp.ir.implementation.EdgeKind
|
||||
private import Construction::BlockConstruction
|
||||
import Cached
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
final string toString() {
|
||||
@@ -98,3 +98,82 @@ class IRBlock extends TIRBlock {
|
||||
getAPredecessor().isReachableFromFunctionEntry()
|
||||
}
|
||||
}
|
||||
|
||||
private predicate startsBasicBlock(Instruction instr) {
|
||||
not instr instanceof PhiInstruction and
|
||||
(
|
||||
count(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor()
|
||||
) != 1 or // Multiple predecessors or no predecessor
|
||||
exists(Instruction predecessor |
|
||||
instr = predecessor.getASuccessor() and
|
||||
strictcount(Instruction other |
|
||||
other = predecessor.getASuccessor()
|
||||
) > 1
|
||||
) or // Predecessor has multiple successors
|
||||
exists(Instruction predecessor, EdgeKind kind |
|
||||
instr = predecessor.getSuccessor(kind) and
|
||||
not kind instanceof GotoEdge
|
||||
) // Incoming edge is not a GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isEntryBlock(TIRBlock block) {
|
||||
block = MkIRBlock(any(EnterFunctionInstruction enter))
|
||||
}
|
||||
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock =
|
||||
MkIRBlock(Instruction firstInstr) {
|
||||
startsBasicBlock(firstInstr)
|
||||
}
|
||||
|
||||
/** Holds if `i2` follows `i1` in a `IRBlock`. */
|
||||
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
|
||||
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
|
||||
not startsBasicBlock(i2)
|
||||
}
|
||||
|
||||
/** 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
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `i` is the `index`th instruction in `block`. */
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
exists(Instruction first |
|
||||
block = MkIRBlock(first) and
|
||||
index = getMemberIndex(result) and
|
||||
adjacentInBlock*(first, result)
|
||||
)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = strictcount(getInstruction(block, _))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
exists(Instruction predLast, Instruction succFirst |
|
||||
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
|
||||
succFirst = predLast.getSuccessor(kind) and
|
||||
succ = MkIRBlock(succFirst)
|
||||
)
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
|
||||
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
|
||||
}
|
||||
|
||||
Instruction getFirstInstruction(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import SSAConstructionInternal
|
||||
private import SSAConstruction as Construction
|
||||
private import NewIR
|
||||
|
||||
import Cached
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||
|
||||
private OldIR::IRBlock getOldBlock(TIRBlock block) {
|
||||
block = MkIRBlock(result)
|
||||
}
|
||||
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
Construction::getOldInstruction(result) =
|
||||
getOldBlock(block).getInstruction(index)
|
||||
}
|
||||
|
||||
cached int getInstructionCount(TIRBlock block) {
|
||||
result = getOldBlock(block).getInstructionCount()
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
|
||||
succ = MkIRBlock(getOldBlock(pred).getSuccessor(kind))
|
||||
}
|
||||
|
||||
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
|
||||
blockSuccessor(pred, succ, _)
|
||||
}
|
||||
|
||||
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) {
|
||||
getOldBlock(dominator).immediatelyDominates(getOldBlock(block))
|
||||
}
|
||||
|
||||
cached Instruction getFirstInstruction(TIRBlock block) {
|
||||
Construction::getOldInstruction(result) =
|
||||
getOldBlock(block).getFirstInstruction()
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
import SSAConstructionInternal
|
||||
import cpp
|
||||
private import semmle.code.cpp.ir.implementation.Opcode
|
||||
private import semmle.code.cpp.ir.internal.OperandTag
|
||||
private import NewIR
|
||||
import IRBlockConstruction as BlockConstruction
|
||||
|
||||
import Cached
|
||||
cached private module Cached {
|
||||
|
||||
Reference in New Issue
Block a user