C++: Don't have ReachableBlock extends IRBlock

This commit is contained in:
Dave Bartolomeo
2018-12-17 13:10:53 -08:00
parent fda8605aae
commit 63a2670fcd
5 changed files with 79 additions and 19 deletions

View File

@@ -3,7 +3,18 @@ import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import Cached
class IRBlock extends TIRBlock {
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
* sequence.
*
* This class does not contain any members that query the predecessor or successor edges of the
* block. This allows different classes that extend `IRBlockBase` to expose different subsets of
* edges (e.g. ignoring unreachable edges).
*
* Most consumers should use the class `IRBlock`.
*/
class IRBlockBase extends TIRBlock {
final string toString() {
result = getFirstInstruction(this).toString()
}
@@ -59,7 +70,14 @@ class IRBlock extends TIRBlock {
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
}
}
/**
* A basic block with additional information about its predecessor and successor edges. Each edge
* corresponds to the control flow between the last instruction of one block and the first
* instruction of another block.
*/
class IRBlock extends IRBlockBase {
final IRBlock getASuccessor() {
blockSuccessor(this, result)
}

View File

@@ -3,7 +3,18 @@ import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import Cached
class IRBlock extends TIRBlock {
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
* sequence.
*
* This class does not contain any members that query the predecessor or successor edges of the
* block. This allows different classes that extend `IRBlockBase` to expose different subsets of
* edges (e.g. ignoring unreachable edges).
*
* Most consumers should use the class `IRBlock`.
*/
class IRBlockBase extends TIRBlock {
final string toString() {
result = getFirstInstruction(this).toString()
}
@@ -59,7 +70,14 @@ class IRBlock extends TIRBlock {
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
}
}
/**
* A basic block with additional information about its predecessor and successor edges. Each edge
* corresponds to the control flow between the last instruction of one block and the first
* instruction of another block.
*/
class IRBlock extends IRBlockBase {
final IRBlock getASuccessor() {
blockSuccessor(this, result)
}

View File

@@ -13,28 +13,28 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
)
}
predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
predicate isInfeasibleEdge(IRBlockBase block, EdgeKind kind) {
isInfeasibleInstructionSuccessor(block.getLastInstruction(), kind)
}
IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
private IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
exists(EdgeKind kind |
result.getSuccessor(kind) = successor and
not isInfeasibleEdge(result, kind)
)
}
predicate isBlockReachable(IRBlock block) {
private predicate isBlockReachable(IRBlock block) {
exists(FunctionIR f |
getAFeasiblePredecessorBlock*(block) = f.getEntryBlock()
)
}
predicate isInstructionReachable(Instruction instr) {
isBlockReachable(instr.getBlock())
}
class ReachableBlock extends IRBlock {
/**
* An IR block that is reachable from the entry block of the function, considering only feasible
* edges.
*/
class ReachableBlock extends IRBlockBase {
ReachableBlock() {
isBlockReachable(this)
}
@@ -48,6 +48,9 @@ class ReachableBlock extends IRBlock {
}
}
/**
* An instruction that is contained in a reachable block.
*/
class ReachableInstruction extends Instruction {
ReachableInstruction() {
this.getBlock() instanceof ReachableBlock

View File

@@ -3,7 +3,18 @@ import Instruction
import semmle.code.cpp.ir.implementation.EdgeKind
private import Cached
class IRBlock extends TIRBlock {
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
* sequence.
*
* This class does not contain any members that query the predecessor or successor edges of the
* block. This allows different classes that extend `IRBlockBase` to expose different subsets of
* edges (e.g. ignoring unreachable edges).
*
* Most consumers should use the class `IRBlock`.
*/
class IRBlockBase extends TIRBlock {
final string toString() {
result = getFirstInstruction(this).toString()
}
@@ -59,7 +70,14 @@ class IRBlock extends TIRBlock {
final Function getFunction() {
result = getFirstInstruction(this).getFunction()
}
}
/**
* A basic block with additional information about its predecessor and successor edges. Each edge
* corresponds to the control flow between the last instruction of one block and the first
* instruction of another block.
*/
class IRBlock extends IRBlockBase {
final IRBlock getASuccessor() {
blockSuccessor(this, result)
}

View File

@@ -13,28 +13,28 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
)
}
predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
predicate isInfeasibleEdge(IRBlockBase block, EdgeKind kind) {
isInfeasibleInstructionSuccessor(block.getLastInstruction(), kind)
}
IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
private IRBlock getAFeasiblePredecessorBlock(IRBlock successor) {
exists(EdgeKind kind |
result.getSuccessor(kind) = successor and
not isInfeasibleEdge(result, kind)
)
}
predicate isBlockReachable(IRBlock block) {
private predicate isBlockReachable(IRBlock block) {
exists(FunctionIR f |
getAFeasiblePredecessorBlock*(block) = f.getEntryBlock()
)
}
predicate isInstructionReachable(Instruction instr) {
isBlockReachable(instr.getBlock())
}
class ReachableBlock extends IRBlock {
/**
* An IR block that is reachable from the entry block of the function, considering only feasible
* edges.
*/
class ReachableBlock extends IRBlockBase {
ReachableBlock() {
isBlockReachable(this)
}
@@ -48,6 +48,9 @@ class ReachableBlock extends IRBlock {
}
}
/**
* An instruction that is contained in a reachable block.
*/
class ReachableInstruction extends Instruction {
ReachableInstruction() {
this.getBlock() instanceof ReachableBlock