diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll new file mode 100644 index 000000000000..55d5d4d8a84c --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll @@ -0,0 +1,485 @@ +import cpp +import semmle.code.cpp.ir.IR + +/** + * A Boolean condition in the AST that guards one or more basic blocks. This includes + * operands of logical operators but not switch statements. + */ +class GuardCondition extends Expr { + GuardCondition() { + exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression()) + or + // no binary operators in the IR + exists(GuardCondition gc | + this.(BinaryLogicalOperation).getAnOperand()= gc + ) + or + // the IR short-circuits if(!x) + ( + // don't produce a guard condition for `y = !x` and other non-short-circuited cases + not exists (Instruction inst | this.getFullyConverted() = inst.getAST()) and + exists(IRGuardCondition ir | this.(NotExpr).getOperand() = ir.getAST()) + ) + } + /** + * Holds if this condition controls `block`, meaning that `block` is only + * entered if the value of this condition is `testIsTrue`. + * + * Illustration: + * + * ``` + * [ (testIsTrue) ] + * [ this ----------------succ ---- controlled ] + * [ | | ] + * [ (testIsFalse) | ------ ... ] + * [ other ] + * ``` + * + * The predicate holds if all paths to `controlled` go via the `testIsTrue` + * edge of the control-flow graph. In other words, the `testIsTrue` edge + * must dominate `controlled`. This means that `controlled` must be + * dominated by both `this` and `succ` (the target of the `testIsTrue` + * edge). It also means that any other edge into `succ` must be a back-edge + * from a node which is dominated by `succ`. + * + * The short-circuit boolean operations have slightly surprising behavior + * here: because the operation itself only dominates one branch (due to + * being short-circuited) then it will only control blocks dominated by the + * true (for `&&`) or false (for `||`) branch. + */ + cached predicate controls(BasicBlock controlled, boolean testIsTrue) { + none() + } + + /** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */ + cached predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + none() + } + + /** Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`. + If `isLessThan = false` then this implies `left >= right + k`. */ + cached predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + none() + } + + /** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */ + cached predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + none() + } + + /** Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`. + If `areEqual = false` then this implies `left != right + k`. */ + cached predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { + none() + } +} + +/** + * A binary logical operator in the AST that guards one or more basic blocks. + */ +private class GuardConditionFromBinaryLogicalOperator extends GuardCondition { + GuardConditionFromBinaryLogicalOperator() { + exists(GuardCondition gc | + this.(BinaryLogicalOperation).getAnOperand()= gc + ) + } + + override predicate controls(BasicBlock controlled, boolean testIsTrue) { + exists (BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs + | this = binop and + lhs = binop.getLeftOperand() and + rhs = binop.getRightOperand() and + lhs.controls(controlled, testIsTrue) and + rhs.controls(controlled, testIsTrue)) + } + + override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + exists(boolean partIsTrue, GuardCondition part | + this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) | + part.comparesLt(left, right, k, isLessThan, partIsTrue) + ) + } + + override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + exists(boolean testIsTrue | + comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue) + ) + } + + override predicate comparesEq(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + exists(boolean partIsTrue, GuardCondition part | + this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) | + part.comparesEq(left, right, k, isLessThan, partIsTrue) + ) + } + + override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + exists(boolean testIsTrue | + comparesEq(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue) + ) + } +} + +/** + * A `!` operator in the AST that guards one or more basic blocks, and does not have a corresponding + * IR instruction. + */ +private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr { + GuardConditionFromShortCircuitNot() { + not exists (Instruction inst | this.getFullyConverted() = inst.getAST()) and + exists(IRGuardCondition ir | getOperand() = ir.getAST()) + } + + override predicate controls(BasicBlock controlled, boolean testIsTrue) { + getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot()) + } + + override predicate comparesLt(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + getOperand().(GuardCondition).comparesLt(left, right, k, areEqual, testIsTrue.booleanNot()) + } + + override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean testIsTrue) { + getOperand().(GuardCondition).ensuresLt(left, right, k, block, testIsTrue.booleanNot()) + } + + override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot()) + } + + override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean testIsTrue) { + getOperand().(GuardCondition).ensuresEq(left, right, k, block, testIsTrue.booleanNot()) + } +} +/** + * A Boolean condition in the AST that guards one or more basic blocks and has a corresponding IR + * instruction. + */ +private class GuardConditionFromIR extends GuardCondition { + IRGuardCondition ir; + + GuardConditionFromIR() { + this = ir.getUnconvertedResultExpression() + } + override predicate controls(BasicBlock controlled, boolean testIsTrue) { + /* This condition must determine the flow of control; that is, this + * node must be a top-level condition. */ + this.controlsBlock(controlled, testIsTrue) + } + + /** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */ + override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + exists(Instruction li, Instruction ri | + li.getUnconvertedResultExpression() = left and + ri.getUnconvertedResultExpression() = right and + ir.comparesLt(li, ri, k, isLessThan, testIsTrue) + ) + } + + /** Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`. + If `isLessThan = false` then this implies `left >= right + k`. */ + override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + exists(Instruction li, Instruction ri, boolean testIsTrue | + li.getUnconvertedResultExpression() = left and + ri.getUnconvertedResultExpression() = right and + ir.comparesLt(li, ri, k, isLessThan, testIsTrue) and + this.controls(block, testIsTrue) + ) + } + + /** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */ + override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + exists(Instruction li, Instruction ri | + li.getUnconvertedResultExpression() = left and + ri.getUnconvertedResultExpression() = right and + ir.comparesEq(li, ri, k, areEqual, testIsTrue) + ) + } + + /** Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`. + If `areEqual = false` then this implies `left != right + k`. */ + override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { + exists(Instruction li, Instruction ri, boolean testIsTrue | + li.getUnconvertedResultExpression() = left and + ri.getUnconvertedResultExpression() = right and + ir.comparesEq(li, ri, k, areEqual, testIsTrue) + and this.controls(block, testIsTrue) + ) + } + + /** + * Holds if this condition controls `block`, meaning that `block` is only + * entered if the value of this condition is `testIsTrue`. This helper + * predicate does not necessarily hold for binary logical operations like + * `&&` and `||`. See the detailed explanation on predicate `controls`. + */ + 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 + ) + } +} + +/** + * A Boolean condition in the IR that guards one or more basic blocks. This includes + * operands of logical operators but not switch statements. Note that `&&` and `||` + * don't have an explicit representation in the IR, and therefore will not appear as + * IRGuardConditions. + */ +class IRGuardCondition extends Instruction { + + IRGuardCondition() { + is_condition(this) + } + + /** + * Holds if this condition controls `block`, meaning that `block` is only + * entered if the value of this condition is `testIsTrue`. + * + * Illustration: + * + * ``` + * [ (testIsTrue) ] + * [ this ----------------succ ---- controlled ] + * [ | | ] + * [ (testIsFalse) | ------ ... ] + * [ other ] + * ``` + * + * The predicate holds if all paths to `controlled` go via the `testIsTrue` + * edge of the control-flow graph. In other words, the `testIsTrue` edge + * must dominate `controlled`. This means that `controlled` must be + * dominated by both `this` and `succ` (the target of the `testIsTrue` + * edge). It also means that any other edge into `succ` must be a back-edge + * from a node which is dominated by `succ`. + * + * The short-circuit boolean operations have slightly surprising behavior + * here: because the operation itself only dominates one branch (due to + * being short-circuited) then it will only control blocks dominated by the + * true (for `&&`) or false (for `||`) branch. + */ + cached predicate controls(IRBlock controlled, boolean testIsTrue) { + /* This condition must determine the flow of control; that is, this + * node must be a top-level condition. */ + this.controlsBlock(controlled, testIsTrue) + or + exists (IRGuardCondition ne + | this = ne.(LogicalNotInstruction).getOperand() and + ne.controls(controlled, testIsTrue.booleanNot())) + } + + /** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */ + cached predicate comparesLt(Instruction left, Instruction right, int k, boolean isLessThan, boolean testIsTrue) { + compares_lt(this, left, right, k, isLessThan, testIsTrue) + } + + /** Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`. + If `isLessThan = false` then this implies `left >= right + k`. */ + cached predicate ensuresLt(Instruction left, Instruction right, int k, IRBlock block, boolean isLessThan) { + exists(boolean testIsTrue | + compares_lt(this, left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue) + ) + } + + /** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */ + cached predicate comparesEq(Instruction left, Instruction right, int k, boolean areEqual, boolean testIsTrue) { + compares_eq(this, left, right, k, areEqual, testIsTrue) + } + + /** Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`. + If `areEqual = false` then this implies `left != right + k`. */ + cached predicate ensuresEq(Instruction left, Instruction right, int k, IRBlock block, boolean areEqual) { + exists(boolean testIsTrue | + compares_eq(this, left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue) + ) + } + + /** + * Holds if this condition controls `block`, meaning that `block` is only + * entered if the value of this condition is `testIsTrue`. This helper + * predicate does not necessarily hold for binary logical operations like + * `&&` and `||`. See the detailed explanation on predicate `controls`. + */ + private predicate controlsBlock(IRBlock controlled, boolean testIsTrue) { + exists(IRBlock thisblock + | thisblock.getAnInstruction() = this + | exists(IRBlock succ, ConditionalBranchInstruction branch + | testIsTrue = true and succ.getFirstInstruction() = branch.getTrueSuccessor() + or + testIsTrue = false and succ.getFirstInstruction() = branch.getFalseSuccessor() + | branch.getCondition() = this and + succ.dominates(controlled) and + forall(IRBlock pred + | pred.getASuccessor() = succ + | pred = thisblock or succ.dominates(pred) or not pred.isReachableFromFunctionEntry()))) + } +} + +private predicate is_condition(Instruction guard) { + exists(ConditionalBranchInstruction branch| + branch.getCondition() = guard + ) + or + exists(LogicalNotInstruction cond | is_condition(cond) and cond.getOperand() = guard) +} + +/** + * Holds if `left == right + k` is `areEqual` given that test is `testIsTrue`. + * + * Beware making mistaken logical implications here relating `areEqual` and `testIsTrue`. + */ +private predicate compares_eq(Instruction test, Instruction left, Instruction right, int k, boolean areEqual, boolean testIsTrue) { + /* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */ + exists(boolean eq | simple_comparison_eq(test, left, right, k, eq) | + areEqual = true and testIsTrue = eq or areEqual = false and testIsTrue = eq.booleanNot() + ) + // I think this is handled by forwarding in controlsBlock. + /* or + logical_comparison_eq(test, left, right, k, areEqual, testIsTrue) */ + or + /* a == b + k => b == a - k */ + exists(int mk | k = -mk | compares_eq(test, right, left, mk, areEqual, testIsTrue)) + or + complex_eq(test, left, right, k, areEqual, testIsTrue) + or + /* (x is true => (left == right + k)) => (!x is false => (left == right + k)) */ + exists(boolean isFalse | testIsTrue = isFalse.booleanNot() | + compares_eq(test.(LogicalNotInstruction).getOperand(), left, right, k, areEqual, isFalse) + ) +} + +/** Rearrange various simple comparisons into `left == right + k` form. */ +private predicate simple_comparison_eq(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean areEqual) { + left = cmp.getLeftOperand() and cmp instanceof CompareEQInstruction and right = cmp.getRightOperand() and k = 0 and areEqual = true + or + left = cmp.getLeftOperand() and cmp instanceof CompareNEInstruction and right = cmp.getRightOperand() and k = 0 and areEqual = false +} + +private predicate complex_eq(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean areEqual, boolean testIsTrue) { + sub_eq(cmp, left, right, k, areEqual, testIsTrue) + or + add_eq(cmp, left, right, k, areEqual, testIsTrue) +} + + +/* Simplification of inequality expressions + * Simplify conditions in the source to the canonical form l < r + k. + */ + +/** Holds if `left < right + k` evaluates to `isLt` given that test is `testIsTrue`. */ +private predicate compares_lt(Instruction test, Instruction left, Instruction right, int k, boolean isLt, boolean testIsTrue) { + /* In the simple case, the test is the comparison, so isLt = testIsTrue */ + simple_comparison_lt(test, left, right, k) and isLt = true and testIsTrue = true + or + simple_comparison_lt(test, left, right, k) and isLt = false and testIsTrue = false + or + complex_lt(test, left, right, k, isLt, testIsTrue) + or + /* (not (left < right + k)) => (left >= right + k) */ + exists(boolean isGe | isLt = isGe.booleanNot() | + compares_ge(test, left, right, k, isGe, testIsTrue) + ) + or + /* (x is true => (left < right + k)) => (!x is false => (left < right + k)) */ + exists(boolean isFalse | testIsTrue = isFalse.booleanNot() | + compares_lt(test.(LogicalNotInstruction).getOperand(), left, right, k, isLt, isFalse) + ) +} + +/** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */ +private predicate compares_ge(Instruction test, Instruction left, Instruction right, int k, boolean isGe, boolean testIsTrue) { + exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, testIsTrue)) +} + +/** Rearrange various simple comparisons into `left < right + k` form. */ +private predicate simple_comparison_lt(CompareInstruction cmp, Instruction left, Instruction right, int k) { + left = cmp.getLeftOperand() and cmp instanceof CompareLTInstruction and right = cmp.getRightOperand() and k = 0 + or + left = cmp.getLeftOperand() and cmp instanceof CompareLEInstruction and right = cmp.getRightOperand() and k = 1 + or + right = cmp.getLeftOperand() and cmp instanceof CompareGTInstruction and left = cmp.getRightOperand() and k = 0 + or + right = cmp.getLeftOperand() and cmp instanceof CompareGEInstruction and left = cmp.getRightOperand() and k = 1 +} + +private predicate complex_lt(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean isLt, boolean testIsTrue) { + sub_lt(cmp, left, right, k, isLt, testIsTrue) + or + add_lt(cmp, left, right, k, isLt, testIsTrue) +} + + +/* left - x < right + c => left < right + (c+x) + left < (right - x) + c => left < right + (c-x) */ +private predicate sub_lt(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean isLt, boolean testIsTrue) { + exists(SubInstruction lhs, int c, int x | compares_lt(cmp, lhs, right, c, isLt, testIsTrue) and + left = lhs.getLeftOperand() and x = int_value(lhs.getRightOperand()) + and k = c + x + ) + or + exists(SubInstruction rhs, int c, int x | compares_lt(cmp, left, rhs, c, isLt, testIsTrue) and + right = rhs.getLeftOperand() and x = int_value(rhs.getRightOperand()) + and k = c - x + ) +} + +/* left + x < right + c => left < right + (c-x) + left < (right + x) + c => left < right + (c+x) */ +private predicate add_lt(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean isLt, boolean testIsTrue) { + exists(AddInstruction lhs, int c, int x | compares_lt(cmp, lhs, right, c, isLt, testIsTrue) and + (left = lhs.getLeftOperand() and x = int_value(lhs.getRightOperand()) + or + left = lhs.getRightOperand() and x = int_value(lhs.getLeftOperand()) + ) + and k = c - x + ) + or + exists(AddInstruction rhs, int c, int x | compares_lt(cmp, left, rhs, c, isLt, testIsTrue) and + (right = rhs.getLeftOperand() and x = int_value(rhs.getRightOperand()) + or + right = rhs.getRightOperand() and x = int_value(rhs.getLeftOperand()) + ) + and k = c + x + ) +} + + +/* left - x == right + c => left == right + (c+x) + left == (right - x) + c => left == right + (c-x) */ +private predicate sub_eq(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean areEqual, boolean testIsTrue) { + exists(SubInstruction lhs, int c, int x | compares_eq(cmp, lhs, right, c, areEqual, testIsTrue) and + left = lhs.getLeftOperand() and x = int_value(lhs.getRightOperand()) + and k = c + x + ) + or + exists(SubInstruction rhs, int c, int x | compares_eq(cmp, left, rhs, c, areEqual, testIsTrue) and + right = rhs.getLeftOperand() and x = int_value(rhs.getRightOperand()) + and k = c - x + ) +} + + +/* left + x == right + c => left == right + (c-x) + left == (right + x) + c => left == right + (c+x) */ +private predicate add_eq(CompareInstruction cmp, Instruction left, Instruction right, int k, boolean areEqual, boolean testIsTrue) { + exists(AddInstruction lhs, int c, int x | compares_eq(cmp, lhs, right, c, areEqual, testIsTrue) and + (left = lhs.getLeftOperand() and x = int_value(lhs.getRightOperand()) + or + left = lhs.getRightOperand() and x = int_value(lhs.getLeftOperand()) + ) + and k = c - x + ) + or + exists(AddInstruction rhs, int c, int x | compares_eq(cmp, left, rhs, c, areEqual, testIsTrue) and + (right = rhs.getLeftOperand() and x = int_value(rhs.getRightOperand()) + or + right = rhs.getRightOperand() and x = int_value(rhs.getLeftOperand()) + ) + and k = c + x + ) +} + +/** The int value of integer constant expression. */ +private int int_value(Instruction i) { + result = i.(IntegerConstantInstruction).getValue().toInt() +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll index dd12ea1a8a54..992dde33bcc7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll @@ -76,6 +76,8 @@ abstract class PointerOffsetOpcode extends PointerArithmeticOpcode {} abstract class CompareOpcode extends BinaryOpcode {} +abstract class RelationalOpcode extends CompareOpcode {} + abstract class CopyOpcode extends Opcode {} abstract class MemoryAccessOpcode extends Opcode {} @@ -117,10 +119,10 @@ module Opcode { class LogicalNot extends UnaryOpcode, TLogicalNot { override final string toString() { result = "LogicalNot" } } class CompareEQ extends CompareOpcode, TCompareEQ { override final string toString() { result = "CompareEQ" } } class CompareNE extends CompareOpcode, TCompareNE { override final string toString() { result = "CompareNE" } } - class CompareLT extends CompareOpcode, TCompareLT { override final string toString() { result = "CompareLT" } } - class CompareGT extends CompareOpcode, TCompareGT { override final string toString() { result = "CompareGT" } } - class CompareLE extends CompareOpcode, TCompareLE { override final string toString() { result = "CompareLE" } } - class CompareGE extends CompareOpcode, TCompareGE { override final string toString() { result = "CompareGE" } } + class CompareLT extends RelationalOpcode, TCompareLT { override final string toString() { result = "CompareLT" } } + class CompareGT extends RelationalOpcode, TCompareGT { override final string toString() { result = "CompareGT" } } + class CompareLE extends RelationalOpcode, TCompareLE { override final string toString() { result = "CompareLE" } } + class CompareGE extends RelationalOpcode, TCompareGE { override final string toString() { result = "CompareGE" } } class PointerAdd extends PointerOffsetOpcode, TPointerAdd { override final string toString() { result = "PointerAdd" } } class PointerSub extends PointerOffsetOpcode, TPointerSub { override final string toString() { result = "PointerSub" } } class PointerDiff extends PointerArithmeticOpcode, TPointerDiff { override final string toString() { result = "PointerDiff" } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index c794c6cb288b..c51b05a073bb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock { dominates(result.getAPredecessor()) and not strictlyDominates(result) } + + /** + * Holds if this block is reachable from the entry point of its function + */ + final predicate isReachableFromFunctionEntry() { + this = getFunctionIR().getEntryBlock() or + getAPredecessor().isReachableFromFunctionEntry() + } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index e63fd979def7..bf1837298138 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -310,11 +310,19 @@ class Instruction extends Construction::TInstruction { } /** - * Gets the `Expr` whose results is computed by this instruction, if any. + * Gets the `Expr` whose result is computed by this instruction, if any. */ - final Expr getResultExpression() { - result = Construction::getInstructionResultExpression(this) + final Expr getConvertedResultExpression() { + result = Construction::getInstructionConvertedResultExpression(this) } + + /** + * Gets the unconverted `Expr` whose result is computed by this instruction, if any. + */ + final Expr getUnconvertedResultExpression() { + result = Construction::getInstructionUnconvertedResultExpression(this) + } + /** * Gets the type of the result produced by this instruction. If the @@ -967,28 +975,110 @@ class CompareNEInstruction extends CompareInstruction { } } -class CompareLTInstruction extends CompareInstruction { +/** + * Represents an instruction that does a relative comparison of two values, such as `<` or `>=`. + */ +class RelationalInstruction extends CompareInstruction { + RelationalInstruction() { + opcode instanceof RelationalOpcode + } + /** + * Gets the operand on the "greater" (or "greater-or-equal") side + * of this relational instruction, that is, the side that is larger + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is the `20`, and on `y > 0` it is `y`. + */ + Instruction getGreaterOperand() { + none() + } + + /** + * Gets the operand on the "lesser" (or "lesser-or-equal") side + * of this relational instruction, that is, the side that is smaller + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is `x`, and on `y > 0` it is the `0`. + */ + Instruction getLesserOperand() { + none() + } + /** + * Holds if this relational instruction is strict (is not an "or-equal" instruction). + */ + predicate isStrict() { + none() + } +} + +class CompareLTInstruction extends RelationalInstruction { CompareLTInstruction() { opcode instanceof Opcode::CompareLT } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + any() + } } -class CompareGTInstruction extends CompareInstruction { +class CompareGTInstruction extends RelationalInstruction { CompareGTInstruction() { opcode instanceof Opcode::CompareGT } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + any() + } } -class CompareLEInstruction extends CompareInstruction { +class CompareLEInstruction extends RelationalInstruction { CompareLEInstruction() { opcode instanceof Opcode::CompareLE } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + none() + } } -class CompareGEInstruction extends CompareInstruction { +class CompareGEInstruction extends RelationalInstruction { CompareGEInstruction() { opcode instanceof Opcode::CompareGE } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + none() + } } class SwitchInstruction extends Instruction { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index f6e2034296d9..70af6ce64138 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -197,8 +197,12 @@ cached private module Cached { ) } - cached Expr getInstructionResultExpression(Instruction instruction) { - result = getOldInstruction(instruction).getResultExpression() + cached Expr getInstructionConvertedResultExpression(Instruction instruction) { + result = getOldInstruction(instruction).getConvertedResultExpression() + } + + cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) { + result = getOldInstruction(instruction).getUnconvertedResultExpression() } cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index c794c6cb288b..c51b05a073bb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock { dominates(result.getAPredecessor()) and not strictlyDominates(result) } + + /** + * Holds if this block is reachable from the entry point of its function + */ + final predicate isReachableFromFunctionEntry() { + this = getFunctionIR().getEntryBlock() or + getAPredecessor().isReachableFromFunctionEntry() + } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index e63fd979def7..bf1837298138 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -310,11 +310,19 @@ class Instruction extends Construction::TInstruction { } /** - * Gets the `Expr` whose results is computed by this instruction, if any. + * Gets the `Expr` whose result is computed by this instruction, if any. */ - final Expr getResultExpression() { - result = Construction::getInstructionResultExpression(this) + final Expr getConvertedResultExpression() { + result = Construction::getInstructionConvertedResultExpression(this) } + + /** + * Gets the unconverted `Expr` whose result is computed by this instruction, if any. + */ + final Expr getUnconvertedResultExpression() { + result = Construction::getInstructionUnconvertedResultExpression(this) + } + /** * Gets the type of the result produced by this instruction. If the @@ -967,28 +975,110 @@ class CompareNEInstruction extends CompareInstruction { } } -class CompareLTInstruction extends CompareInstruction { +/** + * Represents an instruction that does a relative comparison of two values, such as `<` or `>=`. + */ +class RelationalInstruction extends CompareInstruction { + RelationalInstruction() { + opcode instanceof RelationalOpcode + } + /** + * Gets the operand on the "greater" (or "greater-or-equal") side + * of this relational instruction, that is, the side that is larger + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is the `20`, and on `y > 0` it is `y`. + */ + Instruction getGreaterOperand() { + none() + } + + /** + * Gets the operand on the "lesser" (or "lesser-or-equal") side + * of this relational instruction, that is, the side that is smaller + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is `x`, and on `y > 0` it is the `0`. + */ + Instruction getLesserOperand() { + none() + } + /** + * Holds if this relational instruction is strict (is not an "or-equal" instruction). + */ + predicate isStrict() { + none() + } +} + +class CompareLTInstruction extends RelationalInstruction { CompareLTInstruction() { opcode instanceof Opcode::CompareLT } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + any() + } } -class CompareGTInstruction extends CompareInstruction { +class CompareGTInstruction extends RelationalInstruction { CompareGTInstruction() { opcode instanceof Opcode::CompareGT } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + any() + } } -class CompareLEInstruction extends CompareInstruction { +class CompareLEInstruction extends RelationalInstruction { CompareLEInstruction() { opcode instanceof Opcode::CompareLE } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + none() + } } -class CompareGEInstruction extends CompareInstruction { +class CompareGEInstruction extends RelationalInstruction { CompareGEInstruction() { opcode instanceof Opcode::CompareGE } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + none() + } } class SwitchInstruction extends Instruction { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index 306180e764ec..d8c14c0f9508 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -74,13 +74,25 @@ cached private module Cached { none() } - cached Expr getInstructionResultExpression(Instruction instruction) { + cached Expr getInstructionConvertedResultExpression(Instruction instruction) { exists(TranslatedExpr translatedExpr | translatedExpr = getTranslatedExpr(result) and instruction = translatedExpr.getResult() ) } + cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) { + exists(Expr converted, TranslatedExpr translatedExpr | + result = converted.(Conversion).getExpr+() + or + result = converted + | + not result instanceof Conversion and + translatedExpr = getTranslatedExpr(converted) and + instruction = translatedExpr.getResult() + ) + } + cached Instruction getInstructionOperand(Instruction instruction, OperandTag tag) { result = getInstructionTranslatedElement(instruction).getInstructionOperand( instruction.getTag(), tag) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index c794c6cb288b..c51b05a073bb 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -89,4 +89,12 @@ class IRBlock extends TIRBlock { dominates(result.getAPredecessor()) and not strictlyDominates(result) } + + /** + * Holds if this block is reachable from the entry point of its function + */ + final predicate isReachableFromFunctionEntry() { + this = getFunctionIR().getEntryBlock() or + getAPredecessor().isReachableFromFunctionEntry() + } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index e63fd979def7..bf1837298138 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -310,11 +310,19 @@ class Instruction extends Construction::TInstruction { } /** - * Gets the `Expr` whose results is computed by this instruction, if any. + * Gets the `Expr` whose result is computed by this instruction, if any. */ - final Expr getResultExpression() { - result = Construction::getInstructionResultExpression(this) + final Expr getConvertedResultExpression() { + result = Construction::getInstructionConvertedResultExpression(this) } + + /** + * Gets the unconverted `Expr` whose result is computed by this instruction, if any. + */ + final Expr getUnconvertedResultExpression() { + result = Construction::getInstructionUnconvertedResultExpression(this) + } + /** * Gets the type of the result produced by this instruction. If the @@ -967,28 +975,110 @@ class CompareNEInstruction extends CompareInstruction { } } -class CompareLTInstruction extends CompareInstruction { +/** + * Represents an instruction that does a relative comparison of two values, such as `<` or `>=`. + */ +class RelationalInstruction extends CompareInstruction { + RelationalInstruction() { + opcode instanceof RelationalOpcode + } + /** + * Gets the operand on the "greater" (or "greater-or-equal") side + * of this relational instruction, that is, the side that is larger + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is the `20`, and on `y > 0` it is `y`. + */ + Instruction getGreaterOperand() { + none() + } + + /** + * Gets the operand on the "lesser" (or "lesser-or-equal") side + * of this relational instruction, that is, the side that is smaller + * if the overall instruction evaluates to `true`; for example on + * `x <= 20` this is `x`, and on `y > 0` it is the `0`. + */ + Instruction getLesserOperand() { + none() + } + /** + * Holds if this relational instruction is strict (is not an "or-equal" instruction). + */ + predicate isStrict() { + none() + } +} + +class CompareLTInstruction extends RelationalInstruction { CompareLTInstruction() { opcode instanceof Opcode::CompareLT } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + any() + } } -class CompareGTInstruction extends CompareInstruction { +class CompareGTInstruction extends RelationalInstruction { CompareGTInstruction() { opcode instanceof Opcode::CompareGT } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + any() + } } -class CompareLEInstruction extends CompareInstruction { +class CompareLEInstruction extends RelationalInstruction { CompareLEInstruction() { opcode instanceof Opcode::CompareLE } + + override Instruction getLesserOperand() { + result = getLeftOperand() + } + + override Instruction getGreaterOperand() { + result = getRightOperand() + } + + override predicate isStrict() { + none() + } } -class CompareGEInstruction extends CompareInstruction { +class CompareGEInstruction extends RelationalInstruction { CompareGEInstruction() { opcode instanceof Opcode::CompareGE } + + override Instruction getLesserOperand() { + result = getRightOperand() + } + + override Instruction getGreaterOperand() { + result = getLeftOperand() + } + + override predicate isStrict() { + none() + } } class SwitchInstruction extends Instruction { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index f6e2034296d9..70af6ce64138 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -197,8 +197,12 @@ cached private module Cached { ) } - cached Expr getInstructionResultExpression(Instruction instruction) { - result = getOldInstruction(instruction).getResultExpression() + cached Expr getInstructionConvertedResultExpression(Instruction instruction) { + result = getOldInstruction(instruction).getConvertedResultExpression() + } + + cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) { + result = getOldInstruction(instruction).getUnconvertedResultExpression() } cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) { diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/test.c b/cpp/ql/test/library-tests/controlflow/guards-ir/test.c new file mode 100644 index 000000000000..384d265440fb --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/test.c @@ -0,0 +1,154 @@ + +int test(int x, int w, int z) { + int j; + long y = 50; + + // simple comparison + if (x > 0) { + y = 20; + z = 10; + } else { + y = 30; + } + + z = x + y; + + // More complex + if(x < 0 && y > 1) + y = 40; + else + y = 20; /* The && expression does not control this block as the x<0 expression jumps here if false. */ + + + z = 10; + + // while loop + while(x > 0) { + y = 10; + x--; + } + + z += y; + + // for loop + for(j = 0; j < 10; j++) { + y = 0; + w = 10; + } + + z += w; + + // nested control flow + for(j = 0; j < 10; j++) { + y = 30; + if(z > 0) + if(y > 0) { + w = 0; + break; + } else { + w = 20; + } + else { + w = 10; + continue; + } + x = 0; + } + + if (x == 0 || y < 0) { + y = 60; + z = 10; + } else + return z; + + z += x; + + return 0; +} + + +int test2(int x, int w, int z) { + int j; + long y = 50; + + // simple comparison + if (x == 0) { + y = 20; + z = 10; + } else { + y = 30; + } + + z = x + y; + + // More complex + if(x == 0 && y != 0) + y = 40; + else + y = 20; + + + z = 10; + + // while loop + while(x != 0) { + y = 10; + x--; + } + + z += y; + + // for loop + for(j = 0; j < 10; j++) { + y = 0; + w = 10; + } + + z += w; + + if (x == 0 || y < 0) { + y = 60; + z = 10; + } else + return z; + + z += x; + + return 0; +} + +int test3_condition(); +void test3_action(); + +void test3() { + int b = 0; + + if (1 && test3_condition()) { + b = 1; + test3_action(); + } + + if (b) { + test3_action(); + } +} + +void test4(int i) { + if (0) { + if (i) { + ; + } + } + return; +} + +void test5(int x) { + if (!x) { + test3(); + } +} + +void test6(int x, int y) { + return x && y; +} + diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/test.cpp b/cpp/ql/test/library-tests/controlflow/guards-ir/test.cpp new file mode 100644 index 000000000000..46d894813f9b --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/test.cpp @@ -0,0 +1,54 @@ +class X +{ +public: + void set(); +}; + +class Y +{ +public: + Y* f(); + + const X* get() const { return 0; } + X* get() { return 0; } +}; + +Y* Y::f() +{ + if ( get() ) + get()->set(); + return 0; +} + +class Error { +public: + Error() {} +}; + +bool getABool(); + +void doSomething(int x) { + if (x == -1) { + throw new Error(); + } +} + +void doSomethingElse(int x); + +bool testWithCatch0(int v) +{ + try + { + if( getABool() ) + { + doSomething(v); + return true; + } + } + catch(Error &e) + { + doSomethingElse(v); + } + + return false; +} diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected new file mode 100644 index 000000000000..07661aaf3206 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -0,0 +1,730 @@ +astGuards +| test.c:7:9:7:13 | ... > ... | +| test.c:17:8:17:12 | ... < ... | +| test.c:17:8:17:21 | ... && ... | +| test.c:17:17:17:21 | ... > ... | +| test.c:26:11:26:15 | ... > ... | +| test.c:34:16:34:21 | ... < ... | +| test.c:42:16:42:21 | ... < ... | +| test.c:44:12:44:16 | ... > ... | +| test.c:45:16:45:20 | ... > ... | +| test.c:58:9:58:14 | ... == ... | +| test.c:58:9:58:23 | ... \|\| ... | +| test.c:58:19:58:23 | ... < ... | +| test.c:75:9:75:14 | ... == ... | +| test.c:85:8:85:13 | ... == ... | +| test.c:85:8:85:23 | ... && ... | +| test.c:85:18:85:23 | ... != ... | +| test.c:94:11:94:16 | ... != ... | +| test.c:102:16:102:21 | ... < ... | +| test.c:109:9:109:14 | ... == ... | +| test.c:109:9:109:23 | ... \|\| ... | +| test.c:109:19:109:23 | ... < ... | +| test.c:126:7:126:7 | 1 | +| test.c:126:7:126:28 | ... && ... | +| test.c:126:12:126:26 | call to test3_condition | +| test.c:131:7:131:7 | b | +| test.c:137:7:137:7 | 0 | +| test.c:138:9:138:9 | i | +| test.c:146:7:146:8 | ! ... | +| test.c:146:8:146:8 | x | +| test.c:152:10:152:10 | x | +| test.c:152:10:152:15 | ... && ... | +| test.c:152:15:152:15 | y | +| test.cpp:18:8:18:10 | call to get | +| test.cpp:31:7:31:13 | ... == ... | +| test.cpp:42:13:42:20 | call to getABool | +astGuardsCompare +| 7 | 0 < x+0 when ... > ... is true | +| 7 | 0 >= x+0 when ... > ... is false | +| 7 | x < 0+1 when ... > ... is false | +| 7 | x >= 0+1 when ... > ... is true | +| 17 | 0 < x+1 when ... < ... is false | +| 17 | 0 >= x+1 when ... && ... is true | +| 17 | 0 >= x+1 when ... < ... is true | +| 17 | 1 < y+0 when ... && ... is true | +| 17 | 1 < y+0 when ... > ... is true | +| 17 | 1 >= y+0 when ... > ... is false | +| 17 | x < 0+0 when ... && ... is true | +| 17 | x < 0+0 when ... < ... is true | +| 17 | x >= 0+0 when ... < ... is false | +| 17 | y < 1+1 when ... > ... is false | +| 17 | y >= 1+1 when ... && ... is true | +| 17 | y >= 1+1 when ... > ... is true | +| 26 | 0 < x+0 when ... > ... is true | +| 26 | 0 >= x+0 when ... > ... is false | +| 26 | x < 0+1 when ... > ... is false | +| 26 | x >= 0+1 when ... > ... is true | +| 31 | - ... != x+0 when ... == ... is false | +| 31 | - ... == x+0 when ... == ... is true | +| 31 | x != - ...+0 when ... == ... is false | +| 31 | x == - ...+0 when ... == ... is true | +| 34 | 10 < j+1 when ... < ... is false | +| 34 | 10 >= j+1 when ... < ... is true | +| 34 | j < 10+0 when ... < ... is true | +| 34 | j >= 10+0 when ... < ... is false | +| 42 | 10 < j+1 when ... < ... is false | +| 42 | 10 >= j+1 when ... < ... is true | +| 42 | j < 10+0 when ... < ... is true | +| 42 | j >= 10+0 when ... < ... is false | +| 44 | 0 < z+0 when ... > ... is true | +| 44 | 0 >= z+0 when ... > ... is false | +| 44 | z < 0+1 when ... > ... is false | +| 44 | z >= 0+1 when ... > ... is true | +| 45 | 0 < y+0 when ... > ... is true | +| 45 | 0 >= y+0 when ... > ... is false | +| 45 | y < 0+1 when ... > ... is false | +| 45 | y >= 0+1 when ... > ... is true | +| 58 | 0 != x+0 when ... == ... is false | +| 58 | 0 != x+0 when ... \|\| ... is false | +| 58 | 0 < y+1 when ... < ... is false | +| 58 | 0 < y+1 when ... \|\| ... is false | +| 58 | 0 == x+0 when ... == ... is true | +| 58 | 0 >= y+1 when ... < ... is true | +| 58 | x != 0+0 when ... == ... is false | +| 58 | x != 0+0 when ... \|\| ... is false | +| 58 | x == 0+0 when ... == ... is true | +| 58 | y < 0+0 when ... < ... is true | +| 58 | y >= 0+0 when ... < ... is false | +| 58 | y >= 0+0 when ... \|\| ... is false | +| 75 | 0 != x+0 when ... == ... is false | +| 75 | 0 == x+0 when ... == ... is true | +| 75 | x != 0+0 when ... == ... is false | +| 75 | x == 0+0 when ... == ... is true | +| 85 | 0 != x+0 when ... == ... is false | +| 85 | 0 != y+0 when ... != ... is true | +| 85 | 0 != y+0 when ... && ... is true | +| 85 | 0 == x+0 when ... && ... is true | +| 85 | 0 == x+0 when ... == ... is true | +| 85 | 0 == y+0 when ... != ... is false | +| 85 | x != 0+0 when ... == ... is false | +| 85 | x == 0+0 when ... && ... is true | +| 85 | x == 0+0 when ... == ... is true | +| 85 | y != 0+0 when ... != ... is true | +| 85 | y != 0+0 when ... && ... is true | +| 85 | y == 0+0 when ... != ... is false | +| 94 | 0 != x+0 when ... != ... is true | +| 94 | 0 == x+0 when ... != ... is false | +| 94 | x != 0+0 when ... != ... is true | +| 94 | x == 0+0 when ... != ... is false | +| 102 | 10 < j+1 when ... < ... is false | +| 102 | 10 >= j+1 when ... < ... is true | +| 102 | j < 10+0 when ... < ... is true | +| 102 | j >= 10+0 when ... < ... is false | +| 109 | 0 != x+0 when ... == ... is false | +| 109 | 0 != x+0 when ... \|\| ... is false | +| 109 | 0 < y+1 when ... < ... is false | +| 109 | 0 < y+1 when ... \|\| ... is false | +| 109 | 0 == x+0 when ... == ... is true | +| 109 | 0 >= y+1 when ... < ... is true | +| 109 | x != 0+0 when ... == ... is false | +| 109 | x != 0+0 when ... \|\| ... is false | +| 109 | x == 0+0 when ... == ... is true | +| 109 | y < 0+0 when ... < ... is true | +| 109 | y >= 0+0 when ... < ... is false | +| 109 | y >= 0+0 when ... \|\| ... is false | +astGuardsControl +| test.c:7:9:7:13 | ... > ... | false | 10 | 11 | +| test.c:7:9:7:13 | ... > ... | true | 7 | 9 | +| test.c:17:8:17:12 | ... < ... | true | 17 | 17 | +| test.c:17:8:17:12 | ... < ... | true | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | true | 18 | 18 | +| test.c:17:17:17:21 | ... > ... | true | 18 | 18 | +| test.c:26:11:26:15 | ... > ... | false | 2 | 2 | +| test.c:26:11:26:15 | ... > ... | false | 31 | 34 | +| test.c:26:11:26:15 | ... > ... | false | 34 | 34 | +| test.c:26:11:26:15 | ... > ... | false | 39 | 42 | +| test.c:26:11:26:15 | ... > ... | false | 42 | 42 | +| 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 | +| test.c:26:11:26:15 | ... > ... | false | 58 | 66 | +| test.c:26:11:26:15 | ... > ... | false | 62 | 62 | +| test.c:26:11:26:15 | ... > ... | true | 26 | 28 | +| test.c:34:16:34:21 | ... < ... | false | 2 | 2 | +| test.c:34:16:34:21 | ... < ... | false | 39 | 42 | +| test.c:34:16:34:21 | ... < ... | false | 42 | 42 | +| 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 | +| test.c:34:16:34:21 | ... < ... | false | 58 | 66 | +| test.c:34:16:34:21 | ... < ... | false | 62 | 62 | +| test.c:34:16:34:21 | ... < ... | true | 34 | 34 | +| test.c:42:16:42:21 | ... < ... | true | 42 | 42 | +| 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 | 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 | +| test.c:58:9:58:23 | ... \|\| ... | false | 62 | 62 | +| test.c:58:19:58:23 | ... < ... | false | 62 | 62 | +| test.c:75:9:75:14 | ... == ... | false | 78 | 79 | +| test.c:75:9:75:14 | ... == ... | true | 75 | 77 | +| test.c:85:8:85:13 | ... == ... | true | 85 | 85 | +| test.c:85:8:85:13 | ... == ... | true | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | true | 86 | 86 | +| test.c:85:18:85:23 | ... != ... | true | 86 | 86 | +| test.c:94:11:94:16 | ... != ... | false | 70 | 70 | +| test.c:94:11:94:16 | ... != ... | false | 99 | 102 | +| test.c:94:11:94:16 | ... != ... | false | 102 | 102 | +| test.c:94:11:94:16 | ... != ... | false | 107 | 109 | +| test.c:94:11:94:16 | ... != ... | false | 109 | 109 | +| test.c:94:11:94:16 | ... != ... | false | 109 | 117 | +| test.c:94:11:94:16 | ... != ... | false | 113 | 113 | +| test.c:94:11:94:16 | ... != ... | true | 94 | 96 | +| test.c:102:16:102:21 | ... < ... | false | 70 | 70 | +| test.c:102:16:102:21 | ... < ... | false | 107 | 109 | +| test.c:102:16:102:21 | ... < ... | false | 109 | 109 | +| test.c:102:16:102:21 | ... < ... | false | 109 | 117 | +| test.c:102:16:102:21 | ... < ... | false | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | true | 102 | 102 | +| test.c:109:9:109:14 | ... == ... | false | 109 | 109 | +| test.c:109:9:109:14 | ... == ... | false | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | false | 113 | 113 | +| 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: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 | true | 137 | 138 | +| test.c:137:7:137:7 | 0 | true | 138 | 139 | +| test.c:138:9:138:9 | i | true | 138 | 139 | +| 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 | +| test.c:152:10:152:10 | x | true | 152 | 152 | +| test.c:152:10:152:15 | ... && ... | true | 151 | 152 | +| test.c:152:15:152:15 | y | true | 151 | 152 | +| test.cpp:18:8:18:10 | call to get | true | 19 | 19 | +| test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 | +| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 | +| test.cpp:42:13:42:20 | call to getABool | false | 53 | 53 | +| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 | +astGuardsEnsure +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 | +| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | 7 | 9 | +| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | 7 | 9 | +| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | >= | test.c:7:9:7:9 | x | 0 | 10 | 11 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 17 | 17 | +| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 18 | 18 | +| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 17 | 17 | +| test.c:17:8:17:12 | ... < ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | test.c:17:12:17:12 | 0 | 0 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:12:17:12 | 0 | >= | test.c:17:8:17:8 | x | 1 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | 18 | 18 | +| test.c:17:8:17:21 | ... && ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | 18 | 18 | +| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | test.c:17:21:17:21 | 1 | 1 | 18 | 18 | +| test.c:17:17:17:21 | ... > ... | test.c:17:21:17:21 | 1 | < | test.c:17:17:17:17 | y | 0 | 18 | 18 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 2 | 2 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 31 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 34 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 39 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 42 | 42 | +| 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 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 58 | 66 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | test.c:26:15:26:15 | 0 | 1 | 62 | 62 | +| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | test.c:26:15:26:15 | 0 | 1 | 26 | 28 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | < | test.c:26:11:26:11 | x | 0 | 26 | 28 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 2 | 2 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 31 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 34 | 34 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 39 | 42 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 42 | 42 | +| 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 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 58 | 66 | +| test.c:26:11:26:15 | ... > ... | test.c:26:15:26:15 | 0 | >= | test.c:26:11:26:11 | x | 0 | 62 | 62 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | test.c:34:20:34:21 | 10 | 0 | 34 | 34 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 2 | 2 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 39 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 42 | 42 | +| 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 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 58 | 66 | +| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | test.c:34:20:34:21 | 10 | 0 | 62 | 62 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 2 | 2 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 39 | 42 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 42 | 42 | +| 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 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 58 | 66 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | < | test.c:34:16:34:16 | j | 1 | 62 | 62 | +| test.c:34:16:34:21 | ... < ... | test.c:34:20:34:21 | 10 | >= | test.c:34:16:34:16 | j | 1 | 34 | 34 | +| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | test.c:42:20:42:21 | 10 | 0 | 42 | 42 | +| 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 | 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 | 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 | +| test.c:58:9:58:14 | ... == ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | test.c:58:14:58:14 | 0 | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:14:58:14 | 0 | != | test.c:58:9:58:9 | x | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | 62 | 62 | +| test.c:58:9:58:23 | ... \|\| ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | 62 | 62 | +| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | test.c:58:23:58:23 | 0 | 0 | 62 | 62 | +| test.c:58:19:58:23 | ... < ... | test.c:58:23:58:23 | 0 | < | test.c:58:19:58:19 | y | 1 | 62 | 62 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | test.c:75:14:75:14 | 0 | 0 | 78 | 79 | +| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | test.c:75:14:75:14 | 0 | 0 | 75 | 77 | +| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | != | test.c:75:9:75:9 | x | 0 | 78 | 79 | +| test.c:75:9:75:14 | ... == ... | test.c:75:14:75:14 | 0 | == | test.c:75:9:75:9 | x | 0 | 75 | 77 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 85 | 85 | +| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 86 | 86 | +| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 85 | 85 | +| test.c:85:8:85:13 | ... == ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | test.c:85:13:85:13 | 0 | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:13:85:13 | 0 | == | test.c:85:8:85:8 | x | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | 86 | 86 | +| test.c:85:8:85:23 | ... && ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | 86 | 86 | +| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | test.c:85:23:85:23 | 0 | 0 | 86 | 86 | +| test.c:85:18:85:23 | ... != ... | test.c:85:23:85:23 | 0 | != | test.c:85:18:85:18 | y | 0 | 86 | 86 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | test.c:94:16:94:16 | 0 | 0 | 94 | 96 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 70 | 70 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 99 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 102 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 107 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 109 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 109 | 117 | +| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | test.c:94:16:94:16 | 0 | 0 | 113 | 113 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | != | test.c:94:11:94:11 | x | 0 | 94 | 96 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 70 | 70 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 99 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 102 | 102 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 107 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 109 | 109 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 109 | 117 | +| test.c:94:11:94:16 | ... != ... | test.c:94:16:94:16 | 0 | == | test.c:94:11:94:11 | x | 0 | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | test.c:102:20:102:21 | 10 | 0 | 102 | 102 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 70 | 70 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 107 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 109 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 109 | 117 | +| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | test.c:102:20:102:21 | 10 | 0 | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 70 | 70 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 107 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 109 | 109 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 109 | 117 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | < | test.c:102:16:102:16 | j | 1 | 113 | 113 | +| test.c:102:16:102:21 | ... < ... | test.c:102:20:102:21 | 10 | >= | test.c:102:16:102:16 | j | 1 | 102 | 102 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 109 | 109 | +| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 113 | 113 | +| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 109 | 109 | +| test.c:109:9:109:14 | ... == ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | test.c:109:14:109:14 | 0 | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:14:109:14 | 0 | != | test.c:109:9:109:9 | x | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | 113 | 113 | +| test.c:109:9:109:23 | ... \|\| ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 | +| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | 113 | 113 | +| test.c:109:19:109:23 | ... < ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 34 | 34 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 31 | 32 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 | +irGuards +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | +| test.c:17:17:17:21 | r17_3(int) = CompareGT r17_1, r17_2 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | +| test.c:58:19:58:23 | r11_3(int) = CompareLT r11_1, r11_2 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | +| test.c:85:18:85:23 | r9_3(int) = CompareNE r9_1, r9_2 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | +| test.c:109:19:109:23 | r3_3(int) = CompareLT r3_1, r3_2 | +| test.c:126:7:126:7 | r0_5(int) = Constant[1] | +| test.c:126:12:126:26 | r1_1(int) = Call r1_0 | +| test.c:131:7:131:7 | r3_2(int) = Load r3_1, m3_0 | +| test.c:137:7:137:7 | r0_4(int) = Constant[0] | +| test.c:138:9:138:9 | r1_1(int) = Load r1_0, m0_3 | +| test.c:146:8:146:8 | r0_5(int) = Load r0_4, m0_3 | +| test.c:152:10:152:10 | r0_7(int) = Load r0_6, m0_3 | +| test.c:152:15:152:15 | r1_1(int) = Load r1_0, m0_5 | +| test.cpp:18:8:18:12 | r0_7(bool) = CompareNE r0_5, r0_6 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | +| test.cpp:42:13:42:20 | r0_5(bool) = Call r0_4 | +irGuardsCompare +| 7 | 0 < x+0 when r0_16(int) = CompareGT r0_14, r0_15 is true | +| 7 | 0 >= x+0 when r0_16(int) = CompareGT r0_14, r0_15 is false | +| 7 | x < 0+1 when r0_16(int) = CompareGT r0_14, r0_15 is false | +| 7 | x >= 0+1 when r0_16(int) = CompareGT r0_14, r0_15 is true | +| 17 | 0 < x+1 when r16_13(int) = CompareLT r16_11, r16_12 is false | +| 17 | 0 >= x+1 when r16_13(int) = CompareLT r16_11, r16_12 is true | +| 17 | 1 < y+0 when r17_3(int) = CompareGT r17_1, r17_2 is true | +| 17 | 1 >= y+0 when r17_3(int) = CompareGT r17_1, r17_2 is false | +| 17 | x < 0+0 when r16_13(int) = CompareLT r16_11, r16_12 is true | +| 17 | x >= 0+0 when r16_13(int) = CompareLT r16_11, r16_12 is false | +| 17 | y < 1+1 when r17_3(int) = CompareGT r17_1, r17_2 is false | +| 17 | y >= 1+1 when r17_3(int) = CompareGT r17_1, r17_2 is true | +| 26 | 0 < x+0 when r21_5(int) = CompareGT r21_3, r21_4 is true | +| 26 | 0 >= x+0 when r21_5(int) = CompareGT r21_3, r21_4 is false | +| 26 | x < 0+1 when r21_5(int) = CompareGT r21_3, r21_4 is false | +| 26 | x >= 0+1 when r21_5(int) = CompareGT r21_3, r21_4 is true | +| 31 | - ... != x+0 when r0_7(bool) = CompareEQ r0_5, r0_6 is false | +| 31 | - ... == x+0 when r0_7(bool) = CompareEQ r0_5, r0_6 is true | +| 31 | x != - ...+0 when r0_7(bool) = CompareEQ r0_5, r0_6 is false | +| 31 | x == - ...+0 when r0_7(bool) = CompareEQ r0_5, r0_6 is true | +| 34 | 10 < j+1 when r24_6(int) = CompareLT r24_4, r24_5 is false | +| 34 | 10 >= j+1 when r24_6(int) = CompareLT r24_4, r24_5 is true | +| 34 | j < 10+0 when r24_6(int) = CompareLT r24_4, r24_5 is true | +| 34 | j >= 10+0 when r24_6(int) = CompareLT r24_4, r24_5 is false | +| 42 | 10 < j+1 when r3_6(int) = CompareLT r3_4, r3_5 is false | +| 42 | 10 >= j+1 when r3_6(int) = CompareLT r3_4, r3_5 is true | +| 42 | j < 10+0 when r3_6(int) = CompareLT r3_4, r3_5 is true | +| 42 | j >= 10+0 when r3_6(int) = CompareLT r3_4, r3_5 is false | +| 44 | 0 < z+0 when r4_6(int) = CompareGT r4_4, r4_5 is true | +| 44 | 0 >= z+0 when r4_6(int) = CompareGT r4_4, r4_5 is false | +| 44 | z < 0+1 when r4_6(int) = CompareGT r4_4, r4_5 is false | +| 44 | z >= 0+1 when r4_6(int) = CompareGT r4_4, r4_5 is true | +| 45 | 0 < y+0 when r5_3(int) = CompareGT r5_1, r5_2 is true | +| 45 | 0 >= y+0 when r5_3(int) = CompareGT r5_1, r5_2 is false | +| 45 | y < 0+1 when r5_3(int) = CompareGT r5_1, r5_2 is false | +| 45 | y >= 0+1 when r5_3(int) = CompareGT r5_1, r5_2 is true | +| 58 | 0 != x+0 when r10_5(int) = CompareEQ r10_3, r10_4 is false | +| 58 | 0 < y+1 when r11_3(int) = CompareLT r11_1, r11_2 is false | +| 58 | 0 == x+0 when r10_5(int) = CompareEQ r10_3, r10_4 is true | +| 58 | 0 >= y+1 when r11_3(int) = CompareLT r11_1, r11_2 is true | +| 58 | x != 0+0 when r10_5(int) = CompareEQ r10_3, r10_4 is false | +| 58 | x == 0+0 when r10_5(int) = CompareEQ r10_3, r10_4 is true | +| 58 | y < 0+0 when r11_3(int) = CompareLT r11_1, r11_2 is true | +| 58 | y >= 0+0 when r11_3(int) = CompareLT r11_1, r11_2 is false | +| 75 | 0 != x+0 when r0_16(int) = CompareEQ r0_14, r0_15 is false | +| 75 | 0 == x+0 when r0_16(int) = CompareEQ r0_14, r0_15 is true | +| 75 | x != 0+0 when r0_16(int) = CompareEQ r0_14, r0_15 is false | +| 75 | x == 0+0 when r0_16(int) = CompareEQ r0_14, r0_15 is true | +| 85 | 0 != x+0 when r8_13(int) = CompareEQ r8_11, r8_12 is false | +| 85 | 0 != y+0 when r9_3(int) = CompareNE r9_1, r9_2 is true | +| 85 | 0 == x+0 when r8_13(int) = CompareEQ r8_11, r8_12 is true | +| 85 | 0 == y+0 when r9_3(int) = CompareNE r9_1, r9_2 is false | +| 85 | x != 0+0 when r8_13(int) = CompareEQ r8_11, r8_12 is false | +| 85 | x == 0+0 when r8_13(int) = CompareEQ r8_11, r8_12 is true | +| 85 | y != 0+0 when r9_3(int) = CompareNE r9_1, r9_2 is true | +| 85 | y == 0+0 when r9_3(int) = CompareNE r9_1, r9_2 is false | +| 94 | 0 != x+0 when r13_5(int) = CompareNE r13_3, r13_4 is true | +| 94 | 0 == x+0 when r13_5(int) = CompareNE r13_3, r13_4 is false | +| 94 | x != 0+0 when r13_5(int) = CompareNE r13_3, r13_4 is true | +| 94 | x == 0+0 when r13_5(int) = CompareNE r13_3, r13_4 is false | +| 102 | 10 < j+1 when r16_6(int) = CompareLT r16_4, r16_5 is false | +| 102 | 10 >= j+1 when r16_6(int) = CompareLT r16_4, r16_5 is true | +| 102 | j < 10+0 when r16_6(int) = CompareLT r16_4, r16_5 is true | +| 102 | j >= 10+0 when r16_6(int) = CompareLT r16_4, r16_5 is false | +| 109 | 0 != x+0 when r2_9(int) = CompareEQ r2_7, r2_8 is false | +| 109 | 0 < y+1 when r3_3(int) = CompareLT r3_1, r3_2 is false | +| 109 | 0 == x+0 when r2_9(int) = CompareEQ r2_7, r2_8 is true | +| 109 | 0 >= y+1 when r3_3(int) = CompareLT r3_1, r3_2 is true | +| 109 | x != 0+0 when r2_9(int) = CompareEQ r2_7, r2_8 is false | +| 109 | x == 0+0 when r2_9(int) = CompareEQ r2_7, r2_8 is true | +| 109 | y < 0+0 when r3_3(int) = CompareLT r3_1, r3_2 is true | +| 109 | y >= 0+0 when r3_3(int) = CompareLT r3_1, r3_2 is false | +irGuardsControl +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | false | 11 | 11 | +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | true | 8 | 8 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | true | 17 | 17 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | true | 18 | 18 | +| test.c:17:17:17:21 | r17_3(int) = CompareGT r17_1, r17_2 | true | 18 | 18 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 2 | 2 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 31 | 31 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 34 | 34 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 35 | 35 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 39 | 39 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 42 | 42 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 43 | 43 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 45 | 45 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 46 | 46 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 49 | 49 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 52 | 52 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 56 | 56 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 58 | 58 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 59 | 59 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | false | 62 | 62 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | true | 27 | 27 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 2 | 2 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 39 | 39 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 42 | 42 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 43 | 43 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 45 | 45 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 46 | 46 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 49 | 49 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 52 | 52 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 56 | 56 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 58 | 58 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 59 | 59 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | false | 62 | 62 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | true | 35 | 35 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 42 | 42 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 43 | 43 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 45 | 45 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 46 | 46 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 49 | 49 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | true | 52 | 52 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | false | 52 | 52 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | true | 45 | 45 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | true | 46 | 46 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | true | 49 | 49 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | false | 49 | 49 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | true | 46 | 46 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | false | 58 | 58 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | false | 62 | 62 | +| test.c:58:19:58:23 | r11_3(int) = CompareLT r11_1, r11_2 | false | 62 | 62 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | false | 79 | 79 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | true | 76 | 76 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | true | 85 | 85 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | true | 86 | 86 | +| test.c:85:18:85:23 | r9_3(int) = CompareNE r9_1, r9_2 | true | 86 | 86 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 70 | 70 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 99 | 99 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 102 | 102 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 103 | 103 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 107 | 107 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 109 | 109 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 110 | 110 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | false | 113 | 113 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | true | 95 | 95 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | false | 70 | 70 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | false | 107 | 107 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | false | 109 | 109 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | false | 110 | 110 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | false | 113 | 113 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | true | 103 | 103 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | false | 109 | 109 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | false | 113 | 113 | +| test.c:109:19:109:23 | r3_3(int) = CompareLT r3_1, r3_2 | false | 113 | 113 | +| test.c:126:7:126:7 | r0_5(int) = Constant[1] | true | 126 | 126 | +| test.c:126:7:126:7 | r0_5(int) = Constant[1] | true | 127 | 127 | +| test.c:126:12:126:26 | r1_1(int) = Call r1_0 | true | 127 | 127 | +| test.c:131:7:131:7 | r3_2(int) = Load r3_1, m3_0 | true | 132 | 132 | +| test.c:137:7:137:7 | r0_4(int) = Constant[0] | true | 138 | 138 | +| test.c:137:7:137:7 | r0_4(int) = Constant[0] | true | 139 | 139 | +| test.c:138:9:138:9 | r1_1(int) = Load r1_0, m0_3 | true | 139 | 139 | +| test.c:146:8:146:8 | r0_5(int) = Load r0_4, m0_3 | false | 147 | 147 | +| test.c:152:10:152:10 | r0_7(int) = Load r0_6, m0_3 | true | 152 | 152 | +| test.c:152:15:152:15 | r1_1(int) = Load r1_0, m0_5 | true | 152 | 152 | +| test.cpp:18:8:18:12 | r0_7(bool) = CompareNE r0_5, r0_6 | true | 0 | 0 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | false | 34 | 34 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | true | 30 | 30 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | true | 32 | 32 | +| test.cpp:42:13:42:20 | r0_5(bool) = Call r0_4 | false | 53 | 53 | +| test.cpp:42:13:42:20 | r0_5(bool) = Call r0_4 | true | 44 | 44 | +irGuardsEnsure +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | test.c:7:9:7:9 | r0_14(int) = Load r0_13, m0_3 | < | test.c:7:13:7:13 | r0_15(int) = Constant[0] | 1 | 11 | 11 | +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | test.c:7:9:7:9 | r0_14(int) = Load r0_13, m0_3 | >= | test.c:7:13:7:13 | r0_15(int) = Constant[0] | 1 | 8 | 8 | +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | test.c:7:13:7:13 | r0_15(int) = Constant[0] | < | test.c:7:9:7:9 | r0_14(int) = Load r0_13, m0_3 | 0 | 8 | 8 | +| test.c:7:9:7:13 | r0_16(int) = CompareGT r0_14, r0_15 | test.c:7:13:7:13 | r0_15(int) = Constant[0] | >= | test.c:7:9:7:9 | r0_14(int) = Load r0_13, m0_3 | 0 | 11 | 11 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | test.c:17:8:17:8 | r16_11(int) = Load r16_10, m0_3 | < | test.c:17:12:17:12 | r16_12(int) = Constant[0] | 0 | 17 | 17 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | test.c:17:8:17:8 | r16_11(int) = Load r16_10, m0_3 | < | test.c:17:12:17:12 | r16_12(int) = Constant[0] | 0 | 18 | 18 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | test.c:17:12:17:12 | r16_12(int) = Constant[0] | >= | test.c:17:8:17:8 | r16_11(int) = Load r16_10, m0_3 | 1 | 17 | 17 | +| test.c:17:8:17:12 | r16_13(int) = CompareLT r16_11, r16_12 | test.c:17:12:17:12 | r16_12(int) = Constant[0] | >= | test.c:17:8:17:8 | r16_11(int) = Load r16_10, m0_3 | 1 | 18 | 18 | +| test.c:17:17:17:21 | r17_3(int) = CompareGT r17_1, r17_2 | test.c:17:17:17:17 | r17_1(long) = Load r17_0, m16_0 | >= | test.c:17:21:17:21 | r17_2(long) = Constant[1] | 1 | 18 | 18 | +| test.c:17:17:17:21 | r17_3(int) = CompareGT r17_1, r17_2 | test.c:17:21:17:21 | r17_2(long) = Constant[1] | < | test.c:17:17:17:17 | r17_1(long) = Load r17_0, m16_0 | 0 | 18 | 18 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 2 | 2 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 31 | 31 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 34 | 34 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 35 | 35 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 39 | 39 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 42 | 42 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 43 | 43 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 45 | 45 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 46 | 46 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 49 | 49 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 52 | 52 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 56 | 56 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 58 | 58 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 59 | 59 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | < | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 62 | 62 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | >= | test.c:26:15:26:15 | r21_4(int) = Constant[0] | 1 | 27 | 27 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | < | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 27 | 27 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 2 | 2 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 31 | 31 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 34 | 34 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 35 | 35 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 39 | 39 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 42 | 42 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 43 | 43 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 45 | 45 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 46 | 46 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 49 | 49 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 52 | 52 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 56 | 56 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 58 | 58 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 59 | 59 | +| test.c:26:11:26:15 | r21_5(int) = CompareGT r21_3, r21_4 | test.c:26:15:26:15 | r21_4(int) = Constant[0] | >= | test.c:26:11:26:11 | r21_3(int) = Load r21_2, m21_0 | 0 | 62 | 62 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | < | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 35 | 35 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 2 | 2 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 39 | 39 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 42 | 42 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 43 | 43 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 45 | 45 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 46 | 46 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 49 | 49 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 52 | 52 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 56 | 56 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 58 | 58 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 59 | 59 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | >= | test.c:34:20:34:21 | r24_5(int) = Constant[10] | 0 | 62 | 62 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 2 | 2 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 39 | 39 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 42 | 42 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 43 | 43 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 45 | 45 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 46 | 46 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 49 | 49 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 52 | 52 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 56 | 56 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 58 | 58 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 59 | 59 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | < | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 62 | 62 | +| test.c:34:16:34:21 | r24_6(int) = CompareLT r24_4, r24_5 | test.c:34:20:34:21 | r24_5(int) = Constant[10] | >= | test.c:34:16:34:16 | r24_4(int) = Load r24_3, m24_0 | 1 | 35 | 35 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 42 | 42 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 43 | 43 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 45 | 45 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 46 | 46 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 49 | 49 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | < | test.c:42:20:42:21 | r3_5(int) = Constant[10] | 0 | 52 | 52 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 42 | 42 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 43 | 43 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 45 | 45 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 46 | 46 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 49 | 49 | +| test.c:42:16:42:21 | r3_6(int) = CompareLT r3_4, r3_5 | test.c:42:20:42:21 | r3_5(int) = Constant[10] | >= | test.c:42:16:42:16 | r3_4(int) = Load r3_3, m3_0 | 1 | 52 | 52 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | < | test.c:44:16:44:16 | r4_5(int) = Constant[0] | 1 | 52 | 52 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | >= | test.c:44:16:44:16 | r4_5(int) = Constant[0] | 1 | 45 | 45 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | >= | test.c:44:16:44:16 | r4_5(int) = Constant[0] | 1 | 46 | 46 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | >= | test.c:44:16:44:16 | r4_5(int) = Constant[0] | 1 | 49 | 49 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:16:44:16 | r4_5(int) = Constant[0] | < | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | 0 | 45 | 45 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:16:44:16 | r4_5(int) = Constant[0] | < | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | 0 | 46 | 46 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:16:44:16 | r4_5(int) = Constant[0] | < | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | 0 | 49 | 49 | +| test.c:44:12:44:16 | r4_6(int) = CompareGT r4_4, r4_5 | test.c:44:16:44:16 | r4_5(int) = Constant[0] | >= | test.c:44:12:44:12 | r4_4(int) = Load r4_3, m2_5 | 0 | 52 | 52 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | test.c:45:16:45:16 | r5_1(long) = Load r5_0, m4_2 | < | test.c:45:20:45:20 | r5_2(long) = Constant[0] | 1 | 49 | 49 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | test.c:45:16:45:16 | r5_1(long) = Load r5_0, m4_2 | >= | test.c:45:20:45:20 | r5_2(long) = Constant[0] | 1 | 46 | 46 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | test.c:45:20:45:20 | r5_2(long) = Constant[0] | < | test.c:45:16:45:16 | r5_1(long) = Load r5_0, m4_2 | 0 | 46 | 46 | +| test.c:45:16:45:20 | r5_3(int) = CompareGT r5_1, r5_2 | test.c:45:20:45:20 | r5_2(long) = Constant[0] | >= | test.c:45:16:45:16 | r5_1(long) = Load r5_0, m4_2 | 0 | 49 | 49 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | test.c:58:9:58:9 | r10_3(int) = Load r10_2, m3_1 | != | test.c:58:14:58:14 | r10_4(int) = Constant[0] | 0 | 58 | 58 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | test.c:58:9:58:9 | r10_3(int) = Load r10_2, m3_1 | != | test.c:58:14:58:14 | r10_4(int) = Constant[0] | 0 | 62 | 62 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | test.c:58:14:58:14 | r10_4(int) = Constant[0] | != | test.c:58:9:58:9 | r10_3(int) = Load r10_2, m3_1 | 0 | 58 | 58 | +| test.c:58:9:58:14 | r10_5(int) = CompareEQ r10_3, r10_4 | test.c:58:14:58:14 | r10_4(int) = Constant[0] | != | test.c:58:9:58:9 | r10_3(int) = Load r10_2, m3_1 | 0 | 62 | 62 | +| test.c:58:19:58:23 | r11_3(int) = CompareLT r11_1, r11_2 | test.c:58:19:58:19 | r11_1(long) = Load r11_0, m10_0 | >= | test.c:58:23:58:23 | r11_2(long) = Constant[0] | 0 | 62 | 62 | +| test.c:58:19:58:23 | r11_3(int) = CompareLT r11_1, r11_2 | test.c:58:23:58:23 | r11_2(long) = Constant[0] | < | test.c:58:19:58:19 | r11_1(long) = Load r11_0, m10_0 | 1 | 62 | 62 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | test.c:75:9:75:9 | r0_14(int) = Load r0_13, m0_3 | != | test.c:75:14:75:14 | r0_15(int) = Constant[0] | 0 | 79 | 79 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | test.c:75:9:75:9 | r0_14(int) = Load r0_13, m0_3 | == | test.c:75:14:75:14 | r0_15(int) = Constant[0] | 0 | 76 | 76 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | test.c:75:14:75:14 | r0_15(int) = Constant[0] | != | test.c:75:9:75:9 | r0_14(int) = Load r0_13, m0_3 | 0 | 79 | 79 | +| test.c:75:9:75:14 | r0_16(int) = CompareEQ r0_14, r0_15 | test.c:75:14:75:14 | r0_15(int) = Constant[0] | == | test.c:75:9:75:9 | r0_14(int) = Load r0_13, m0_3 | 0 | 76 | 76 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | test.c:85:8:85:8 | r8_11(int) = Load r8_10, m0_3 | == | test.c:85:13:85:13 | r8_12(int) = Constant[0] | 0 | 85 | 85 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | test.c:85:8:85:8 | r8_11(int) = Load r8_10, m0_3 | == | test.c:85:13:85:13 | r8_12(int) = Constant[0] | 0 | 86 | 86 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | test.c:85:13:85:13 | r8_12(int) = Constant[0] | == | test.c:85:8:85:8 | r8_11(int) = Load r8_10, m0_3 | 0 | 85 | 85 | +| test.c:85:8:85:13 | r8_13(int) = CompareEQ r8_11, r8_12 | test.c:85:13:85:13 | r8_12(int) = Constant[0] | == | test.c:85:8:85:8 | r8_11(int) = Load r8_10, m0_3 | 0 | 86 | 86 | +| test.c:85:18:85:23 | r9_3(int) = CompareNE r9_1, r9_2 | test.c:85:18:85:18 | r9_1(long) = Load r9_0, m8_0 | != | test.c:85:23:85:23 | r9_2(long) = Constant[0] | 0 | 86 | 86 | +| test.c:85:18:85:23 | r9_3(int) = CompareNE r9_1, r9_2 | test.c:85:23:85:23 | r9_2(long) = Constant[0] | != | test.c:85:18:85:18 | r9_1(long) = Load r9_0, m8_0 | 0 | 86 | 86 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | != | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 95 | 95 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 70 | 70 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 99 | 99 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 102 | 102 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 103 | 103 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 107 | 107 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 109 | 109 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 110 | 110 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | == | test.c:94:16:94:16 | r13_4(int) = Constant[0] | 0 | 113 | 113 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | != | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 95 | 95 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 70 | 70 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 99 | 99 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 102 | 102 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 103 | 103 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 107 | 107 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 109 | 109 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 110 | 110 | +| test.c:94:11:94:16 | r13_5(int) = CompareNE r13_3, r13_4 | test.c:94:16:94:16 | r13_4(int) = Constant[0] | == | test.c:94:11:94:11 | r13_3(int) = Load r13_2, m13_0 | 0 | 113 | 113 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | < | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 103 | 103 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | >= | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 70 | 70 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | >= | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 107 | 107 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | >= | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 109 | 109 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | >= | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 110 | 110 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | >= | test.c:102:20:102:21 | r16_5(int) = Constant[10] | 0 | 113 | 113 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | < | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 70 | 70 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | < | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 107 | 107 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | < | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 109 | 109 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | < | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 110 | 110 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | < | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 113 | 113 | +| test.c:102:16:102:21 | r16_6(int) = CompareLT r16_4, r16_5 | test.c:102:20:102:21 | r16_5(int) = Constant[10] | >= | test.c:102:16:102:16 | r16_4(int) = Load r16_3, m16_0 | 1 | 103 | 103 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | test.c:109:9:109:9 | r2_7(int) = Load r2_6, m13_0 | != | test.c:109:14:109:14 | r2_8(int) = Constant[0] | 0 | 109 | 109 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | test.c:109:9:109:9 | r2_7(int) = Load r2_6, m13_0 | != | test.c:109:14:109:14 | r2_8(int) = Constant[0] | 0 | 113 | 113 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | test.c:109:14:109:14 | r2_8(int) = Constant[0] | != | test.c:109:9:109:9 | r2_7(int) = Load r2_6, m13_0 | 0 | 109 | 109 | +| test.c:109:9:109:14 | r2_9(int) = CompareEQ r2_7, r2_8 | test.c:109:14:109:14 | r2_8(int) = Constant[0] | != | test.c:109:9:109:9 | r2_7(int) = Load r2_6, m13_0 | 0 | 113 | 113 | +| test.c:109:19:109:23 | r3_3(int) = CompareLT r3_1, r3_2 | test.c:109:19:109:19 | r3_1(long) = Load r3_0, m16_2 | >= | test.c:109:23:109:23 | r3_2(long) = Constant[0] | 0 | 113 | 113 | +| test.c:109:19:109:23 | r3_3(int) = CompareLT r3_1, r3_2 | test.c:109:23:109:23 | r3_2(long) = Constant[0] | < | test.c:109:19:109:19 | r3_1(long) = Load r3_0, m16_2 | 1 | 113 | 113 | +| test.cpp:18:8:18:12 | r0_7(bool) = CompareNE r0_5, r0_6 | test.cpp:18:8:18:10 | r0_5(X *) = Call r0_4, this:r0_3 | != | test.cpp:18:8:18:12 | r0_6(X *) = Constant[0] | 0 | 0 | 0 | +| test.cpp:18:8:18:12 | r0_7(bool) = CompareNE r0_5, r0_6 | test.cpp:18:8:18:12 | r0_6(X *) = Constant[0] | != | test.cpp:18:8:18:10 | r0_5(X *) = Call r0_4, this:r0_3 | 0 | 0 | 0 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | != | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | 0 | 34 | 34 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | == | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | == | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | 0 | 32 | 32 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | != | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | 0 | 34 | 34 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | == | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | 0 | 30 | 30 | +| test.cpp:31:7:31:13 | r0_7(bool) = CompareEQ r0_5, r0_6 | test.cpp:31:12:31:13 | r0_6(int) = Constant[-1] | == | test.cpp:31:7:31:7 | r0_5(int) = Load r0_4, m0_3 | 0 | 32 | 32 | diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql new file mode 100644 index 000000000000..2bb8b2f9fa99 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql @@ -0,0 +1,91 @@ +import cpp +import semmle.code.cpp.controlflow.IRGuards + +query predicate astGuards(GuardCondition guard) { + any() +} + +query predicate astGuardsCompare(int startLine, string msg) { + exists(GuardCondition guard, Expr left, Expr right, int k, string which, string op | + exists(boolean sense | + sense = true and which = "true" + or sense = false and which = "false" + | + guard.comparesLt(left, right, k, true, sense) and op = " < " + or + guard.comparesLt(left, right, k, false, sense) and op = " >= " + or + guard.comparesEq(left, right, k, true, sense) and op = " == " + or + guard.comparesEq(left, right, k, false, sense) and op = " != " + ) + and startLine = guard.getLocation().getStartLine() + and msg = left + op + right + "+" + k + " when " + guard + " is " + which + ) +} + +query predicate astGuardsControl(GuardCondition guard, boolean sense, int start, int end) { + exists(BasicBlock block | + guard.controls(block, sense) and + block.hasLocationInfo(_, start, _, end, _) + ) +} + +query predicate astGuardsEnsure(GuardCondition guard, Expr left, string op, Expr right, int k, int start, int end) +{ + exists(BasicBlock block | + guard.ensuresLt(left, right, k, block, true) and op = "<" + or + guard.ensuresLt(left, right, k, block, false) and op = ">=" + or + guard.ensuresEq(left, right, k, block, true) and op = "==" + or + guard.ensuresEq(left, right, k, block, false) and op = "!=" + | + block.hasLocationInfo(_, start, _, end, _) + ) +} + +query predicate irGuards(IRGuardCondition guard) { + any() +} + +query predicate irGuardsCompare(int startLine, string msg) { + exists(IRGuardCondition guard, Instruction left, Instruction right, int k, string which, string op | + exists(boolean sense | + sense = true and which = "true" + or sense = false and which = "false" + | + guard.comparesLt(left, right, k, true, sense) and op = " < " + or + guard.comparesLt(left, right, k, false, sense) and op = " >= " + or + guard.comparesEq(left, right, k, true, sense) and op = " == " + or + guard.comparesEq(left, right, k, false, sense) and op = " != " + ) + and startLine = guard.getLocation().getStartLine() + and msg = left.getUnconvertedResultExpression() + op + right.getUnconvertedResultExpression() + "+" + k + " when " + guard + " is " + which + ) +} +query predicate irGuardsControl(IRGuardCondition guard, boolean sense, int start, int end) { + exists(IRBlock block | + guard.controls(block, sense) and + block.getLocation().hasLocationInfo(_, start, _, end, _) + ) +} + +query predicate irGuardsEnsure(IRGuardCondition guard, Instruction left, string op, Instruction right, int k, int start, int end) +{ + exists(IRBlock block | + guard.ensuresLt(left, right, k, block, true) and op = "<" + or + guard.ensuresLt(left, right, k, block, false) and op = ">=" + or + guard.ensuresEq(left, right, k, block, true) and op = "==" + or + guard.ensuresEq(left, right, k, block, false) and op = "!=" + | + block.getLocation().hasLocationInfo(_, start, _, end, _) + ) +}