mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #19571 from aschackmull/rangeanalysis/guards
Rangeanalysis: Simplify Guards integration.
This commit is contained in:
@@ -264,10 +264,6 @@ module SemanticExprConfig {
|
|||||||
|
|
||||||
Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e }
|
Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e }
|
||||||
|
|
||||||
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
|
|
||||||
none() // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the expression associated with `instr`. */
|
/** Gets the expression associated with `instr`. */
|
||||||
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
|
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ class SemGuard instanceof Specific::Guard {
|
|||||||
Specific::equalityGuard(this, e1, e2, polarity)
|
Specific::equalityGuard(this, e1, e2, polarity)
|
||||||
}
|
}
|
||||||
|
|
||||||
final predicate directlyControls(SemBasicBlock controlled, boolean branch) {
|
final predicate controls(SemBasicBlock controlled, boolean branch) {
|
||||||
Specific::guardDirectlyControlsBlock(this, controlled, branch)
|
Specific::guardDirectlyControlsBlock(this, controlled, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
final predicate hasBranchEdge(SemBasicBlock bb1, SemBasicBlock bb2, boolean branch) {
|
final predicate controlsBranchEdge(SemBasicBlock bb1, SemBasicBlock bb2, boolean branch) {
|
||||||
Specific::guardHasBranchEdge(this, bb1, bb2, branch)
|
Specific::guardHasBranchEdge(this, bb1, bb2, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +31,4 @@ class SemGuard instanceof Specific::Guard {
|
|||||||
final SemExpr asExpr() { result = Specific::getGuardAsExpr(this) }
|
final SemExpr asExpr() { result = Specific::getGuardAsExpr(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate semImplies_v2(SemGuard g1, boolean b1, SemGuard g2, boolean b2) {
|
|
||||||
Specific::implies_v2(g1, b1, g2, b2)
|
|
||||||
}
|
|
||||||
|
|
||||||
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }
|
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ module Sem implements Semantic<SemLocation> {
|
|||||||
|
|
||||||
class Guard = SemGuard;
|
class Guard = SemGuard;
|
||||||
|
|
||||||
predicate implies_v2 = semImplies_v2/4;
|
|
||||||
|
|
||||||
class Type = SemType;
|
class Type = SemType;
|
||||||
|
|
||||||
class IntegerType = SemIntegerType;
|
class IntegerType = SemIntegerType;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ private predicate valueFlowStepSsa(SsaVariable v, SsaReadPosition pos, Expr e, i
|
|||||||
exists(Guard guard, boolean testIsTrue |
|
exists(Guard guard, boolean testIsTrue |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
|
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
|
||||||
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
|
guardControlsSsaRead(guard, pos, testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ module Private {
|
|||||||
|
|
||||||
class LeftShiftExpr = RU::ExprNode::LeftShiftExpr;
|
class LeftShiftExpr = RU::ExprNode::LeftShiftExpr;
|
||||||
|
|
||||||
predicate guardDirectlyControlsSsaRead = RU::guardControlsSsaRead/3;
|
|
||||||
|
|
||||||
predicate guardControlsSsaRead = RU::guardControlsSsaRead/3;
|
predicate guardControlsSsaRead = RU::guardControlsSsaRead/3;
|
||||||
|
|
||||||
predicate valueFlowStep = RU::valueFlowStep/3;
|
predicate valueFlowStep = RU::valueFlowStep/3;
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
|
|||||||
* Evaluating a switch case to true corresponds to taking that switch case, and
|
* Evaluating a switch case to true corresponds to taking that switch case, and
|
||||||
* evaluating it to false corresponds to taking some other branch.
|
* evaluating it to false corresponds to taking some other branch.
|
||||||
*/
|
*/
|
||||||
class Guard extends ExprParent {
|
final class Guard extends ExprParent {
|
||||||
Guard() {
|
Guard() {
|
||||||
this.(Expr).getType() instanceof BooleanType and not this instanceof BooleanLiteral
|
this.(Expr).getType() instanceof BooleanType and not this instanceof BooleanLiteral
|
||||||
or
|
or
|
||||||
@@ -360,6 +360,18 @@ private predicate guardControls_v3(Guard guard, BasicBlock controlled, boolean b
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate guardControlsBranchEdge_v2(
|
||||||
|
Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch
|
||||||
|
) {
|
||||||
|
guard.hasBranchEdge(bb1, bb2, branch)
|
||||||
|
or
|
||||||
|
exists(Guard g, boolean b |
|
||||||
|
guardControlsBranchEdge_v2(g, bb1, bb2, b) and
|
||||||
|
implies_v2(g, b, guard, branch)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate guardControlsBranchEdge_v3(
|
private predicate guardControlsBranchEdge_v3(
|
||||||
Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch
|
Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch
|
||||||
@@ -372,6 +384,27 @@ private predicate guardControlsBranchEdge_v3(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** INTERNAL: Use `Guard` instead. */
|
||||||
|
final class Guard_v2 extends Guard {
|
||||||
|
/**
|
||||||
|
* Holds if this guard evaluating to `branch` controls the control-flow
|
||||||
|
* branch edge from `bb1` to `bb2`. That is, following the edge from
|
||||||
|
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
|
||||||
|
*/
|
||||||
|
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
|
||||||
|
guardControlsBranchEdge_v2(this, bb1, bb2, branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this guard evaluating to `branch` directly or indirectly controls
|
||||||
|
* the block `controlled`. That is, the evaluation of `controlled` is
|
||||||
|
* dominated by this guard evaluating to `branch`.
|
||||||
|
*/
|
||||||
|
predicate controls(BasicBlock controlled, boolean branch) {
|
||||||
|
guardControls_v2(this, controlled, branch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
|
private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
|
||||||
exists(EqualityTest eqtest |
|
exists(EqualityTest eqtest |
|
||||||
eqtest = g and
|
eqtest = g and
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ private predicate valueFlowStepSsa(SsaVariable v, SsaReadPosition pos, Expr e, i
|
|||||||
exists(Guard guard, boolean testIsTrue |
|
exists(Guard guard, boolean testIsTrue |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
|
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
|
||||||
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
|
guardControlsSsaRead(guard, pos, testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -219,16 +219,10 @@ module Sem implements Semantic<Location> {
|
|||||||
|
|
||||||
int getBlockId1(BasicBlock bb) { idOf(bb, result) }
|
int getBlockId1(BasicBlock bb) { idOf(bb, result) }
|
||||||
|
|
||||||
final private class FinalGuard = GL::Guard;
|
class Guard extends GL::Guard_v2 {
|
||||||
|
|
||||||
class Guard extends FinalGuard {
|
|
||||||
Expr asExpr() { result = this }
|
Expr asExpr() { result = this }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
|
|
||||||
GL::implies_v2(g1, b1, g2, b2)
|
|
||||||
}
|
|
||||||
|
|
||||||
class Type = J::Type;
|
class Type = J::Type;
|
||||||
|
|
||||||
class IntegerType extends J::IntegralType {
|
class IntegerType extends J::IntegralType {
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ predicate ssaUpdateStep = U::ssaUpdateStep/3;
|
|||||||
|
|
||||||
predicate valueFlowStep = U::valueFlowStep/3;
|
predicate valueFlowStep = U::valueFlowStep/3;
|
||||||
|
|
||||||
predicate guardDirectlyControlsSsaRead = U::guardDirectlyControlsSsaRead/3;
|
|
||||||
|
|
||||||
predicate guardControlsSsaRead = U::guardControlsSsaRead/3;
|
predicate guardControlsSsaRead = U::guardControlsSsaRead/3;
|
||||||
|
|
||||||
predicate eqFlowCond = U::eqFlowCond/5;
|
predicate eqFlowCond = U::eqFlowCond/5;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ module Private {
|
|||||||
private import semmle.code.java.dataflow.RangeUtils as RU
|
private import semmle.code.java.dataflow.RangeUtils as RU
|
||||||
private import semmle.code.java.controlflow.Guards as G
|
private import semmle.code.java.controlflow.Guards as G
|
||||||
private import semmle.code.java.controlflow.BasicBlocks as BB
|
private import semmle.code.java.controlflow.BasicBlocks as BB
|
||||||
private import semmle.code.java.controlflow.internal.GuardsLogic as GL
|
|
||||||
private import SsaReadPositionCommon
|
private import SsaReadPositionCommon
|
||||||
|
|
||||||
class BasicBlock = BB::BasicBlock;
|
class BasicBlock = BB::BasicBlock;
|
||||||
@@ -15,7 +14,7 @@ module Private {
|
|||||||
|
|
||||||
class Expr = J::Expr;
|
class Expr = J::Expr;
|
||||||
|
|
||||||
class Guard = G::Guard;
|
class Guard = G::Guard_v2;
|
||||||
|
|
||||||
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
|
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
|
||||||
|
|
||||||
@@ -101,29 +100,17 @@ module Private {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` directly controls the position `controlled` with the
|
|
||||||
* value `testIsTrue`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
|
||||||
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
|
||||||
or
|
|
||||||
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
|
||||||
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
|
|
||||||
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
||||||
*/
|
*/
|
||||||
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
||||||
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
|
guard.controls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
||||||
or
|
or
|
||||||
exists(Guard guard0, boolean testIsTrue0 |
|
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
||||||
GL::implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
|
guard.controls(controlledEdge.getOrigBlock(), testIsTrue) or
|
||||||
guardControlsSsaRead(guard0, controlled, testIsTrue0)
|
guard
|
||||||
|
.controlsBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(),
|
||||||
|
testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ module Private {
|
|||||||
private import semmle.code.java.dataflow.SSA as Ssa
|
private import semmle.code.java.dataflow.SSA as Ssa
|
||||||
private import semmle.code.java.controlflow.Guards as G
|
private import semmle.code.java.controlflow.Guards as G
|
||||||
private import SsaReadPositionCommon
|
private import SsaReadPositionCommon
|
||||||
private import semmle.code.java.controlflow.internal.GuardsLogic as GL
|
|
||||||
private import Sign
|
private import Sign
|
||||||
import Impl
|
import Impl
|
||||||
|
|
||||||
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
|
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
|
||||||
|
|
||||||
class Guard = G::Guard;
|
class Guard = G::Guard_v2;
|
||||||
|
|
||||||
class SsaVariable = Ssa::SsaVariable;
|
class SsaVariable = Ssa::SsaVariable;
|
||||||
|
|
||||||
@@ -170,31 +169,17 @@ module Private {
|
|||||||
|
|
||||||
predicate ssaRead = RU::ssaRead/2;
|
predicate ssaRead = RU::ssaRead/2;
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` directly controls the position `controlled` with the
|
|
||||||
* value `testIsTrue`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate guardDirectlyControlsSsaRead(
|
|
||||||
Guard guard, SsaReadPosition controlled, boolean testIsTrue
|
|
||||||
) {
|
|
||||||
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
|
||||||
or
|
|
||||||
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
|
||||||
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
|
|
||||||
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
||||||
*/
|
*/
|
||||||
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
||||||
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
|
guard.controls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
||||||
or
|
or
|
||||||
exists(Guard guard0, boolean testIsTrue0 |
|
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
||||||
GL::implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
|
guard.controls(controlledEdge.getOrigBlock(), testIsTrue) or
|
||||||
guardControlsSsaRead(guard0, controlled, testIsTrue0)
|
guard
|
||||||
|
.controlsBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(),
|
||||||
|
testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ module ModulusAnalysis<
|
|||||||
exists(Sem::Guard guard, boolean testIsTrue |
|
exists(Sem::Guard guard, boolean testIsTrue |
|
||||||
hasReadOfVarInlineLate(pos, v) and
|
hasReadOfVarInlineLate(pos, v) and
|
||||||
guard = eqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
|
guard = eqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
|
||||||
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
|
guardControlsSsaRead(guard, pos, testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,21 +181,6 @@ signature module Semantic<LocationSig Location> {
|
|||||||
*/
|
*/
|
||||||
Expr asExpr();
|
Expr asExpr();
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the guard directly controls a given basic block. For example in
|
|
||||||
* the following code, the guard `(x > y)` directly controls the block
|
|
||||||
* beneath it:
|
|
||||||
* ```
|
|
||||||
* if (x > y)
|
|
||||||
* {
|
|
||||||
* Console.WriteLine("x is greater than y");
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* `branch` indicates whether the basic block is entered when the guard
|
|
||||||
* evaluates to `true` or when it evaluates to `false`.
|
|
||||||
*/
|
|
||||||
predicate directlyControls(BasicBlock controlled, boolean branch);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this guard is an equality test between `e1` and `e2`. If the
|
* Holds if this guard is an equality test between `e1` and `e2`. If the
|
||||||
* test is negated, that is `!=`, then `polarity` is false, otherwise
|
* test is negated, that is `!=`, then `polarity` is false, otherwise
|
||||||
@@ -204,24 +189,19 @@ signature module Semantic<LocationSig Location> {
|
|||||||
predicate isEquality(Expr e1, Expr e2, boolean polarity);
|
predicate isEquality(Expr e1, Expr e2, boolean polarity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if there is a branch edge between two basic blocks. For example
|
* Holds if this guard evaluating to `branch` controls the control-flow
|
||||||
* in the following C code, there are two branch edges from the basic block
|
* branch edge from `bb1` to `bb2`. That is, following the edge from
|
||||||
* containing the condition `(x > y)` to the beginnings of the true and
|
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
|
||||||
* false blocks that follow:
|
|
||||||
* ```
|
|
||||||
* if (x > y) {
|
|
||||||
* printf("x is greater than y\n");
|
|
||||||
* } else {
|
|
||||||
* printf("x is not greater than y\n");
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* `branch` indicates whether the second basic block is the one entered
|
|
||||||
* when the guard evaluates to `true` or when it evaluates to `false`.
|
|
||||||
*/
|
*/
|
||||||
predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch);
|
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch);
|
||||||
}
|
|
||||||
|
|
||||||
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2);
|
/**
|
||||||
|
* Holds if this guard evaluating to `branch` directly or indirectly controls
|
||||||
|
* the block `controlled`. That is, the evaluation of `controlled` is
|
||||||
|
* dominated by this guard evaluating to `branch`.
|
||||||
|
*/
|
||||||
|
predicate controls(BasicBlock controlled, boolean branch);
|
||||||
|
}
|
||||||
|
|
||||||
class Type;
|
class Type;
|
||||||
|
|
||||||
@@ -670,19 +650,14 @@ module RangeStage<
|
|||||||
delta = D::fromFloat(D::toFloat(d1) + d2 + d3)
|
delta = D::fromFloat(D::toFloat(d1) + d2 + d3)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(boolean testIsTrue0 |
|
|
||||||
Sem::implies_v2(result, testIsTrue, boundFlowCond(v, e, delta, upper, testIsTrue0),
|
|
||||||
testIsTrue0)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
result = eqFlowCond(v, e, delta, true, testIsTrue) and
|
result = eqFlowCond(v, e, delta, true, testIsTrue) and
|
||||||
(upper = true or upper = false)
|
(upper = true or upper = false)
|
||||||
or
|
or
|
||||||
// guard that tests whether `v2` is bounded by `e + delta + d1 - d2` and
|
// guard that tests whether `v2` is bounded by `e + delta - d` and
|
||||||
// exists a guard `guardEq` such that `v = v2 - d1 + d2`.
|
// exists a guard `guardEq` such that `v = v2 + d`.
|
||||||
exists(Sem::SsaVariable v2, D::Delta oldDelta, float d |
|
exists(Sem::SsaVariable v2, D::Delta oldDelta, float d |
|
||||||
// equality needs to control guard
|
// equality needs to control guard
|
||||||
result.getBasicBlock() = eqSsaCondDirectlyControls(v, v2, d) and
|
result.getBasicBlock() = eqSsaCondControls(v, v2, d) and
|
||||||
result = boundFlowCond(v2, e, oldDelta, upper, testIsTrue) and
|
result = boundFlowCond(v2, e, oldDelta, upper, testIsTrue) and
|
||||||
delta = D::fromFloat(D::toFloat(oldDelta) + d)
|
delta = D::fromFloat(D::toFloat(oldDelta) + d)
|
||||||
)
|
)
|
||||||
@@ -692,13 +667,11 @@ module RangeStage<
|
|||||||
* Gets a basic block in which `v1` equals `v2 + delta`.
|
* Gets a basic block in which `v1` equals `v2 + delta`.
|
||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private Sem::BasicBlock eqSsaCondDirectlyControls(
|
private Sem::BasicBlock eqSsaCondControls(Sem::SsaVariable v1, Sem::SsaVariable v2, float delta) {
|
||||||
Sem::SsaVariable v1, Sem::SsaVariable v2, float delta
|
|
||||||
) {
|
|
||||||
exists(Sem::Guard guardEq, D::Delta d1, D::Delta d2, boolean eqIsTrue |
|
exists(Sem::Guard guardEq, D::Delta d1, D::Delta d2, boolean eqIsTrue |
|
||||||
guardEq = eqFlowCond(v1, ssaRead(v2, d1), d2, true, eqIsTrue) and
|
guardEq = eqFlowCond(v1, ssaRead(v2, d1), d2, true, eqIsTrue) and
|
||||||
delta = D::toFloat(d2) - D::toFloat(d1) and
|
delta = D::toFloat(d2) - D::toFloat(d1) and
|
||||||
guardEq.directlyControls(result, eqIsTrue)
|
guardEq.controls(result, eqIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,7 +722,7 @@ module RangeStage<
|
|||||||
exists(Sem::Guard guard, boolean testIsTrue |
|
exists(Sem::Guard guard, boolean testIsTrue |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
guard = boundFlowCond(v, e, delta, upper, testIsTrue) and
|
guard = boundFlowCond(v, e, delta, upper, testIsTrue) and
|
||||||
guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
|
guardControlsSsaRead(guard, pos, testIsTrue) and
|
||||||
reason = TSemCondReason(guard)
|
reason = TSemCondReason(guard)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -762,7 +735,7 @@ module RangeStage<
|
|||||||
exists(Sem::Guard guard, boolean testIsTrue |
|
exists(Sem::Guard guard, boolean testIsTrue |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
guard = eqFlowCond(v, e, delta, false, testIsTrue) and
|
guard = eqFlowCond(v, e, delta, false, testIsTrue) and
|
||||||
guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
|
guardControlsSsaRead(guard, pos, testIsTrue) and
|
||||||
reason = TSemCondReason(guard)
|
reason = TSemCondReason(guard)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,6 @@ module MakeUtils<LocationSig Location, Semantic<Location> Lang, DeltaSig D> {
|
|||||||
(testIsTrue = true or testIsTrue = false) and
|
(testIsTrue = true or testIsTrue = false) and
|
||||||
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
|
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
|
||||||
)
|
)
|
||||||
or
|
|
||||||
exists(boolean testIsTrue0 |
|
|
||||||
implies_v2(result, testIsTrue, eqFlowCond(v, e, delta, isEq, testIsTrue0), testIsTrue0)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,29 +169,17 @@ module MakeUtils<LocationSig Location, Semantic<Location> Lang, DeltaSig D> {
|
|||||||
override string toString() { result = "edge" }
|
override string toString() { result = "edge" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` directly controls the position `controlled` with the
|
|
||||||
* value `testIsTrue`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
|
||||||
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
|
||||||
or
|
|
||||||
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
|
||||||
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
|
|
||||||
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
||||||
*/
|
*/
|
||||||
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
|
||||||
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
|
guard.controls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
|
||||||
or
|
or
|
||||||
exists(Guard guard0, boolean testIsTrue0 |
|
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
||||||
implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
|
guard.controls(controlledEdge.getOrigBlock(), testIsTrue) or
|
||||||
guardControlsSsaRead(guard0, controlled, testIsTrue0)
|
guard
|
||||||
|
.controlsBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(),
|
||||||
|
testIsTrue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user