Merge pull request #694 from dave-bartolomeo/dave/BetterUnreached

C++: Remove infeasible edges to reachable blocks
This commit is contained in:
Jonas Jensen
2018-12-21 07:36:51 +00:00
committed by GitHub
20 changed files with 386 additions and 131 deletions

View File

@@ -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

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

@@ -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"
)
}

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

@@ -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()
)
)
}
}

View File

@@ -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()
}
}

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

@@ -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"
)
}

View File

@@ -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()
)
)
}
}

View File

@@ -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()
}
}

View File

@@ -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 |

View File

@@ -58,3 +58,13 @@ int UnreachableIf(bool b) {
}
}
}
int DoWhileFalse() {
int i = 0;
do {
i++;
} while (false);
return i;
}

View File

@@ -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 |

View File

@@ -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)

View File

@@ -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 :

View File

@@ -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

View File

@@ -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 :

View File

@@ -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 |

View File

@@ -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 :