Skip to content

Commit 02f1957

Browse files
committed
C++: make SemBound a RangeAnalysis parameter
1 parent 71b93d1 commit 02f1957

File tree

4 files changed

+59
-25
lines changed

4 files changed

+59
-25
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/ModulusAnalysis.qll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private import ConstantAnalysis
1616
private import RangeUtils
1717
private import RangeAnalysisStage
1818

19-
module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
19+
module ModulusAnalysis<DeltaSig D, BoundSig<D> Bounds, UtilSig<D> U> {
2020
/**
2121
* Holds if `e + delta` equals `v` at `pos`.
2222
*/
@@ -146,7 +146,7 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
146146
private predicate phiSelfModulus(
147147
SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int mod
148148
) {
149-
exists(SemSsaBound phibound, int v, int m |
149+
exists(Bounds::SemSsaBound phibound, int v, int m |
150150
edge.phiInput(phi, inp) and
151151
phibound.getAVariable() = phi and
152152
ssaModulus(inp, edge, phibound, v, m) and
@@ -158,7 +158,7 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
158158
/**
159159
* Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
160160
*/
161-
private predicate phiModulusInit(SemSsaPhiNode phi, SemBound b, int val, int mod) {
161+
private predicate phiModulusInit(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
162162
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge |
163163
edge.phiInput(phi, inp) and
164164
ssaModulus(inp, edge, b, val, mod)
@@ -169,7 +169,7 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
169169
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
170170
*/
171171
pragma[nomagic]
172-
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
172+
private predicate phiModulusRankStep(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod, int rix) {
173173
/*
174174
* base case. If any phi input is equal to `b + val` modulo `mod`, that's a potential congruence
175175
* class for the phi node.
@@ -213,7 +213,7 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
213213
/**
214214
* Holds if `phi` is equal to `b + val` modulo `mod`.
215215
*/
216-
private predicate phiModulus(SemSsaPhiNode phi, SemBound b, int val, int mod) {
216+
private predicate phiModulus(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
217217
exists(int r |
218218
maxPhiInputRank(phi, r) and
219219
phiModulusRankStep(phi, b, val, mod, r)
@@ -224,19 +224,19 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
224224
* Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
225225
*/
226226
private predicate ssaModulus(
227-
SemSsaVariable v, SemSsaReadPosition pos, SemBound b, int val, int mod
227+
SemSsaVariable v, SemSsaReadPosition pos, Bounds::SemBound b, int val, int mod
228228
) {
229229
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
230230
or
231-
b.(SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
231+
b.(Bounds::SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
232232
or
233233
exists(SemExpr e, int val0, int delta |
234234
semExprModulus(e, b, val0, mod) and
235235
valueFlowStepSsa(v, pos, e, delta) and
236236
val = remainder(val0 + delta, mod)
237237
)
238238
or
239-
moduloGuardedRead(v, pos, val, mod) and b instanceof SemZeroBound
239+
moduloGuardedRead(v, pos, val, mod) and b instanceof Bounds::SemZeroBound
240240
}
241241

242242
/**
@@ -247,14 +247,14 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
247247
* - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
248248
*/
249249
cached
250-
predicate semExprModulus(SemExpr e, SemBound b, int val, int mod) {
250+
predicate semExprModulus(SemExpr e, Bounds::SemBound b, int val, int mod) {
251251
not ignoreExprModulus(e) and
252252
(
253-
e = b.getExpr(val) and mod = 0
253+
e = b.getExpr(D::fromInt(val)) and mod = 0
254254
or
255255
evenlyDivisibleExpr(e, mod) and
256256
val = 0 and
257-
b instanceof SemZeroBound
257+
b instanceof Bounds::SemZeroBound
258258
or
259259
exists(SemSsaVariable v, SemSsaReadPositionBlock bb |
260260
ssaModulus(v, bb, b, val, mod) and
@@ -277,21 +277,21 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
277277
val = remainder(v1, mod)
278278
)
279279
or
280-
exists(SemBound b1, SemBound b2, int v1, int v2, int m1, int m2 |
280+
exists(Bounds::SemBound b1, Bounds::SemBound b2, int v1, int v2, int m1, int m2 |
281281
addModulus(e, true, b1, v1, m1) and
282282
addModulus(e, false, b2, v2, m2) and
283283
mod = m1.gcd(m2) and
284284
mod != 1 and
285285
val = remainder(v1 + v2, mod)
286286
|
287-
b = b1 and b2 instanceof SemZeroBound
287+
b = b1 and b2 instanceof Bounds::SemZeroBound
288288
or
289-
b = b2 and b1 instanceof SemZeroBound
289+
b = b2 and b1 instanceof Bounds::SemZeroBound
290290
)
291291
or
292292
exists(int v1, int v2, int m1, int m2 |
293293
subModulus(e, true, b, v1, m1) and
294-
subModulus(e, false, any(SemZeroBound zb), v2, m2) and
294+
subModulus(e, false, any(Bounds::SemZeroBound zb), v2, m2) and
295295
mod = m1.gcd(m2) and
296296
mod != 1 and
297297
val = remainder(v1 - v2, mod)
@@ -300,20 +300,20 @@ module ModulusAnalysis<DeltaSig D, UtilSig<D> U> {
300300
}
301301

302302
private predicate condExprBranchModulus(
303-
SemConditionalExpr cond, boolean branch, SemBound b, int val, int mod
303+
SemConditionalExpr cond, boolean branch, Bounds::SemBound b, int val, int mod
304304
) {
305305
semExprModulus(cond.getBranchExpr(branch), b, val, mod)
306306
}
307307

308-
private predicate addModulus(SemExpr add, boolean isLeft, SemBound b, int val, int mod) {
308+
private predicate addModulus(SemExpr add, boolean isLeft, Bounds::SemBound b, int val, int mod) {
309309
exists(SemExpr larg, SemExpr rarg | nonConstAddition(add, larg, rarg) |
310310
semExprModulus(larg, b, val, mod) and isLeft = true
311311
or
312312
semExprModulus(rarg, b, val, mod) and isLeft = false
313313
)
314314
}
315315

316-
private predicate subModulus(SemExpr sub, boolean isLeft, SemBound b, int val, int mod) {
316+
private predicate subModulus(SemExpr sub, boolean isLeft, Bounds::SemBound b, int val, int mod) {
317317
exists(SemExpr larg, SemExpr rarg | nonConstSubtraction(sub, larg, rarg) |
318318
semExprModulus(larg, b, val, mod) and isLeft = true
319319
or

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysis.qll

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@ private import RangeAnalysisStage
22
private import RangeAnalysisSpecific
33
private import FloatDelta
44
private import RangeUtils
5+
private import experimental.semmle.code.cpp.semantic.SemanticBound as SemanticBound
56

6-
private module CppRangeAnalysis = RangeStage<FloatDelta, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
7-
import CppRangeAnalysis
7+
module Bounds implements BoundSig<FloatDelta> {
8+
class SemBound instanceof SemanticBound::SemBound {
9+
string toString() { result = super.toString() }
10+
11+
SemExpr getExpr(float delta) { result = super.getExpr(delta) }
12+
}
13+
14+
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
15+
16+
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
17+
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
18+
}
19+
}
20+
21+
private module CppRangeAnalysis =
22+
RangeStage<FloatDelta, Bounds, CppLangImpl, RangeUtil<FloatDelta, CppLangImpl>>;
23+
24+
import CppRangeAnalysis

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisSpecific.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,4 @@ module CppLangImpl implements LangSig<FloatDelta> {
8989
* actually references but whose values can be tracked as the type contained in the box.
9090
*/
9191
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
92-
}
92+
}

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@
6666
private import RangeUtils as Utils
6767
private import SignAnalysisCommon
6868
private import ModulusAnalysis
69-
private import experimental.semmle.code.cpp.semantic.Semantic
69+
import experimental.semmle.code.cpp.semantic.SemanticExpr
70+
import experimental.semmle.code.cpp.semantic.SemanticSSA
71+
import experimental.semmle.code.cpp.semantic.SemanticGuard
72+
import experimental.semmle.code.cpp.semantic.SemanticCFG
73+
import experimental.semmle.code.cpp.semantic.SemanticType
74+
import experimental.semmle.code.cpp.semantic.SemanticOpcode
7075
private import ConstantAnalysis
7176

7277
/**
@@ -222,7 +227,19 @@ signature module UtilSig<DeltaSig DeltaParam> {
222227
SemType getTrackedType(SemExpr e);
223228
}
224229

225-
module RangeStage<DeltaSig D, LangSig<D> LangParam, UtilSig<D> UtilParam> {
230+
signature module BoundSig<DeltaSig D> {
231+
class SemBound {
232+
SemExpr getExpr(D::Delta delta);
233+
}
234+
class SemZeroBound extends SemBound;
235+
class SemSsaBound extends SemBound {
236+
SemSsaVariable getAVariable();
237+
}
238+
}
239+
240+
module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<D> UtilParam> {
241+
import Bounds // TODO: remove this import?
242+
226243
/**
227244
* An expression that does conversion, boxing, or unboxing
228245
*/
@@ -270,7 +287,7 @@ module RangeStage<DeltaSig D, LangSig<D> LangParam, UtilSig<D> UtilParam> {
270287

271288
private import SignAnalysisInstantiated
272289

273-
private module ModulusAnalysisInstantiated = ModulusAnalysis<D, UtilParam>; // TODO: will this cause reevaluation if it's instantiated with the same DeltaSig and UtilParam multiple times?
290+
private module ModulusAnalysisInstantiated = ModulusAnalysis<D, Bounds, UtilParam>; // TODO: will this cause reevaluation if it's instantiated with the same DeltaSig and UtilParam multiple times?
274291

275292
private import ModulusAnalysisInstantiated
276293

@@ -906,7 +923,7 @@ module RangeStage<DeltaSig D, LangSig<D> LangParam, UtilSig<D> UtilParam> {
906923
) {
907924
not Specific::ignoreExprBound(e) and
908925
(
909-
e = b.getExpr(delta) and
926+
e = b.getExpr(D::fromFloat(delta)) and
910927
(upper = true or upper = false) and
911928
fromBackEdge = false and
912929
origdelta = delta and

0 commit comments

Comments
 (0)