mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C++: Factor out IRBlock.qll differences
All three `IRBlock.qll` files are now identical again, and they are just a thin object-oriented layer on top of the three `IRBlockConstruction.qll` files, two of which are identical.
This commit is contained in:
@@ -1,78 +1,11 @@
|
||||
private import IRInternal
|
||||
private import IRBlockConstruction
|
||||
import Instruction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.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))
|
||||
}
|
||||
|
||||
private import Cached
|
||||
private cached module Cached {
|
||||
cached newtype TIRBlock =
|
||||
MkIRBlock(Instruction firstInstr) {
|
||||
startsBasicBlock(firstInstr)
|
||||
}
|
||||
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
index = 0 and block = MkIRBlock(result) or
|
||||
(
|
||||
index > 0 and
|
||||
not startsBasicBlock(result) and
|
||||
exists(Instruction predecessor, GotoEdge edge |
|
||||
predecessor = getInstruction(block, index - 1) and
|
||||
result = predecessor.getSuccessor(edge)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
Instruction firstInstr;
|
||||
|
||||
IRBlock() {
|
||||
this = MkIRBlock(firstInstr)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = firstInstr.toString()
|
||||
result = getFirstInstruction(this).toString()
|
||||
}
|
||||
|
||||
final Location getLocation() {
|
||||
@@ -80,7 +13,7 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final string getUniqueId() {
|
||||
result = firstInstr.getUniqueId()
|
||||
result = getFirstInstruction(this).getUniqueId()
|
||||
}
|
||||
|
||||
final Instruction getInstruction(int index) {
|
||||
@@ -88,7 +21,7 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final PhiInstruction getAPhiInstruction() {
|
||||
none()
|
||||
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||
}
|
||||
|
||||
final Instruction getAnInstruction() {
|
||||
@@ -97,7 +30,7 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final Instruction getFirstInstruction() {
|
||||
result = firstInstr
|
||||
result = getFirstInstruction(this)
|
||||
}
|
||||
|
||||
final Instruction getLastInstruction() {
|
||||
@@ -109,11 +42,11 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = firstInstr.getFunctionIR()
|
||||
result = getFirstInstruction(this).getFunctionIR()
|
||||
}
|
||||
|
||||
final Function getFunction() {
|
||||
result = firstInstr.getFunction()
|
||||
result = getFirstInstruction(this).getFunction()
|
||||
}
|
||||
|
||||
final IRBlock getASuccessor() {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
private import IRInternal
|
||||
import Instruction
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.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)
|
||||
}
|
||||
|
||||
cached Instruction getInstruction(TIRBlock block, int index) {
|
||||
index = 0 and block = MkIRBlock(result) or
|
||||
(
|
||||
index > 0 and
|
||||
not startsBasicBlock(result) and
|
||||
exists(Instruction predecessor, GotoEdge edge |
|
||||
predecessor = getInstruction(block, index - 1) and
|
||||
result = predecessor.getSuccessor(edge)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
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,7 +1,6 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
private import InstructionTag
|
||||
private import Opcode
|
||||
private import TempVariableTag
|
||||
private import TranslatedElement
|
||||
private import TranslatedFunction
|
||||
|
||||
@@ -1,36 +1,27 @@
|
||||
private import IRInternal
|
||||
private import Construction::OldIR as OldIR
|
||||
private import IRBlockConstruction
|
||||
import Instruction
|
||||
import semmle.code.cpp.ir.EdgeKind
|
||||
|
||||
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
OldIR::IRBlock oldBlock;
|
||||
|
||||
IRBlock() {
|
||||
this = MkIRBlock(oldBlock)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = oldBlock.toString()
|
||||
result = getFirstInstruction(this).toString()
|
||||
}
|
||||
|
||||
final Location getLocation() {
|
||||
result = oldBlock.getLocation()
|
||||
result = getFirstInstruction().getLocation()
|
||||
}
|
||||
|
||||
|
||||
final string getUniqueId() {
|
||||
result = oldBlock.getUniqueId()
|
||||
result = getFirstInstruction(this).getUniqueId()
|
||||
}
|
||||
|
||||
|
||||
final Instruction getInstruction(int index) {
|
||||
Construction::getOldInstruction(result) = oldBlock.getInstruction(index)
|
||||
result = getInstruction(this, index)
|
||||
}
|
||||
|
||||
final PhiInstruction getAPhiInstruction() {
|
||||
Construction::getPhiInstructionBlockStart(result) =
|
||||
getFirstInstruction()
|
||||
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||
}
|
||||
|
||||
final Instruction getAnInstruction() {
|
||||
@@ -39,47 +30,43 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final Instruction getFirstInstruction() {
|
||||
Construction::getOldInstruction(result) = oldBlock.getFirstInstruction()
|
||||
result = getFirstInstruction(this)
|
||||
}
|
||||
|
||||
final Instruction getLastInstruction() {
|
||||
Construction::getOldInstruction(result) = oldBlock.getLastInstruction()
|
||||
result = getInstruction(getInstructionCount() - 1)
|
||||
}
|
||||
|
||||
final int getInstructionCount() {
|
||||
result = oldBlock.getInstructionCount()
|
||||
result = strictcount(getInstruction(_))
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = getFirstInstruction().getFunctionIR()
|
||||
result = getFirstInstruction(this).getFunctionIR()
|
||||
}
|
||||
|
||||
final Function getFunction() {
|
||||
result = getFirstInstruction().getFunction()
|
||||
result = getFirstInstruction(this).getFunction()
|
||||
}
|
||||
|
||||
final IRBlock getASuccessor() {
|
||||
result = MkIRBlock(oldBlock.getASuccessor())
|
||||
blockSuccessor(this, result)
|
||||
}
|
||||
|
||||
final IRBlock getAPredecessor() {
|
||||
result.getASuccessor() = this
|
||||
blockSuccessor(result, this)
|
||||
}
|
||||
|
||||
final IRBlock getSuccessor(EdgeKind kind) {
|
||||
result = MkIRBlock(oldBlock.getSuccessor(kind))
|
||||
blockSuccessor(this, result, kind)
|
||||
}
|
||||
|
||||
final predicate immediatelyDominates(IRBlock block) {
|
||||
oldBlock.immediatelyDominates(block.getOldBlock())
|
||||
blockImmediatelyDominates(this, block)
|
||||
}
|
||||
|
||||
final predicate strictlyDominates(IRBlock block) {
|
||||
// This is recomputed from scratch rather than reusing the corresponding
|
||||
// predicate of `getOldBlock` because `getOldBlock.strictlyDominates/1` may
|
||||
// at run time be a compactly stored transitive closure that we don't want
|
||||
// to risk materializing in order to join with `MkIRBlock`.
|
||||
immediatelyDominates+(block)
|
||||
blockImmediatelyDominates+(this, block)
|
||||
}
|
||||
|
||||
final predicate dominates(IRBlock block) {
|
||||
@@ -91,8 +78,4 @@ class IRBlock extends TIRBlock {
|
||||
dominates(result.getAPredecessor()) and
|
||||
not strictlyDominates(result)
|
||||
}
|
||||
|
||||
private OldIR::IRBlock getOldBlock() {
|
||||
result = oldBlock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
private import IRInternal
|
||||
private import Construction::OldIR as OldIR
|
||||
import Instruction
|
||||
|
||||
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,36 +1,27 @@
|
||||
private import IRInternal
|
||||
private import Construction::OldIR as OldIR
|
||||
private import IRBlockConstruction
|
||||
import Instruction
|
||||
import semmle.code.cpp.ir.EdgeKind
|
||||
|
||||
cached newtype TIRBlock = MkIRBlock(OldIR::IRBlock oldBlock)
|
||||
|
||||
class IRBlock extends TIRBlock {
|
||||
OldIR::IRBlock oldBlock;
|
||||
|
||||
IRBlock() {
|
||||
this = MkIRBlock(oldBlock)
|
||||
}
|
||||
|
||||
final string toString() {
|
||||
result = oldBlock.toString()
|
||||
result = getFirstInstruction(this).toString()
|
||||
}
|
||||
|
||||
final Location getLocation() {
|
||||
result = oldBlock.getLocation()
|
||||
result = getFirstInstruction().getLocation()
|
||||
}
|
||||
|
||||
|
||||
final string getUniqueId() {
|
||||
result = oldBlock.getUniqueId()
|
||||
result = getFirstInstruction(this).getUniqueId()
|
||||
}
|
||||
|
||||
|
||||
final Instruction getInstruction(int index) {
|
||||
Construction::getOldInstruction(result) = oldBlock.getInstruction(index)
|
||||
result = getInstruction(this, index)
|
||||
}
|
||||
|
||||
final PhiInstruction getAPhiInstruction() {
|
||||
Construction::getPhiInstructionBlockStart(result) =
|
||||
getFirstInstruction()
|
||||
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
|
||||
}
|
||||
|
||||
final Instruction getAnInstruction() {
|
||||
@@ -39,47 +30,43 @@ class IRBlock extends TIRBlock {
|
||||
}
|
||||
|
||||
final Instruction getFirstInstruction() {
|
||||
Construction::getOldInstruction(result) = oldBlock.getFirstInstruction()
|
||||
result = getFirstInstruction(this)
|
||||
}
|
||||
|
||||
final Instruction getLastInstruction() {
|
||||
Construction::getOldInstruction(result) = oldBlock.getLastInstruction()
|
||||
result = getInstruction(getInstructionCount() - 1)
|
||||
}
|
||||
|
||||
final int getInstructionCount() {
|
||||
result = oldBlock.getInstructionCount()
|
||||
result = strictcount(getInstruction(_))
|
||||
}
|
||||
|
||||
final FunctionIR getFunctionIR() {
|
||||
result = getFirstInstruction().getFunctionIR()
|
||||
result = getFirstInstruction(this).getFunctionIR()
|
||||
}
|
||||
|
||||
final Function getFunction() {
|
||||
result = getFirstInstruction().getFunction()
|
||||
result = getFirstInstruction(this).getFunction()
|
||||
}
|
||||
|
||||
final IRBlock getASuccessor() {
|
||||
result = MkIRBlock(oldBlock.getASuccessor())
|
||||
blockSuccessor(this, result)
|
||||
}
|
||||
|
||||
final IRBlock getAPredecessor() {
|
||||
result.getASuccessor() = this
|
||||
blockSuccessor(result, this)
|
||||
}
|
||||
|
||||
final IRBlock getSuccessor(EdgeKind kind) {
|
||||
result = MkIRBlock(oldBlock.getSuccessor(kind))
|
||||
blockSuccessor(this, result, kind)
|
||||
}
|
||||
|
||||
final predicate immediatelyDominates(IRBlock block) {
|
||||
oldBlock.immediatelyDominates(block.getOldBlock())
|
||||
blockImmediatelyDominates(this, block)
|
||||
}
|
||||
|
||||
final predicate strictlyDominates(IRBlock block) {
|
||||
// This is recomputed from scratch rather than reusing the corresponding
|
||||
// predicate of `getOldBlock` because `getOldBlock.strictlyDominates/1` may
|
||||
// at run time be a compactly stored transitive closure that we don't want
|
||||
// to risk materializing in order to join with `MkIRBlock`.
|
||||
immediatelyDominates+(block)
|
||||
blockImmediatelyDominates+(this, block)
|
||||
}
|
||||
|
||||
final predicate dominates(IRBlock block) {
|
||||
@@ -91,8 +78,4 @@ class IRBlock extends TIRBlock {
|
||||
dominates(result.getAPredecessor()) and
|
||||
not strictlyDominates(result)
|
||||
}
|
||||
|
||||
private OldIR::IRBlock getOldBlock() {
|
||||
result = oldBlock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
private import IRInternal
|
||||
private import Construction::OldIR as OldIR
|
||||
import Instruction
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user