Skip to content

Commit 78d7e25

Browse files
committed
ModulusAnalysis shared between C# and Java
1 parent 5efd675 commit 78d7e25

File tree

14 files changed

+1058
-437
lines changed

14 files changed

+1058
-437
lines changed

config/identical-files.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/BoundCommon.qll",
6767
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundCommon.qll"
6868
],
69+
"ModulusAnalysis Java/C#": [
70+
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/ModulusAnalysisCommon.qll",
71+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisCommon.qll"
72+
],
6973
"C++ SubBasicBlocks": [
7074
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
7175
"cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Provides inferences of the form: `e` equals `b + v` modulo `m` where `e` is
3+
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
4+
* variable), and `v` is an integer in the range `[0 .. m-1]`.
5+
*/
6+
7+
import semmle.code.csharp.dataflow.internal.rangeanalysis.ModulusAnalysisCommon

csharp/ql/src/semmle/code/csharp/dataflow/RangeAnalysis.qll

Lines changed: 5 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import csharp
22
import Ssa
3-
import Bound
4-
import SignAnalysis
3+
import semmle.code.csharp.dataflow.internal.rangeanalysis.BoundCommon
4+
import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisCommon
55
import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaReadPositionCommon
66
import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils
77
import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils
8-
import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisSpecific::Private as SignPrivate
8+
import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils
99
import semmle.code.csharp.controlflow.Guards as G
1010
import semmle.code.csharp.commons.ComparisonTest
1111

@@ -61,29 +61,6 @@ private predicate boundCondition(
6161
// todo: other cases: // (v - d) - e < c, ...
6262
}
6363

64-
/**
65-
* Gets a condition that tests whether `v` equals `e + delta`.
66-
*
67-
* If the condition evaluates to `testIsTrue`:
68-
* - `isEq = true` : `v == e + delta`
69-
* - `isEq = false` : `v != e + delta`
70-
*/
71-
G::Guard eqFlowCond(Definition v, Expr e, int delta, boolean isEq, boolean testIsTrue) {
72-
exists(boolean eqpolarity |
73-
result.isEquality(ssaRead(v, delta), e, eqpolarity) and
74-
(testIsTrue = true or testIsTrue = false) and
75-
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
76-
)
77-
or
78-
exists(
79-
boolean testIsTrue0, G::AbstractValues::BooleanValue b0, G::AbstractValues::BooleanValue b1
80-
|
81-
b1.getValue() = testIsTrue and b0.getValue() = testIsTrue0
82-
|
83-
G::Internal::impliesSteps(result, b1, eqFlowCond(v, e, delta, isEq, testIsTrue0), b0)
84-
)
85-
}
86-
8764
/**
8865
* Gets a condition that tests whether `v` is bounded by `e + delta`.
8966
*
@@ -149,27 +126,10 @@ private predicate boundFlowStepSsa(
149126
exists(G::Guard guard, boolean testIsTrue |
150127
pos.hasReadOfVar(v) and
151128
guard = boundFlowCond(v, e, delta, upper, testIsTrue) and
152-
SignPrivate::guardControlsSsaRead(guard, pos, testIsTrue)
129+
guardControlsSsaRead(guard, pos, testIsTrue)
153130
)
154131
}
155132

156-
/**
157-
* Holds if `v` is an `ExplicitDefinition` that equals `e + delta`.
158-
*/
159-
predicate ssaUpdateStep(ExplicitDefinition v, Expr e, int delta) {
160-
v.getADefinition().getExpr().(Assignment).getRValue() = e and delta = 0
161-
or
162-
v.getADefinition().getExpr().(PostIncrExpr).getOperand() = e and delta = 1
163-
or
164-
v.getADefinition().getExpr().(PreIncrExpr).getOperand() = e and delta = 1
165-
or
166-
v.getADefinition().getExpr().(PostDecrExpr).getOperand() = e and delta = -1
167-
or
168-
v.getADefinition().getExpr().(PreDecrExpr).getOperand() = e and delta = -1
169-
or
170-
v.getADefinition().getExpr().(AssignOperation) = e and delta = 0
171-
}
172-
173133
/**
174134
* Holds if `b + delta` is a valid bound for `e`.
175135
* - `upper = true` : `e <= b + delta`
@@ -237,59 +197,6 @@ private predicate bounded(
237197
)
238198
}
239199

240-
/**
241-
* Holds if `e1 + delta` equals `e2`.
242-
*/
243-
predicate valueFlowStep(Expr e2, Expr e1, int delta) {
244-
e2.(AssignExpr).getRValue() = e1 and delta = 0
245-
or
246-
e2.(UnaryPlusExpr).getOperand() = e1 and delta = 0
247-
or
248-
e2.(PostIncrExpr).getOperand() = e1 and delta = 0
249-
or
250-
e2.(PostDecrExpr).getOperand() = e1 and delta = 0
251-
or
252-
e2.(PreIncrExpr).getOperand() = e1 and delta = 1
253-
or
254-
e2.(PreDecrExpr).getOperand() = e1 and delta = -1
255-
or
256-
// exists(ArrayCreationExpr a |
257-
// arrayLengthDef(e2, a) and
258-
// a.getDimension(0) = e1 and
259-
// delta = 0
260-
// )
261-
// or
262-
exists(Expr x |
263-
e2.(AddExpr).getAnOperand() = e1 and
264-
e2.(AddExpr).getAnOperand() = x and
265-
not e1 = x
266-
or
267-
exists(AssignAddExpr add | add = e2 |
268-
add.getLValue() = e1 and add.getRValue() = x
269-
or
270-
add.getLValue() = x and add.getRValue() = e1
271-
)
272-
|
273-
x.(ConstantIntegerExpr).getIntValue() = delta
274-
)
275-
or
276-
exists(Expr x |
277-
exists(SubExpr sub |
278-
e2 = sub and
279-
sub.getLeftOperand() = e1 and
280-
sub.getRightOperand() = x
281-
)
282-
or
283-
exists(AssignSubExpr sub |
284-
e2 = sub and
285-
sub.getLValue() = e1 and
286-
sub.getRValue() = x
287-
)
288-
|
289-
x.(ConstantIntegerExpr).getIntValue() = -delta
290-
)
291-
}
292-
293200
/**
294201
* Holds if `e1 + delta` is a valid bound for `e2`.
295202
* - `upper = true` : `e2 <= e1 + delta`
@@ -465,7 +372,7 @@ private predicate unequalFlowStepIntegralSsa(Definition v, SsaReadPosition pos,
465372
exists(G::Guard guard, boolean testIsTrue |
466373
pos.hasReadOfVar(v) and
467374
guard = eqFlowCond(v, e, delta, false, testIsTrue) and
468-
SignPrivate::guardControlsSsaRead(guard, pos, testIsTrue)
375+
guardControlsSsaRead(guard, pos, testIsTrue)
469376
)
470377
}
471378

csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ class IntegralType = CS::IntegralType;
1818
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
1919

2020
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
21-
predicate nonSsaVariableBoundedExpr(Expr e) { CU::systemArrayLengthAccess(e.(CS::PropertyRead)) }
21+
predicate nonSsaVariableBoundedExpr(Expr e) {
22+
CU::systemArrayLengthAccess(e.(CS::PropertyRead)) and
23+
not exists(SsaVariable v | e = v.getAUse())
24+
}

0 commit comments

Comments
 (0)