1010 * handles phi inputs.
1111 */
1212
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
2015
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+ {
2220 pragma [ nomagic]
2321 private predicate valueFlowStepSsaEqFlowCond (
24- SemSsaReadPosition pos , SemSsaVariable v , SemExpr e , int delta
22+ Sem :: SsaReadPosition pos , Sem :: SsaVariable v , Sem :: Expr e , int delta
2523 ) {
26- exists ( SemGuard guard , boolean testIsTrue |
24+ exists ( Sem :: Guard guard , boolean testIsTrue |
2725 guard = U:: semEqFlowCond ( v , e , D:: fromInt ( delta ) , true , testIsTrue ) and
28- semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue )
26+ Sem :: guardDirectlyControlsSsaRead ( guard , pos , testIsTrue )
2927 )
3028 }
3129
3230 /**
3331 * Holds if `e + delta` equals `v` at `pos`.
3432 */
3533 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+ ) {
3737 U:: semSsaUpdateStep ( v , e , D:: fromInt ( delta ) ) and pos .hasReadOfVar ( v )
3838 or
3939 pos .hasReadOfVar ( v ) and
@@ -44,49 +44,49 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
4444 * Holds if `add` is the addition of `larg` and `rarg`, neither of which are
4545 * `ConstantIntegerExpr`s.
4646 */
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 |
4949 larg = a .getLeftOperand ( ) and
5050 rarg = a .getRightOperand ( )
5151 ) 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
5454 }
5555
5656 /**
5757 * Holds if `sub` is the subtraction of `larg` and `rarg`, where `rarg` is not
5858 * a `ConstantIntegerExpr`.
5959 */
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 |
6262 larg = s .getLeftOperand ( ) and
6363 rarg = s .getRightOperand ( )
6464 ) and
65- not rarg instanceof SemConstantIntegerExpr
65+ not rarg instanceof Sem :: ConstantIntegerExpr
6666 }
6767
6868 /** 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 |
7171 result = rem and
7272 arg = rem .getLeftOperand ( ) and
73- rem .getRightOperand ( ) .( SemConstantIntegerExpr ) .getIntValue ( ) = mod and
73+ rem .getRightOperand ( ) .( Sem :: ConstantIntegerExpr ) .getIntValue ( ) = mod and
7474 mod >= 2
7575 )
7676 or
77- exists ( SemConstantIntegerExpr c |
77+ exists ( Sem :: ConstantIntegerExpr c |
7878 mod = 2 .pow ( [ 1 .. 30 ] ) and
7979 c .getIntValue ( ) = mod - 1 and
80- result .( SemBitAndExpr ) .hasOperands ( arg , c )
80+ result .( Sem :: BitAndExpr ) .hasOperands ( arg , c )
8181 )
8282 }
8383
8484 /**
8585 * Gets a guard that tests whether `v` is congruent with `val` modulo `mod` on
8686 * its `testIsTrue` branch.
8787 */
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 |
9090 result .isEquality ( rem , c , polarity ) and
9191 c .getIntValue ( ) = r and
9292 rem = modExpr ( v .getAUse ( ) , mod ) and
@@ -104,11 +104,11 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
104104 /**
105105 * Holds if a guard ensures that `v` at `pos` is congruent with `val` modulo `mod`.
106106 */
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 |
109109 pos .hasReadOfVar ( v ) and
110110 guard = moduloCheck ( v , val , mod , testIsTrue ) and
111- semGuardControlsSsaRead ( guard , pos , testIsTrue )
111+ Sem :: guardControlsSsaRead ( guard , pos , testIsTrue )
112112 )
113113 }
114114
@@ -120,13 +120,13 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
120120 }
121121
122122 /** 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
126126 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
128128 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 ) )
130130 )
131131 }
132132
@@ -147,7 +147,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
147147 * Holds if `inp` is an input to `phi` and equals `phi` modulo `mod` along `edge`.
148148 */
149149 private predicate phiSelfModulus (
150- SemSsaPhiNode phi , SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge , int mod
150+ Sem :: SsaPhiNode phi , Sem :: SsaVariable inp , Sem :: SsaReadPositionPhiInputEdge edge , int mod
151151 ) {
152152 exists ( Bounds:: SemSsaBound phibound , int v , int m |
153153 edge .phiInput ( phi , inp ) and
@@ -161,8 +161,8 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
161161 /**
162162 * Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
163163 */
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 |
166166 edge .phiInput ( phi , inp ) and
167167 ssaModulus ( inp , edge , b , val , mod )
168168 )
@@ -173,7 +173,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
173173 */
174174 pragma [ nomagic]
175175 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
177177 ) {
178178 /*
179179 * 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
183183 rix = 0 and
184184 phiModulusInit ( phi , b , val , mod )
185185 or
186- exists ( SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge , int v1 , int m1 |
186+ exists ( Sem :: SsaVariable inp , Sem :: SsaReadPositionPhiInputEdge edge , int v1 , int m1 |
187187 mod != 1 and
188188 val = remainder ( v1 , mod )
189189 |
@@ -194,7 +194,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
194194 */
195195
196196 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
198198 phiModulusRankStep ( phi , b , v1 , m1 , rix - 1 ) and
199199 ssaModulus ( inp , edge , b , v2 , m2 ) and
200200 mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 )
@@ -207,7 +207,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
207207 */
208208
209209 exists ( int m2 |
210- rankedPhiInput ( phi , inp , edge , rix ) and
210+ U :: rankedPhiInput ( phi , inp , edge , rix ) and
211211 phiModulusRankStep ( phi , b , v1 , m1 , rix - 1 ) and
212212 phiSelfModulus ( phi , inp , edge , m2 ) and
213213 mod = m1 .gcd ( m2 )
@@ -218,9 +218,9 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
218218 /**
219219 * Holds if `phi` is equal to `b + val` modulo `mod`.
220220 */
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 ) {
222222 exists ( int r |
223- maxPhiInputRank ( phi , r ) and
223+ U :: maxPhiInputRank ( phi , r ) and
224224 phiModulusRankStep ( phi , b , val , mod , r )
225225 )
226226 }
@@ -229,13 +229,13 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
229229 * Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
230230 */
231231 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
233233 ) {
234234 phiModulus ( v , b , val , mod ) and pos .hasReadOfVar ( v )
235235 or
236236 b .( Bounds:: SemSsaBound ) .getVariable ( ) = v and pos .hasReadOfVar ( v ) and val = 0 and mod = 0
237237 or
238- exists ( SemExpr e , int val0 , int delta |
238+ exists ( Sem :: Expr e , int val0 , int delta |
239239 semExprModulus ( e , b , val0 , mod ) and
240240 valueFlowStepSsa ( v , pos , e , delta ) and
241241 val = remainder ( val0 + delta , mod )
@@ -252,74 +252,71 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
252252 * - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
253253 */
254254 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
296291 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 )
304301 )
305302 }
306303
307304 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
309306 ) {
310307 semExprModulus ( cond .getBranchExpr ( branch ) , b , val , mod )
311308 }
312309
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 ) |
315312 semExprModulus ( larg , b , val , mod ) and isLeft = true
316313 or
317314 semExprModulus ( rarg , b , val , mod ) and isLeft = false
318315 )
319316 }
320317
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 ) |
323320 semExprModulus ( larg , b , val , mod ) and isLeft = true
324321 or
325322 semExprModulus ( rarg , b , val , mod ) and isLeft = false
0 commit comments