mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge pull request #694 from dave-bartolomeo/dave/BetterUnreached
C++: Remove infeasible edges to reachable blocks
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* Holds if `block` consists of an `UnreachedInstruction`.
|
||||
*
|
||||
* We avoiding reporting an unreached block as being controlled by a guard. The unreached block
|
||||
* has the AST for the `Function` itself, which tends to confuse mapping between the AST `BasicBlock`
|
||||
* and the `IRBlock`.
|
||||
*/
|
||||
private predicate isUnreachedBlock(IRBlock block) {
|
||||
block.getFirstInstruction() instanceof UnreachedInstruction
|
||||
}
|
||||
|
||||
/**
|
||||
* A Boolean condition in the AST that guards one or more basic blocks. This includes
|
||||
* operands of logical operators but not switch statements.
|
||||
@@ -215,7 +226,8 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) {
|
||||
exists(IRBlock irb |
|
||||
forex(IRGuardCondition inst | inst = ir | inst.controls(irb, testIsTrue)) and
|
||||
irb.getAnInstruction().getAST().(ControlFlowNode).getBasicBlock() = controlled
|
||||
irb.getAnInstruction().getAST().(ControlFlowNode).getBasicBlock() = controlled and
|
||||
not isUnreachedBlock(irb)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -301,6 +313,7 @@ class IRGuardCondition extends Instruction {
|
||||
* `&&` and `||`. See the detailed explanation on predicate `controls`.
|
||||
*/
|
||||
private predicate controlsBlock(IRBlock controlled, boolean testIsTrue) {
|
||||
not isUnreachedBlock(controlled) and
|
||||
exists(IRBlock thisblock
|
||||
| thisblock.getAnInstruction() = this
|
||||
| exists(IRBlock succ, ConditionalBranchInstruction branch
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -25,15 +25,7 @@ cached private module Cached {
|
||||
not oldInstruction instanceof OldIR::PhiInstruction and
|
||||
hasChiNode(_, oldInstruction)
|
||||
} or
|
||||
UnreachedTag(OldInstruction oldInstruction, EdgeKind kind) {
|
||||
// We need an `Unreached` instruction for the destination of any edge whose predecessor
|
||||
// instruction is reachable, but whose successor block is not. This should occur only for
|
||||
// infeasible edges.
|
||||
exists(OldIR::Instruction succInstruction |
|
||||
succInstruction = oldInstruction.getSuccessor(kind) and
|
||||
not succInstruction instanceof OldInstruction
|
||||
)
|
||||
}
|
||||
UnreachedTag()
|
||||
|
||||
cached class InstructionTagType extends TInstructionTag {
|
||||
cached final string toString() {
|
||||
@@ -133,11 +125,12 @@ cached private module Cached {
|
||||
resultType = vvar.getType() and
|
||||
isGLValue = false
|
||||
) or
|
||||
exists(OldInstruction oldInstruction, EdgeKind kind |
|
||||
oldInstruction.getFunction() = func and
|
||||
tag = UnreachedTag(oldInstruction, kind) and
|
||||
exists(OldInstruction oldInstruction |
|
||||
func = oldInstruction.getFunction() and
|
||||
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _) and
|
||||
tag = UnreachedTag() and
|
||||
opcode instanceof Opcode::Unreached and
|
||||
ast = oldInstruction.getSuccessor(kind).getAST() and
|
||||
ast = func and
|
||||
resultType instanceof VoidType and
|
||||
isGLValue = false
|
||||
)
|
||||
@@ -213,7 +206,7 @@ cached private module Cached {
|
||||
exists(Alias::VirtualVariable vvar, OldBlock phiBlock,
|
||||
OldBlock defBlock, int defRank, int defIndex, OldBlock predBlock |
|
||||
hasPhiNode(vvar, phiBlock) and
|
||||
predBlock = phiBlock.getAPredecessor() and
|
||||
predBlock = phiBlock.getAFeasiblePredecessor() and
|
||||
instr.getTag() = PhiTag(vvar, phiBlock) and
|
||||
newPredecessorBlock = getNewBlock(predBlock) and
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
@@ -266,13 +259,22 @@ cached private module Cached {
|
||||
result = getChiInstruction(getOldInstruction(instruction)) and
|
||||
kind instanceof GotoEdge
|
||||
else (
|
||||
result = getNewInstruction(getOldInstruction(instruction).getSuccessor(kind))
|
||||
or
|
||||
exists(OldInstruction oldInstruction |
|
||||
oldInstruction = getOldInstruction(instruction) and
|
||||
(
|
||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
|
||||
result.getTag() = UnreachedTag() and
|
||||
result.getFunction() = instruction.getFunction()
|
||||
)
|
||||
else (
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
) or
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = getChiInstruction(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
) or
|
||||
result.getTag() = UnreachedTag(getOldInstruction(instruction), kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -380,7 +382,7 @@ cached private module Cached {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate variableLiveOnExitFromBlock(Alias::VirtualVariable vvar, OldBlock block) {
|
||||
variableLiveOnEntryToBlock(vvar, block.getASuccessor())
|
||||
variableLiveOnEntryToBlock(vvar, block.getAFeasibleSuccessor())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,7 +476,7 @@ cached private module Cached {
|
||||
useRank) or
|
||||
(
|
||||
definitionReachesEndOfBlock(vvar, defBlock, defRank,
|
||||
useBlock.getAPredecessor()) and
|
||||
useBlock.getAFeasiblePredecessor()) and
|
||||
not definitionReachesUseWithinBlock(vvar, useBlock, _, useBlock, useRank)
|
||||
)
|
||||
)
|
||||
@@ -518,9 +520,9 @@ cached private module CachedForDebugging {
|
||||
instr.getTag() = PhiTag(vvar, phiBlock) and
|
||||
result = "Phi Block(" + phiBlock.getUniqueId() + "): " + vvar.getUniqueId()
|
||||
) or
|
||||
exists(OldInstruction oldInstr, EdgeKind kind |
|
||||
instr.getTag() = UnreachedTag(oldInstr, kind) and
|
||||
result = "Unreached(" + oldInstr.getUniqueId() + ":" + kind.toString() + ")"
|
||||
(
|
||||
instr.getTag() = UnreachedTag() and
|
||||
result = "Unreached"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
private import DominanceInternal
|
||||
private import ReachableBlockInternal
|
||||
private import Dominance
|
||||
import IR
|
||||
|
||||
private class DominancePropertyProvider extends IRPropertyProvider {
|
||||
override string getBlockProperty(IRBlock block, string key) {
|
||||
exists(IRBlock dominator |
|
||||
blockImmediatelyDominates(dominator, block) and
|
||||
key = "ImmediateDominator" and
|
||||
result = "Block " + dominator.getDisplayIndex().toString()
|
||||
) or
|
||||
(
|
||||
key = "DominanceFrontier" and
|
||||
result = strictconcat(IRBlock frontierBlock |
|
||||
frontierBlock = getDominanceFrontier(block) |
|
||||
frontierBlock.getDisplayIndex().toString(), ", " order by frontierBlock.getDisplayIndex()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,9 @@ private import semmle.code.cpp.ir.internal.IntegerConstant
|
||||
private import IR
|
||||
private import ConstantAnalysis
|
||||
|
||||
predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
|
||||
exists(ConditionalBranchInstruction instr, int conditionValue |
|
||||
instr = block.getLastInstruction() and
|
||||
conditionValue = getValue(getConstantValue(instr.getCondition())) and
|
||||
predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
|
||||
exists(int conditionValue |
|
||||
conditionValue = getValue(getConstantValue(instr.(ConditionalBranchInstruction).getCondition())) and
|
||||
if conditionValue = 0 then
|
||||
kind instanceof TrueEdge
|
||||
else
|
||||
@@ -14,29 +13,44 @@ predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
|
||||
)
|
||||
}
|
||||
|
||||
IRBlock getAFeasiblePredecessor(IRBlock successor) {
|
||||
predicate isInfeasibleEdge(IRBlockBase block, EdgeKind kind) {
|
||||
isInfeasibleInstructionSuccessor(block.getLastInstruction(), kind)
|
||||
}
|
||||
|
||||
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 |
|
||||
getAFeasiblePredecessor*(block) = f.getEntryBlock()
|
||||
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)
|
||||
}
|
||||
|
||||
final ReachableBlock getAFeasiblePredecessor() {
|
||||
result = getAFeasiblePredecessorBlock(this)
|
||||
}
|
||||
|
||||
final ReachableBlock getAFeasibleSuccessor() {
|
||||
this = getAFeasiblePredecessorBlock(result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that is contained in a reachable block.
|
||||
*/
|
||||
class ReachableInstruction extends Instruction {
|
||||
ReachableInstruction() {
|
||||
this.getBlock() instanceof ReachableBlock
|
||||
@@ -51,6 +65,6 @@ module Graph {
|
||||
}
|
||||
|
||||
predicate blockSuccessor(ReachableBlock pred, ReachableBlock succ) {
|
||||
succ = pred.getASuccessor()
|
||||
succ = pred.getAFeasibleSuccessor()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -25,15 +25,7 @@ cached private module Cached {
|
||||
not oldInstruction instanceof OldIR::PhiInstruction and
|
||||
hasChiNode(_, oldInstruction)
|
||||
} or
|
||||
UnreachedTag(OldInstruction oldInstruction, EdgeKind kind) {
|
||||
// We need an `Unreached` instruction for the destination of any edge whose predecessor
|
||||
// instruction is reachable, but whose successor block is not. This should occur only for
|
||||
// infeasible edges.
|
||||
exists(OldIR::Instruction succInstruction |
|
||||
succInstruction = oldInstruction.getSuccessor(kind) and
|
||||
not succInstruction instanceof OldInstruction
|
||||
)
|
||||
}
|
||||
UnreachedTag()
|
||||
|
||||
cached class InstructionTagType extends TInstructionTag {
|
||||
cached final string toString() {
|
||||
@@ -133,11 +125,12 @@ cached private module Cached {
|
||||
resultType = vvar.getType() and
|
||||
isGLValue = false
|
||||
) or
|
||||
exists(OldInstruction oldInstruction, EdgeKind kind |
|
||||
oldInstruction.getFunction() = func and
|
||||
tag = UnreachedTag(oldInstruction, kind) and
|
||||
exists(OldInstruction oldInstruction |
|
||||
func = oldInstruction.getFunction() and
|
||||
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _) and
|
||||
tag = UnreachedTag() and
|
||||
opcode instanceof Opcode::Unreached and
|
||||
ast = oldInstruction.getSuccessor(kind).getAST() and
|
||||
ast = func and
|
||||
resultType instanceof VoidType and
|
||||
isGLValue = false
|
||||
)
|
||||
@@ -213,7 +206,7 @@ cached private module Cached {
|
||||
exists(Alias::VirtualVariable vvar, OldBlock phiBlock,
|
||||
OldBlock defBlock, int defRank, int defIndex, OldBlock predBlock |
|
||||
hasPhiNode(vvar, phiBlock) and
|
||||
predBlock = phiBlock.getAPredecessor() and
|
||||
predBlock = phiBlock.getAFeasiblePredecessor() and
|
||||
instr.getTag() = PhiTag(vvar, phiBlock) and
|
||||
newPredecessorBlock = getNewBlock(predBlock) and
|
||||
hasDefinitionAtRank(vvar, defBlock, defRank, defIndex) and
|
||||
@@ -266,13 +259,22 @@ cached private module Cached {
|
||||
result = getChiInstruction(getOldInstruction(instruction)) and
|
||||
kind instanceof GotoEdge
|
||||
else (
|
||||
result = getNewInstruction(getOldInstruction(instruction).getSuccessor(kind))
|
||||
or
|
||||
exists(OldInstruction oldInstruction |
|
||||
oldInstruction = getOldInstruction(instruction) and
|
||||
(
|
||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) then (
|
||||
result.getTag() = UnreachedTag() and
|
||||
result.getFunction() = instruction.getFunction()
|
||||
)
|
||||
else (
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
) or
|
||||
exists(OldInstruction oldInstruction |
|
||||
instruction = getChiInstruction(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
) or
|
||||
result.getTag() = UnreachedTag(getOldInstruction(instruction), kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -380,7 +382,7 @@ cached private module Cached {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate variableLiveOnExitFromBlock(Alias::VirtualVariable vvar, OldBlock block) {
|
||||
variableLiveOnEntryToBlock(vvar, block.getASuccessor())
|
||||
variableLiveOnEntryToBlock(vvar, block.getAFeasibleSuccessor())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,7 +476,7 @@ cached private module Cached {
|
||||
useRank) or
|
||||
(
|
||||
definitionReachesEndOfBlock(vvar, defBlock, defRank,
|
||||
useBlock.getAPredecessor()) and
|
||||
useBlock.getAFeasiblePredecessor()) and
|
||||
not definitionReachesUseWithinBlock(vvar, useBlock, _, useBlock, useRank)
|
||||
)
|
||||
)
|
||||
@@ -518,9 +520,9 @@ cached private module CachedForDebugging {
|
||||
instr.getTag() = PhiTag(vvar, phiBlock) and
|
||||
result = "Phi Block(" + phiBlock.getUniqueId() + "): " + vvar.getUniqueId()
|
||||
) or
|
||||
exists(OldInstruction oldInstr, EdgeKind kind |
|
||||
instr.getTag() = UnreachedTag(oldInstr, kind) and
|
||||
result = "Unreached(" + oldInstr.getUniqueId() + ":" + kind.toString() + ")"
|
||||
(
|
||||
instr.getTag() = UnreachedTag() and
|
||||
result = "Unreached"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
private import DominanceInternal
|
||||
private import ReachableBlockInternal
|
||||
private import Dominance
|
||||
import IR
|
||||
|
||||
private class DominancePropertyProvider extends IRPropertyProvider {
|
||||
override string getBlockProperty(IRBlock block, string key) {
|
||||
exists(IRBlock dominator |
|
||||
blockImmediatelyDominates(dominator, block) and
|
||||
key = "ImmediateDominator" and
|
||||
result = "Block " + dominator.getDisplayIndex().toString()
|
||||
) or
|
||||
(
|
||||
key = "DominanceFrontier" and
|
||||
result = strictconcat(IRBlock frontierBlock |
|
||||
frontierBlock = getDominanceFrontier(block) |
|
||||
frontierBlock.getDisplayIndex().toString(), ", " order by frontierBlock.getDisplayIndex()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,9 @@ private import semmle.code.cpp.ir.internal.IntegerConstant
|
||||
private import IR
|
||||
private import ConstantAnalysis
|
||||
|
||||
predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
|
||||
exists(ConditionalBranchInstruction instr, int conditionValue |
|
||||
instr = block.getLastInstruction() and
|
||||
conditionValue = getValue(getConstantValue(instr.getCondition())) and
|
||||
predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
|
||||
exists(int conditionValue |
|
||||
conditionValue = getValue(getConstantValue(instr.(ConditionalBranchInstruction).getCondition())) and
|
||||
if conditionValue = 0 then
|
||||
kind instanceof TrueEdge
|
||||
else
|
||||
@@ -14,29 +13,44 @@ predicate isInfeasibleEdge(IRBlock block, EdgeKind kind) {
|
||||
)
|
||||
}
|
||||
|
||||
IRBlock getAFeasiblePredecessor(IRBlock successor) {
|
||||
predicate isInfeasibleEdge(IRBlockBase block, EdgeKind kind) {
|
||||
isInfeasibleInstructionSuccessor(block.getLastInstruction(), kind)
|
||||
}
|
||||
|
||||
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 |
|
||||
getAFeasiblePredecessor*(block) = f.getEntryBlock()
|
||||
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)
|
||||
}
|
||||
|
||||
final ReachableBlock getAFeasiblePredecessor() {
|
||||
result = getAFeasiblePredecessorBlock(this)
|
||||
}
|
||||
|
||||
final ReachableBlock getAFeasibleSuccessor() {
|
||||
this = getAFeasiblePredecessorBlock(result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that is contained in a reachable block.
|
||||
*/
|
||||
class ReachableInstruction extends Instruction {
|
||||
ReachableInstruction() {
|
||||
this.getBlock() instanceof ReachableBlock
|
||||
@@ -51,6 +65,6 @@ module Graph {
|
||||
}
|
||||
|
||||
predicate blockSuccessor(ReachableBlock pred, ReachableBlock succ) {
|
||||
succ = pred.getASuccessor()
|
||||
succ = pred.getAFeasibleSuccessor()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,6 @@ astGuardsControl
|
||||
| test.c:26:11:26:15 | ... > ... | false | 42 | 44 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 45 | 45 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 45 | 47 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 48 | 55 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 51 | 53 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 56 | 58 |
|
||||
| test.c:26:11:26:15 | ... > ... | false | 58 | 58 |
|
||||
@@ -150,7 +149,6 @@ astGuardsControl
|
||||
| test.c:34:16:34:21 | ... < ... | false | 42 | 44 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 45 | 45 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 45 | 47 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 48 | 55 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 51 | 53 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 56 | 58 |
|
||||
| test.c:34:16:34:21 | ... < ... | false | 58 | 58 |
|
||||
@@ -161,14 +159,11 @@ astGuardsControl
|
||||
| test.c:42:16:42:21 | ... < ... | true | 42 | 44 |
|
||||
| test.c:42:16:42:21 | ... < ... | true | 45 | 45 |
|
||||
| test.c:42:16:42:21 | ... < ... | true | 45 | 47 |
|
||||
| test.c:42:16:42:21 | ... < ... | true | 48 | 55 |
|
||||
| test.c:42:16:42:21 | ... < ... | true | 51 | 53 |
|
||||
| test.c:44:12:44:16 | ... > ... | false | 42 | 42 |
|
||||
| test.c:44:12:44:16 | ... > ... | false | 51 | 53 |
|
||||
| test.c:44:12:44:16 | ... > ... | true | 45 | 45 |
|
||||
| test.c:44:12:44:16 | ... > ... | true | 45 | 47 |
|
||||
| test.c:44:12:44:16 | ... > ... | true | 48 | 55 |
|
||||
| test.c:45:16:45:20 | ... > ... | false | 48 | 55 |
|
||||
| test.c:45:16:45:20 | ... > ... | true | 45 | 47 |
|
||||
| test.c:58:9:58:14 | ... == ... | false | 58 | 58 |
|
||||
| test.c:58:9:58:14 | ... == ... | false | 62 | 62 |
|
||||
@@ -200,11 +195,13 @@ astGuardsControl
|
||||
| test.c:109:19:109:23 | ... < ... | false | 113 | 113 |
|
||||
| test.c:126:7:126:7 | 1 | true | 126 | 126 |
|
||||
| test.c:126:7:126:7 | 1 | true | 126 | 128 |
|
||||
| test.c:126:7:126:7 | 1 | true | 131 | 131 |
|
||||
| test.c:126:7:126:7 | 1 | true | 131 | 132 |
|
||||
| test.c:126:7:126:7 | 1 | true | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 126 | 128 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 |
|
||||
| test.c:131:7:131:7 | b | true | 131 | 132 |
|
||||
| test.c:137:7:137:7 | 0 | false | 142 | 136 |
|
||||
| test.c:137:7:137:7 | 0 | true | 137 | 138 |
|
||||
| test.c:146:7:146:8 | ! ... | true | 146 | 147 |
|
||||
| test.c:146:8:146:8 | x | false | 146 | 147 |
|
||||
| test.c:152:10:152:10 | x | true | 151 | 152 |
|
||||
@@ -241,7 +238,6 @@ astGuardsEnsure
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 42 | 44 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 45 | 45 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 45 | 47 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 48 | 55 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 51 | 53 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 56 | 58 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 58 | 58 |
|
||||
@@ -257,7 +253,6 @@ astGuardsEnsure
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 42 | 44 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 45 | 45 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 45 | 47 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 48 | 55 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 51 | 53 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 56 | 58 |
|
||||
| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 58 | 58 |
|
||||
@@ -270,7 +265,6 @@ astGuardsEnsure
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 42 | 44 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 45 | 45 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 45 | 47 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 48 | 55 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 51 | 53 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 56 | 58 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 58 | 58 |
|
||||
@@ -282,7 +276,6 @@ astGuardsEnsure
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 42 | 44 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 45 | 45 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 45 | 47 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 48 | 55 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 51 | 53 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 56 | 58 |
|
||||
| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 58 | 58 |
|
||||
@@ -293,28 +286,22 @@ astGuardsEnsure
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 42 | 44 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 45 | 45 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 45 | 47 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 48 | 55 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 51 | 53 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 42 | 42 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 42 | 44 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 45 | 45 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 45 | 47 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 48 | 55 |
|
||||
| test.c:42:16:42:21 | ... < ... | test.c:42:20:42:21 | 10 | >= | test.c:42:16:42:16 | j | 1 | 51 | 53 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | 42 | 42 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | test.c:44:16:44:16 | 0 | 1 | 51 | 53 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | 45 | 45 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | 45 | 47 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | test.c:44:16:44:16 | 0 | 1 | 48 | 55 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | 45 | 45 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | 45 | 47 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | < | test.c:44:12:44:12 | z | 0 | 48 | 55 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | 42 | 42 |
|
||||
| test.c:44:12:44:16 | ... > ... | test.c:44:16:44:16 | 0 | >= | test.c:44:12:44:12 | z | 0 | 51 | 53 |
|
||||
| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | < | test.c:45:20:45:20 | 0 | 1 | 48 | 55 |
|
||||
| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | test.c:45:20:45:20 | 0 | 1 | 45 | 47 |
|
||||
| test.c:45:16:45:20 | ... > ... | test.c:45:20:45:20 | 0 | < | test.c:45:16:45:16 | y | 0 | 45 | 47 |
|
||||
| test.c:45:16:45:20 | ... > ... | test.c:45:20:45:20 | 0 | >= | test.c:45:16:45:16 | y | 0 | 48 | 55 |
|
||||
| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 58 | 58 |
|
||||
| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 62 | 62 |
|
||||
| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 58 | 58 |
|
||||
@@ -501,7 +488,6 @@ irGuardsControl
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 43 | 43 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 45 | 45 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 46 | 46 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 49 | 49 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 52 | 52 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 56 | 56 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | false | 58 | 58 |
|
||||
@@ -514,7 +500,6 @@ irGuardsControl
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 43 | 43 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 45 | 45 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 46 | 46 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 49 | 49 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 52 | 52 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 56 | 56 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | false | 58 | 58 |
|
||||
@@ -524,13 +509,10 @@ irGuardsControl
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | true | 43 | 43 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | true | 45 | 45 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | true | 46 | 46 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | true | 49 | 49 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | true | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | false | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | true | 45 | 45 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | true | 46 | 46 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | true | 49 | 49 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | false | 49 | 49 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | true | 46 | 46 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | false | 58 | 58 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | false | 62 | 62 |
|
||||
@@ -560,10 +542,12 @@ irGuardsControl
|
||||
| test.c:109:19:109:23 | CompareLT: ... < ... | false | 113 | 113 |
|
||||
| test.c:126:7:126:7 | Constant: 1 | true | 126 | 126 |
|
||||
| test.c:126:7:126:7 | Constant: 1 | true | 127 | 127 |
|
||||
| test.c:126:7:126:7 | Constant: 1 | true | 131 | 131 |
|
||||
| test.c:126:7:126:7 | Constant: 1 | true | 132 | 132 |
|
||||
| test.c:126:7:126:7 | Constant: 1 | true | 134 | 134 |
|
||||
| test.c:126:12:126:26 | Call: call to test3_condition | true | 127 | 127 |
|
||||
| test.c:131:7:131:7 | Load: b | true | 132 | 132 |
|
||||
| test.c:137:7:137:7 | Constant: 0 | false | 142 | 142 |
|
||||
| test.c:137:7:137:7 | Constant: 0 | true | 138 | 138 |
|
||||
| test.c:146:8:146:8 | Load: x | false | 147 | 147 |
|
||||
| test.c:152:10:152:10 | Load: x | true | 152 | 152 |
|
||||
| test.c:152:15:152:15 | Load: y | true | 152 | 152 |
|
||||
@@ -593,7 +577,6 @@ irGuardsEnsure
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 43 | 43 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 45 | 45 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 46 | 46 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 49 | 49 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 52 | 52 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 56 | 56 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:11:26:11 | Load: x | < | test.c:26:15:26:15 | Constant: 0 | 1 | 58 | 58 |
|
||||
@@ -610,7 +593,6 @@ irGuardsEnsure
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 43 | 43 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 45 | 45 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 46 | 46 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 49 | 49 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 52 | 52 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 56 | 56 |
|
||||
| test.c:26:11:26:15 | CompareGT: ... > ... | test.c:26:15:26:15 | Constant: 0 | >= | test.c:26:11:26:11 | Load: x | 0 | 58 | 58 |
|
||||
@@ -623,7 +605,6 @@ irGuardsEnsure
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 43 | 43 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 45 | 45 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 46 | 46 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 49 | 49 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 52 | 52 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 56 | 56 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:16 | Load: j | >= | test.c:34:20:34:21 | Constant: 10 | 0 | 58 | 58 |
|
||||
@@ -635,7 +616,6 @@ irGuardsEnsure
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 43 | 43 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 45 | 45 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 46 | 46 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 49 | 49 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 52 | 52 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 56 | 56 |
|
||||
| test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 58 | 58 |
|
||||
@@ -645,25 +625,19 @@ irGuardsEnsure
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 43 | 43 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 45 | 45 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 46 | 46 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 49 | 49 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 52 | 52 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 43 | 43 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 45 | 45 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 46 | 46 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 49 | 49 |
|
||||
| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | < | test.c:44:16:44:16 | Constant: 0 | 1 | 52 | 52 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 45 | 45 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 46 | 46 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 49 | 49 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 45 | 45 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 46 | 46 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 49 | 49 |
|
||||
| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | >= | test.c:44:12:44:12 | Load: z | 0 | 52 | 52 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | < | test.c:45:20:45:20 | Constant: (long)... | 1 | 49 | 49 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | >= | test.c:45:20:45:20 | Constant: (long)... | 1 | 46 | 46 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:20:45:20 | Constant: (long)... | < | test.c:45:16:45:16 | Load: y | 0 | 46 | 46 |
|
||||
| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:20:45:20 | Constant: (long)... | >= | test.c:45:16:45:16 | Load: y | 0 | 49 | 49 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | test.c:58:14:58:14 | Constant: 0 | 0 | 58 | 58 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | test.c:58:14:58:14 | Constant: 0 | 0 | 62 | 62 |
|
||||
| test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:14:58:14 | Constant: 0 | != | test.c:58:9:58:9 | Load: x | 0 | 58 | 58 |
|
||||
|
||||
@@ -58,3 +58,13 @@ int UnreachableIf(bool b) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DoWhileFalse() {
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
} while (false);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
| constant_func.cpp:25:5:25:25 | IR: ReturnConstantPhiLoop | 7 |
|
||||
| constant_func.cpp:34:5:34:22 | IR: UnreachableViaGoto | 0 |
|
||||
| constant_func.cpp:41:5:41:17 | IR: UnreachableIf | 0 |
|
||||
| constant_func.cpp:62:5:62:16 | IR: DoWhileFalse | 1 |
|
||||
|
||||
@@ -6754,3 +6754,31 @@ ir.cpp:
|
||||
# 1044| Type = int
|
||||
# 1044| Value = 1
|
||||
# 1044| ValueCategory = prvalue
|
||||
# 1049| DoWhileFalse() -> int
|
||||
# 1049| params:
|
||||
# 1049| body: { ... }
|
||||
# 1050| 0: declaration
|
||||
# 1050| 0: definition of i
|
||||
# 1050| Type = int
|
||||
# 1050| init: initializer for i
|
||||
# 1050| expr: 0
|
||||
# 1050| Type = int
|
||||
# 1050| Value = 0
|
||||
# 1050| ValueCategory = prvalue
|
||||
# 1051| 1: do (...) ...
|
||||
# 1053| 0: 0
|
||||
# 1053| Type = bool
|
||||
# 1053| Value = 0
|
||||
# 1053| ValueCategory = prvalue
|
||||
# 1051| 1: { ... }
|
||||
# 1052| 0: ExprStmt
|
||||
# 1052| 0: ... ++
|
||||
# 1052| Type = int
|
||||
# 1052| ValueCategory = prvalue
|
||||
# 1052| 0: i
|
||||
# 1052| Type = int
|
||||
# 1052| ValueCategory = lvalue
|
||||
# 1055| 2: return ...
|
||||
# 1055| 0: i
|
||||
# 1055| Type = int
|
||||
# 1055| ValueCategory = prvalue(load)
|
||||
|
||||
@@ -1214,8 +1214,8 @@ ir.cpp:
|
||||
# 281| v2_0(void) = NoOp :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 283| Block 3
|
||||
# 283| v3_0(void) = Unreached :
|
||||
# 278| Block 3
|
||||
# 278| v3_0(void) = Unreached :
|
||||
|
||||
# 285| For_Update() -> void
|
||||
# 285| Block 0
|
||||
@@ -1260,8 +1260,8 @@ ir.cpp:
|
||||
# 294| v2_0(void) = NoOp :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 296| Block 3
|
||||
# 296| v3_0(void) = Unreached :
|
||||
# 292| Block 3
|
||||
# 292| v3_0(void) = Unreached :
|
||||
|
||||
# 298| For_InitUpdate() -> void
|
||||
# 298| Block 0
|
||||
@@ -1465,7 +1465,7 @@ ir.cpp:
|
||||
# 334| r1_2(int) = Constant[10] :
|
||||
# 334| r1_3(bool) = CompareLT : r1_1, r1_2
|
||||
# 334| v1_4(void) = ConditionalBranch : r1_3
|
||||
#-----| False -> Block 5
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 335| Block 2
|
||||
@@ -1481,11 +1481,8 @@ ir.cpp:
|
||||
# 334| v3_0(void) = NoOp :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 336| Block 4
|
||||
# 336| v4_0(void) = Unreached :
|
||||
|
||||
# 339| Block 5
|
||||
# 339| v5_0(void) = Unreached :
|
||||
# 333| Block 4
|
||||
# 333| v4_0(void) = Unreached :
|
||||
|
||||
# 341| Dereference(int *) -> int
|
||||
# 341| Block 0
|
||||
@@ -3225,8 +3222,8 @@ ir.cpp:
|
||||
# 724| v11_1(void) = ReturnVoid :
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 731| Block 12
|
||||
# 731| v12_0(void) = Unreached :
|
||||
# 724| Block 12
|
||||
# 724| v12_0(void) = Unreached :
|
||||
|
||||
# 745| Base::Base(const Base &) -> void
|
||||
# 745| Block 0
|
||||
@@ -4101,8 +4098,8 @@ ir.cpp:
|
||||
# 904| v1_9(void) = UnmodeledUse : mu*
|
||||
# 904| v1_10(void) = ExitFunction :
|
||||
|
||||
# 906| Block 2
|
||||
# 906| v2_0(void) = Unreached :
|
||||
# 904| Block 2
|
||||
# 904| v2_0(void) = Unreached :
|
||||
|
||||
# 940| OperatorNew() -> void
|
||||
# 940| Block 0
|
||||
@@ -4607,7 +4604,7 @@ ir.cpp:
|
||||
# 1040| r4_3(int) = Load : r4_2, m0_10
|
||||
# 1040| r4_4(bool) = CompareLT : r4_1, r4_3
|
||||
# 1040| v4_5(void) = ConditionalBranch : r4_4
|
||||
#-----| False -> Block 7
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 1041| Block 5
|
||||
@@ -4616,8 +4613,36 @@ ir.cpp:
|
||||
# 1041| m5_2(int) = Store : r5_0, r5_1
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1033| Block 6
|
||||
# 1033| v6_0(void) = Unreached :
|
||||
# 1028| Block 6
|
||||
# 1028| v6_0(void) = Unreached :
|
||||
|
||||
# 1044| Block 7
|
||||
# 1044| v7_0(void) = Unreached :
|
||||
# 1049| DoWhileFalse() -> int
|
||||
# 1049| Block 0
|
||||
# 1049| v0_0(void) = EnterFunction :
|
||||
# 1049| m0_1(unknown) = AliasedDefinition :
|
||||
# 1049| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 1050| r0_3(glval<int>) = VariableAddress[i] :
|
||||
# 1050| r0_4(int) = Constant[0] :
|
||||
# 1050| m0_5(int) = Store : r0_3, r0_4
|
||||
# 1052| r0_6(glval<int>) = VariableAddress[i] :
|
||||
# 1052| r0_7(int) = Load : r0_6, m0_5
|
||||
# 1052| r0_8(int) = Constant[1] :
|
||||
# 1052| r0_9(int) = Add : r0_7, r0_8
|
||||
# 1052| m0_10(int) = Store : r0_6, r0_9
|
||||
# 1053| r0_11(bool) = Constant[0] :
|
||||
# 1053| v0_12(void) = ConditionalBranch : r0_11
|
||||
#-----| False -> Block 1
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 1055| Block 1
|
||||
# 1055| r1_0(glval<int>) = VariableAddress[#return] :
|
||||
# 1055| r1_1(glval<int>) = VariableAddress[i] :
|
||||
# 1055| r1_2(int) = Load : r1_1, m0_10
|
||||
# 1055| m1_3(int) = Store : r1_0, r1_2
|
||||
# 1049| r1_4(glval<int>) = VariableAddress[#return] :
|
||||
# 1049| v1_5(void) = ReturnValue : r1_4, m1_3
|
||||
# 1049| v1_6(void) = UnmodeledUse : mu*
|
||||
# 1049| v1_7(void) = ExitFunction :
|
||||
|
||||
# 1049| Block 2
|
||||
# 1049| v2_0(void) = Unreached :
|
||||
|
||||
@@ -1046,4 +1046,13 @@ int UnreachableIf(bool b) {
|
||||
}
|
||||
}
|
||||
|
||||
int DoWhileFalse() {
|
||||
int i = 0;
|
||||
do {
|
||||
i++;
|
||||
} while (false);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17
|
||||
|
||||
@@ -4513,3 +4513,34 @@ ir.cpp:
|
||||
# 1044| r7_1(int) = Constant[1] :
|
||||
# 1044| mu7_2(int) = Store : r7_0, r7_1
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1049| DoWhileFalse() -> int
|
||||
# 1049| Block 0
|
||||
# 1049| v0_0(void) = EnterFunction :
|
||||
# 1049| mu0_1(unknown) = AliasedDefinition :
|
||||
# 1049| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 1050| r0_3(glval<int>) = VariableAddress[i] :
|
||||
# 1050| r0_4(int) = Constant[0] :
|
||||
# 1050| mu0_5(int) = Store : r0_3, r0_4
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1052| Block 1
|
||||
# 1052| r1_0(glval<int>) = VariableAddress[i] :
|
||||
# 1052| r1_1(int) = Load : r1_0, mu0_2
|
||||
# 1052| r1_2(int) = Constant[1] :
|
||||
# 1052| r1_3(int) = Add : r1_1, r1_2
|
||||
# 1052| mu1_4(int) = Store : r1_0, r1_3
|
||||
# 1053| r1_5(bool) = Constant[0] :
|
||||
# 1053| v1_6(void) = ConditionalBranch : r1_5
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 1055| Block 2
|
||||
# 1055| r2_0(glval<int>) = VariableAddress[#return] :
|
||||
# 1055| r2_1(glval<int>) = VariableAddress[i] :
|
||||
# 1055| r2_2(int) = Load : r2_1, mu0_2
|
||||
# 1055| mu2_3(int) = Store : r2_0, r2_2
|
||||
# 1049| r2_4(glval<int>) = VariableAddress[#return] :
|
||||
# 1049| v2_5(void) = ReturnValue : r2_4, mu0_2
|
||||
# 1049| v2_6(void) = UnmodeledUse : mu*
|
||||
# 1049| v2_7(void) = ExitFunction :
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
| IR: Derived | 1 |
|
||||
| IR: DerivedVB | 1 |
|
||||
| IR: DoStatements | 3 |
|
||||
| IR: DoWhileFalse | 3 |
|
||||
| IR: DynamicCast | 1 |
|
||||
| IR: EarlyReturn | 4 |
|
||||
| IR: EarlyReturnValue | 4 |
|
||||
@@ -43,7 +44,7 @@
|
||||
| IR: For_Break | 6 |
|
||||
| IR: For_Condition | 4 |
|
||||
| IR: For_ConditionUpdate | 4 |
|
||||
| IR: For_Continue_NoUpdate | 6 |
|
||||
| IR: For_Continue_NoUpdate | 5 |
|
||||
| IR: For_Continue_Update | 6 |
|
||||
| IR: For_Empty | 2 |
|
||||
| IR: For_Init | 2 |
|
||||
@@ -93,7 +94,7 @@
|
||||
| IR: TryCatch | 13 |
|
||||
| IR: UninitializedVariables | 1 |
|
||||
| IR: UnionInit | 1 |
|
||||
| IR: UnreachableIf | 8 |
|
||||
| IR: UnreachableIf | 7 |
|
||||
| IR: UnreachableViaGoto | 1 |
|
||||
| IR: VarArgUsage | 1 |
|
||||
| IR: VarArgs | 1 |
|
||||
|
||||
@@ -3991,8 +3991,8 @@ ir.cpp:
|
||||
# 904| v1_9(void) = UnmodeledUse : mu*
|
||||
# 904| v1_10(void) = ExitFunction :
|
||||
|
||||
# 906| Block 2
|
||||
# 906| v2_0(void) = Unreached :
|
||||
# 904| Block 2
|
||||
# 904| v2_0(void) = Unreached :
|
||||
|
||||
# 940| OperatorNew() -> void
|
||||
# 940| Block 0
|
||||
@@ -4486,3 +4486,34 @@ ir.cpp:
|
||||
# 1044| r7_1(int) = Constant[1] :
|
||||
# 1044| m7_2(int) = Store : r7_0, r7_1
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1049| DoWhileFalse() -> int
|
||||
# 1049| Block 0
|
||||
# 1049| v0_0(void) = EnterFunction :
|
||||
# 1049| mu0_1(unknown) = AliasedDefinition :
|
||||
# 1049| mu0_2(unknown) = UnmodeledDefinition :
|
||||
# 1050| r0_3(glval<int>) = VariableAddress[i] :
|
||||
# 1050| r0_4(int) = Constant[0] :
|
||||
# 1050| m0_5(int) = Store : r0_3, r0_4
|
||||
# 1052| r0_6(glval<int>) = VariableAddress[i] :
|
||||
# 1052| r0_7(int) = Load : r0_6, m0_5
|
||||
# 1052| r0_8(int) = Constant[1] :
|
||||
# 1052| r0_9(int) = Add : r0_7, r0_8
|
||||
# 1052| m0_10(int) = Store : r0_6, r0_9
|
||||
# 1053| r0_11(bool) = Constant[0] :
|
||||
# 1053| v0_12(void) = ConditionalBranch : r0_11
|
||||
#-----| False -> Block 1
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 1055| Block 1
|
||||
# 1055| r1_0(glval<int>) = VariableAddress[#return] :
|
||||
# 1055| r1_1(glval<int>) = VariableAddress[i] :
|
||||
# 1055| r1_2(int) = Load : r1_1, m0_10
|
||||
# 1055| m1_3(int) = Store : r1_0, r1_2
|
||||
# 1049| r1_4(glval<int>) = VariableAddress[#return] :
|
||||
# 1049| v1_5(void) = ReturnValue : r1_4, m1_3
|
||||
# 1049| v1_6(void) = UnmodeledUse : mu*
|
||||
# 1049| v1_7(void) = ExitFunction :
|
||||
|
||||
# 1049| Block 2
|
||||
# 1049| v2_0(void) = Unreached :
|
||||
|
||||
Reference in New Issue
Block a user