ModulusAnalysis shared between C# and Java

This commit is contained in:
Tamas Vajk
2020-10-06 09:36:42 +02:00
parent d2d8d009eb
commit 4df6a41616
10 changed files with 879 additions and 52 deletions

View File

@@ -4,12 +4,9 @@
* variable), and `v` is an integer in the range `[0 .. m-1]`.
*/
import java
private import SSA
private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon
private import RangeUtils
private import semmle.code.java.controlflow.Guards
import Bound
private import internal.rangeanalysis.ModulusAnalysisSpecific::Private
private import Bound
private import internal.rangeanalysis.SsaReadPositionCommon
/**
* Holds if `e + delta` equals `v` at `pos`.
@@ -29,16 +26,9 @@ private predicate valueFlowStepSsa(SsaVariable v, SsaReadPosition pos, Expr e, i
* `ConstantIntegerExpr`s.
*/
private predicate nonConstAddition(Expr add, Expr larg, Expr rarg) {
(
exists(AddExpr a | a = add |
larg = a.getLeftOperand() and
rarg = a.getRightOperand()
)
or
exists(AssignAddExpr a | a = add |
larg = a.getDest() and
rarg = a.getRhs()
)
exists(AddExpr a | a = add |
larg = a.getLhs() and
rarg = a.getRhs()
) and
not larg instanceof ConstantIntegerExpr and
not rarg instanceof ConstantIntegerExpr
@@ -49,16 +39,9 @@ private predicate nonConstAddition(Expr add, Expr larg, Expr rarg) {
* a `ConstantIntegerExpr`.
*/
private predicate nonConstSubtraction(Expr sub, Expr larg, Expr rarg) {
(
exists(SubExpr s | s = sub |
larg = s.getLeftOperand() and
rarg = s.getRightOperand()
)
or
exists(AssignSubExpr s | s = sub |
larg = s.getDest() and
rarg = s.getRhs()
)
exists(SubExpr s | s = sub |
larg = s.getLhs() and
rarg = s.getRhs()
) and
not rarg instanceof ConstantIntegerExpr
}
@@ -75,7 +58,7 @@ private Expr modExpr(Expr arg, int mod) {
exists(ConstantIntegerExpr c |
mod = 2.pow([1 .. 30]) and
c.getIntValue() = mod - 1 and
result.(AndBitwiseExpr).hasOperands(arg, c)
result.(BitwiseAndExpr).hasOperands(arg, c)
)
}
@@ -122,24 +105,12 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
exists(ConstantIntegerExpr c, int k | k = c.getIntValue() |
e.(MulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
or
e.(AssignMulExpr).getSource() = c and factor = k.abs() and factor >= 2
e.(LShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
or
e.(LShiftExpr).getRightOperand() = c and factor = 2.pow(k) and k > 0
or
e.(AssignLShiftExpr).getRhs() = c and factor = 2.pow(k) and k > 0
or
e.(AndBitwiseExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
or
e.(AssignAndExpr).getSource() = c and factor = max(int f | andmaskFactor(k, f))
e.(BitwiseAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
)
}
private predicate id(BasicBlock x, BasicBlock y) { x = y }
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
private int getId(BasicBlock bb) { idOf(bb, result) }
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
@@ -267,7 +238,7 @@ predicate exprModulus(Expr e, Bound b, int val, int mod) {
exists(SsaVariable v, SsaReadPositionBlock bb |
ssaModulus(v, bb, b, val, mod) and
e = v.getAUse() and
bb.getBlock() = e.getBasicBlock()
getABasicBlockExpr(bb.getBlock()) = e
)
or
exists(Expr mid, int val0, int delta |

View File

@@ -0,0 +1,119 @@
module Private {
private import java as J
private import semmle.code.java.dataflow.SSA as Ssa
private import semmle.code.java.dataflow.RangeUtils as RU
private import semmle.code.java.controlflow.Guards as G
private import semmle.code.java.controlflow.BasicBlocks as BB
class BasicBlock = BB::BasicBlock;
class SsaVariable = Ssa::SsaVariable;
class SsaPhiNode = Ssa::SsaPhiNode;
class Expr = J::Expr;
class Guard = G::Guard;
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
class ConditionalExpr = J::ConditionalExpr;
/** An addition or an assign-add expression. */
class AddExpr extends J::Expr {
AddExpr() { this instanceof J::AddExpr or this instanceof J::AssignAddExpr }
/** Gets the LHS operand of this add expression. */
Expr getLhs() {
result = this.(J::AddExpr).getLeftOperand()
or
result = this.(J::AssignAddExpr).getDest()
}
/** Gets the RHS operand of this add expression. */
Expr getRhs() {
result = this.(J::AddExpr).getRightOperand()
or
result = this.(J::AssignAddExpr).getRhs()
}
}
/** A subtraction or an assign-sub expression. */
class SubExpr extends J::Expr {
SubExpr() { this instanceof J::SubExpr or this instanceof J::AssignSubExpr }
/** Gets the LHS operand of this subtraction expression. */
Expr getLhs() {
result = this.(J::SubExpr).getLeftOperand()
or
result = this.(J::AssignSubExpr).getDest()
}
/** Gets the RHS operand of this subtraction expression. */
Expr getRhs() {
result = this.(J::SubExpr).getRightOperand()
or
result = this.(J::AssignSubExpr).getRhs()
}
}
class RemExpr = J::RemExpr;
/** A multiplication or an assign-mul expression. */
class MulExpr extends J::Expr {
MulExpr() { this instanceof J::MulExpr or this instanceof J::AssignMulExpr }
/** Gets an operand of this multiplication. */
Expr getAnOperand() {
result = this.(J::MulExpr).getAnOperand() or
result = this.(J::AssignMulExpr).getSource()
}
}
/** A left shift or an assign-lshift expression. */
class LShiftExpr extends J::Expr {
LShiftExpr() { this instanceof J::LShiftExpr or this instanceof J::AssignLShiftExpr }
/** Gets the RHS operand of this shift. */
Expr getRhs() {
result = this.(J::LShiftExpr).getRightOperand() or
result = this.(J::AssignLShiftExpr).getRhs()
}
}
/** A bitwise and or an assign-and expression. */
class BitwiseAndExpr extends J::Expr {
BitwiseAndExpr() { this instanceof J::AndBitwiseExpr or this instanceof J::AssignAndExpr }
/** Gets an operand of this bitwise and operation. */
Expr getAnOperand() {
result = this.(J::AndBitwiseExpr).getAnOperand() or
result = this.(J::AssignAndExpr).getSource()
}
/** Holds if this expression has operands `e1` and `e2`. */
predicate hasOperands(Expr e1, Expr e2) {
this.getAnOperand() = e1 and
this.getAnOperand() = e2 and
e1 != e2
}
}
predicate guardDirectlyControlsSsaRead = RU::guardDirectlyControlsSsaRead/3;
predicate guardControlsSsaRead = RU::guardControlsSsaRead/3;
predicate valueFlowStep = RU::valueFlowStep/3;
predicate eqFlowCond = RU::eqFlowCond/5;
predicate ssaUpdateStep = RU::ssaUpdateStep/3;
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() }
private predicate id(BasicBlock x, BasicBlock y) { x = y }
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
int getId(BasicBlock bb) { idOf(bb, result) }
}