10
10
* handles phi inputs.
11
11
*/
12
12
13
- private import ModulusAnalysisSpecific:: Private
14
- private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
15
- private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
16
- private import ConstantAnalysis
17
- private import RangeUtils
18
- private import codeql.rangeanalysis.RangeAnalysis
19
- private import RangeAnalysisImpl
13
+ private import codeql.util.Location
14
+ private import RangeAnalysis
20
15
21
- module ModulusAnalysis< DeltaSig D, BoundSig< SemLocation , Sem , D > Bounds, UtilSig< Sem , D > U> {
16
+ module ModulusAnalysis<
17
+ LocationSig Location, Semantic Sem, DeltaSig D, BoundSig< Location , Sem , D > Bounds,
18
+ UtilSig< Sem , D > U>
19
+ {
22
20
pragma [ nomagic]
23
21
private predicate valueFlowStepSsaEqFlowCond (
24
- SemSsaReadPosition pos , SemSsaVariable v , SemExpr e , int delta
22
+ Sem :: SsaReadPosition pos , Sem :: SsaVariable v , Sem :: Expr e , int delta
25
23
) {
26
- exists ( SemGuard guard , boolean testIsTrue |
24
+ exists ( Sem :: Guard guard , boolean testIsTrue |
27
25
guard = U:: semEqFlowCond ( v , e , D:: fromInt ( delta ) , true , testIsTrue ) and
28
- semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue )
26
+ Sem :: guardDirectlyControlsSsaRead ( guard , pos , testIsTrue )
29
27
)
30
28
}
31
29
32
30
/**
33
31
* Holds if `e + delta` equals `v` at `pos`.
34
32
*/
35
33
pragma [ nomagic]
36
- private predicate valueFlowStepSsa ( SemSsaVariable v , SemSsaReadPosition pos , SemExpr e , int delta ) {
34
+ private predicate valueFlowStepSsa (
35
+ Sem:: SsaVariable v , Sem:: SsaReadPosition pos , Sem:: Expr e , int delta
36
+ ) {
37
37
U:: semSsaUpdateStep ( v , e , D:: fromInt ( delta ) ) and pos .hasReadOfVar ( v )
38
38
or
39
39
pos .hasReadOfVar ( v ) and
@@ -44,49 +44,49 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
44
44
* Holds if `add` is the addition of `larg` and `rarg`, neither of which are
45
45
* `ConstantIntegerExpr`s.
46
46
*/
47
- private predicate nonConstAddition ( SemExpr add , SemExpr larg , SemExpr rarg ) {
48
- exists ( SemAddExpr a | a = add |
47
+ private predicate nonConstAddition ( Sem :: Expr add , Sem :: Expr larg , Sem :: Expr rarg ) {
48
+ exists ( Sem :: AddExpr a | a = add |
49
49
larg = a .getLeftOperand ( ) and
50
50
rarg = a .getRightOperand ( )
51
51
) and
52
- not larg instanceof SemConstantIntegerExpr and
53
- not rarg instanceof SemConstantIntegerExpr
52
+ not larg instanceof Sem :: ConstantIntegerExpr and
53
+ not rarg instanceof Sem :: ConstantIntegerExpr
54
54
}
55
55
56
56
/**
57
57
* Holds if `sub` is the subtraction of `larg` and `rarg`, where `rarg` is not
58
58
* a `ConstantIntegerExpr`.
59
59
*/
60
- private predicate nonConstSubtraction ( SemExpr sub , SemExpr larg , SemExpr rarg ) {
61
- exists ( SemSubExpr s | s = sub |
60
+ private predicate nonConstSubtraction ( Sem :: Expr sub , Sem :: Expr larg , Sem :: Expr rarg ) {
61
+ exists ( Sem :: SubExpr s | s = sub |
62
62
larg = s .getLeftOperand ( ) and
63
63
rarg = s .getRightOperand ( )
64
64
) and
65
- not rarg instanceof SemConstantIntegerExpr
65
+ not rarg instanceof Sem :: ConstantIntegerExpr
66
66
}
67
67
68
68
/** Gets an expression that is the remainder modulo `mod` of `arg`. */
69
- private SemExpr modExpr ( SemExpr arg , int mod ) {
70
- exists ( SemRemExpr rem |
69
+ private Sem :: Expr modExpr ( Sem :: Expr arg , int mod ) {
70
+ exists ( Sem :: RemExpr rem |
71
71
result = rem and
72
72
arg = rem .getLeftOperand ( ) and
73
- rem .getRightOperand ( ) .( SemConstantIntegerExpr ) .getIntValue ( ) = mod and
73
+ rem .getRightOperand ( ) .( Sem :: ConstantIntegerExpr ) .getIntValue ( ) = mod and
74
74
mod >= 2
75
75
)
76
76
or
77
- exists ( SemConstantIntegerExpr c |
77
+ exists ( Sem :: ConstantIntegerExpr c |
78
78
mod = 2 .pow ( [ 1 .. 30 ] ) and
79
79
c .getIntValue ( ) = mod - 1 and
80
- result .( SemBitAndExpr ) .hasOperands ( arg , c )
80
+ result .( Sem :: BitAndExpr ) .hasOperands ( arg , c )
81
81
)
82
82
}
83
83
84
84
/**
85
85
* Gets a guard that tests whether `v` is congruent with `val` modulo `mod` on
86
86
* its `testIsTrue` branch.
87
87
*/
88
- private SemGuard moduloCheck ( SemSsaVariable v , int val , int mod , boolean testIsTrue ) {
89
- exists ( SemExpr rem , SemConstantIntegerExpr c , int r , boolean polarity |
88
+ private Sem :: Guard moduloCheck ( Sem :: SsaVariable v , int val , int mod , boolean testIsTrue ) {
89
+ exists ( Sem :: Expr rem , Sem :: ConstantIntegerExpr c , int r , boolean polarity |
90
90
result .isEquality ( rem , c , polarity ) and
91
91
c .getIntValue ( ) = r and
92
92
rem = modExpr ( v .getAUse ( ) , mod ) and
@@ -104,11 +104,11 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
104
104
/**
105
105
* Holds if a guard ensures that `v` at `pos` is congruent with `val` modulo `mod`.
106
106
*/
107
- private predicate moduloGuardedRead ( SemSsaVariable v , SemSsaReadPosition pos , int val , int mod ) {
108
- exists ( SemGuard guard , boolean testIsTrue |
107
+ private predicate moduloGuardedRead ( Sem :: SsaVariable v , Sem :: SsaReadPosition pos , int val , int mod ) {
108
+ exists ( Sem :: Guard guard , boolean testIsTrue |
109
109
pos .hasReadOfVar ( v ) and
110
110
guard = moduloCheck ( v , val , mod , testIsTrue ) and
111
- semGuardControlsSsaRead ( guard , pos , testIsTrue )
111
+ Sem :: guardControlsSsaRead ( guard , pos , testIsTrue )
112
112
)
113
113
}
114
114
@@ -120,13 +120,13 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
120
120
}
121
121
122
122
/** Holds if `e` is evenly divisible by `factor`. */
123
- private predicate evenlyDivisibleExpr ( SemExpr e , int factor ) {
124
- exists ( SemConstantIntegerExpr c , int k | k = c .getIntValue ( ) |
125
- e .( SemMulExpr ) .getAnOperand ( ) = c and factor = k .abs ( ) and factor >= 2
123
+ private predicate evenlyDivisibleExpr ( Sem :: Expr e , int factor ) {
124
+ exists ( Sem :: ConstantIntegerExpr c , int k | k = c .getIntValue ( ) |
125
+ e .( Sem :: MulExpr ) .getAnOperand ( ) = c and factor = k .abs ( ) and factor >= 2
126
126
or
127
- e .( SemShiftLeftExpr ) .getRightOperand ( ) = c and factor = 2 .pow ( k ) and k > 0
127
+ e .( Sem :: ShiftLeftExpr ) .getRightOperand ( ) = c and factor = 2 .pow ( k ) and k > 0
128
128
or
129
- e .( SemBitAndExpr ) .getAnOperand ( ) = c and factor = max ( int f | andmaskFactor ( k , f ) )
129
+ e .( Sem :: BitAndExpr ) .getAnOperand ( ) = c and factor = max ( int f | andmaskFactor ( k , f ) )
130
130
)
131
131
}
132
132
@@ -147,7 +147,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
147
147
* Holds if `inp` is an input to `phi` and equals `phi` modulo `mod` along `edge`.
148
148
*/
149
149
private predicate phiSelfModulus (
150
- SemSsaPhiNode phi , SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge , int mod
150
+ Sem :: SsaPhiNode phi , Sem :: SsaVariable inp , Sem :: SsaReadPositionPhiInputEdge edge , int mod
151
151
) {
152
152
exists ( Bounds:: SemSsaBound phibound , int v , int m |
153
153
edge .phiInput ( phi , inp ) and
@@ -161,8 +161,8 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
161
161
/**
162
162
* Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
163
163
*/
164
- private predicate phiModulusInit ( SemSsaPhiNode phi , Bounds:: SemBound b , int val , int mod ) {
165
- exists ( SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge |
164
+ private predicate phiModulusInit ( Sem :: SsaPhiNode phi , Bounds:: SemBound b , int val , int mod ) {
165
+ exists ( Sem :: SsaVariable inp , Sem :: SsaReadPositionPhiInputEdge edge |
166
166
edge .phiInput ( phi , inp ) and
167
167
ssaModulus ( inp , edge , b , val , mod )
168
168
)
@@ -173,7 +173,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
173
173
*/
174
174
pragma [ nomagic]
175
175
private predicate phiModulusRankStep (
176
- SemSsaPhiNode phi , Bounds:: SemBound b , int val , int mod , int rix
176
+ Sem :: SsaPhiNode phi , Bounds:: SemBound b , int val , int mod , int rix
177
177
) {
178
178
/*
179
179
* base case. If any phi input is equal to `b + val` modulo `mod`, that's a potential congruence
@@ -183,7 +183,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
183
183
rix = 0 and
184
184
phiModulusInit ( phi , b , val , mod )
185
185
or
186
- exists ( SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge , int v1 , int m1 |
186
+ exists ( Sem :: SsaVariable inp , Sem :: SsaReadPositionPhiInputEdge edge , int v1 , int m1 |
187
187
mod != 1 and
188
188
val = remainder ( v1 , mod )
189
189
|
@@ -194,7 +194,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
194
194
*/
195
195
196
196
exists ( int v2 , int m2 |
197
- rankedPhiInput ( pragma [ only_bind_out ] ( phi ) , inp , edge , rix ) and
197
+ U :: rankedPhiInput ( pragma [ only_bind_out ] ( phi ) , inp , edge , rix ) and
198
198
phiModulusRankStep ( phi , b , v1 , m1 , rix - 1 ) and
199
199
ssaModulus ( inp , edge , b , v2 , m2 ) and
200
200
mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 )
@@ -207,7 +207,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
207
207
*/
208
208
209
209
exists ( int m2 |
210
- rankedPhiInput ( phi , inp , edge , rix ) and
210
+ U :: rankedPhiInput ( phi , inp , edge , rix ) and
211
211
phiModulusRankStep ( phi , b , v1 , m1 , rix - 1 ) and
212
212
phiSelfModulus ( phi , inp , edge , m2 ) and
213
213
mod = m1 .gcd ( m2 )
@@ -218,9 +218,9 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
218
218
/**
219
219
* Holds if `phi` is equal to `b + val` modulo `mod`.
220
220
*/
221
- private predicate phiModulus ( SemSsaPhiNode phi , Bounds:: SemBound b , int val , int mod ) {
221
+ private predicate phiModulus ( Sem :: SsaPhiNode phi , Bounds:: SemBound b , int val , int mod ) {
222
222
exists ( int r |
223
- maxPhiInputRank ( phi , r ) and
223
+ U :: maxPhiInputRank ( phi , r ) and
224
224
phiModulusRankStep ( phi , b , val , mod , r )
225
225
)
226
226
}
@@ -229,13 +229,13 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
229
229
* Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
230
230
*/
231
231
private predicate ssaModulus (
232
- SemSsaVariable v , SemSsaReadPosition pos , Bounds:: SemBound b , int val , int mod
232
+ Sem :: SsaVariable v , Sem :: SsaReadPosition pos , Bounds:: SemBound b , int val , int mod
233
233
) {
234
234
phiModulus ( v , b , val , mod ) and pos .hasReadOfVar ( v )
235
235
or
236
236
b .( Bounds:: SemSsaBound ) .getVariable ( ) = v and pos .hasReadOfVar ( v ) and val = 0 and mod = 0
237
237
or
238
- exists ( SemExpr e , int val0 , int delta |
238
+ exists ( Sem :: Expr e , int val0 , int delta |
239
239
semExprModulus ( e , b , val0 , mod ) and
240
240
valueFlowStepSsa ( v , pos , e , delta ) and
241
241
val = remainder ( val0 + delta , mod )
@@ -252,74 +252,71 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
252
252
* - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
253
253
*/
254
254
cached
255
- predicate semExprModulus ( SemExpr e , Bounds:: SemBound b , int val , int mod ) {
256
- not ignoreExprModulus ( e ) and
257
- (
258
- e = b .getExpr ( D:: fromInt ( val ) ) and mod = 0
259
- or
260
- evenlyDivisibleExpr ( e , mod ) and
261
- val = 0 and
262
- b instanceof Bounds:: SemZeroBound
263
- or
264
- exists ( SemSsaVariable v , SemSsaReadPositionBlock bb |
265
- ssaModulus ( v , bb , b , val , mod ) and
266
- e = v .getAUse ( ) and
267
- bb .getAnExpr ( ) = e
268
- )
269
- or
270
- exists ( SemExpr mid , int val0 , int delta |
271
- semExprModulus ( mid , b , val0 , mod ) and
272
- U:: semValueFlowStep ( e , mid , D:: fromInt ( delta ) ) and
273
- val = remainder ( val0 + delta , mod )
274
- )
275
- or
276
- exists ( SemConditionalExpr cond , int v1 , int v2 , int m1 , int m2 |
277
- cond = e and
278
- condExprBranchModulus ( cond , true , b , v1 , m1 ) and
279
- condExprBranchModulus ( cond , false , b , v2 , m2 ) and
280
- mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 ) and
281
- mod != 1 and
282
- val = remainder ( v1 , mod )
283
- )
284
- or
285
- exists ( Bounds:: SemBound b1 , Bounds:: SemBound b2 , int v1 , int v2 , int m1 , int m2 |
286
- addModulus ( e , true , b1 , v1 , m1 ) and
287
- addModulus ( e , false , b2 , v2 , m2 ) and
288
- mod = m1 .gcd ( m2 ) and
289
- mod != 1 and
290
- val = remainder ( v1 + v2 , mod )
291
- |
292
- b = b1 and b2 instanceof Bounds:: SemZeroBound
293
- or
294
- b = b2 and b1 instanceof Bounds:: SemZeroBound
295
- )
255
+ predicate semExprModulus ( Sem:: Expr e , Bounds:: SemBound b , int val , int mod ) {
256
+ e = b .getExpr ( D:: fromInt ( val ) ) and mod = 0
257
+ or
258
+ evenlyDivisibleExpr ( e , mod ) and
259
+ val = 0 and
260
+ b instanceof Bounds:: SemZeroBound
261
+ or
262
+ exists ( Sem:: SsaVariable v , Sem:: SsaReadPositionBlock bb |
263
+ ssaModulus ( v , bb , b , val , mod ) and
264
+ e = v .getAUse ( ) and
265
+ bb .getBlock ( ) = e .getBasicBlock ( )
266
+ )
267
+ or
268
+ exists ( Sem:: Expr mid , int val0 , int delta |
269
+ semExprModulus ( mid , b , val0 , mod ) and
270
+ U:: semValueFlowStep ( e , mid , D:: fromInt ( delta ) ) and
271
+ val = remainder ( val0 + delta , mod )
272
+ )
273
+ or
274
+ exists ( Sem:: ConditionalExpr cond , int v1 , int v2 , int m1 , int m2 |
275
+ cond = e and
276
+ condExprBranchModulus ( cond , true , b , v1 , m1 ) and
277
+ condExprBranchModulus ( cond , false , b , v2 , m2 ) and
278
+ mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 ) and
279
+ mod != 1 and
280
+ val = remainder ( v1 , mod )
281
+ )
282
+ or
283
+ exists ( Bounds:: SemBound b1 , Bounds:: SemBound b2 , int v1 , int v2 , int m1 , int m2 |
284
+ addModulus ( e , true , b1 , v1 , m1 ) and
285
+ addModulus ( e , false , b2 , v2 , m2 ) and
286
+ mod = m1 .gcd ( m2 ) and
287
+ mod != 1 and
288
+ val = remainder ( v1 + v2 , mod )
289
+ |
290
+ b = b1 and b2 instanceof Bounds:: SemZeroBound
296
291
or
297
- exists ( int v1 , int v2 , int m1 , int m2 |
298
- subModulus ( e , true , b , v1 , m1 ) and
299
- subModulus ( e , false , any ( Bounds:: SemZeroBound zb ) , v2 , m2 ) and
300
- mod = m1 .gcd ( m2 ) and
301
- mod != 1 and
302
- val = remainder ( v1 - v2 , mod )
303
- )
292
+ b = b2 and b1 instanceof Bounds:: SemZeroBound
293
+ )
294
+ or
295
+ exists ( int v1 , int v2 , int m1 , int m2 |
296
+ subModulus ( e , true , b , v1 , m1 ) and
297
+ subModulus ( e , false , any ( Bounds:: SemZeroBound zb ) , v2 , m2 ) and
298
+ mod = m1 .gcd ( m2 ) and
299
+ mod != 1 and
300
+ val = remainder ( v1 - v2 , mod )
304
301
)
305
302
}
306
303
307
304
private predicate condExprBranchModulus (
308
- SemConditionalExpr cond , boolean branch , Bounds:: SemBound b , int val , int mod
305
+ Sem :: ConditionalExpr cond , boolean branch , Bounds:: SemBound b , int val , int mod
309
306
) {
310
307
semExprModulus ( cond .getBranchExpr ( branch ) , b , val , mod )
311
308
}
312
309
313
- private predicate addModulus ( SemExpr add , boolean isLeft , Bounds:: SemBound b , int val , int mod ) {
314
- exists ( SemExpr larg , SemExpr rarg | nonConstAddition ( add , larg , rarg ) |
310
+ private predicate addModulus ( Sem :: Expr add , boolean isLeft , Bounds:: SemBound b , int val , int mod ) {
311
+ exists ( Sem :: Expr larg , Sem :: Expr rarg | nonConstAddition ( add , larg , rarg ) |
315
312
semExprModulus ( larg , b , val , mod ) and isLeft = true
316
313
or
317
314
semExprModulus ( rarg , b , val , mod ) and isLeft = false
318
315
)
319
316
}
320
317
321
- private predicate subModulus ( SemExpr sub , boolean isLeft , Bounds:: SemBound b , int val , int mod ) {
322
- exists ( SemExpr larg , SemExpr rarg | nonConstSubtraction ( sub , larg , rarg ) |
318
+ private predicate subModulus ( Sem :: Expr sub , boolean isLeft , Bounds:: SemBound b , int val , int mod ) {
319
+ exists ( Sem :: Expr larg , Sem :: Expr rarg | nonConstSubtraction ( sub , larg , rarg ) |
323
320
semExprModulus ( larg , b , val , mod ) and isLeft = true
324
321
or
325
322
semExprModulus ( rarg , b , val , mod ) and isLeft = false
0 commit comments