66
77private import ModulusAnalysisSpecific:: Private
88private import semmle.code.java.semantic.SemanticBound
9+ private import semmle.code.java.semantic.SemanticCFG
910private import semmle.code.java.semantic.SemanticExpr
1011private import semmle.code.java.semantic.SemanticGuard
1112private import semmle.code.java.semantic.SemanticSSA
@@ -30,9 +31,9 @@ private predicate valueFlowStepSsa(SemSsaVariable v, SemSsaReadPosition pos, Sem
3031 * `ConstantIntegerExpr`s.
3132 */
3233private predicate nonConstAddition ( SemExpr add , SemExpr larg , SemExpr rarg ) {
33- exists ( AddExpr a | a = add |
34- larg = a .getLhs ( ) and
35- rarg = a .getRhs ( )
34+ exists ( SemAddExpr a | a = add |
35+ larg = a .getLeftOperand ( ) and
36+ rarg = a .getRightOperand ( )
3637 ) and
3738 not larg instanceof SemConstantIntegerExpr and
3839 not rarg instanceof SemConstantIntegerExpr
@@ -43,9 +44,9 @@ private predicate nonConstAddition(SemExpr add, SemExpr larg, SemExpr rarg) {
4344 * a `ConstantIntegerExpr`.
4445 */
4546private predicate nonConstSubtraction ( SemExpr sub , SemExpr larg , SemExpr rarg ) {
46- exists ( SubExpr s | s = sub |
47- larg = s .getLhs ( ) and
48- rarg = s .getRhs ( )
47+ exists ( SemSubExpr s | s = sub |
48+ larg = s .getLeftOperand ( ) and
49+ rarg = s .getRightOperand ( )
4950 ) and
5051 not rarg instanceof SemConstantIntegerExpr
5152}
@@ -62,7 +63,7 @@ private SemExpr modExpr(SemExpr arg, int mod) {
6263 exists ( SemConstantIntegerExpr c |
6364 mod = 2 .pow ( [ 1 .. 30 ] ) and
6465 c .getIntValue ( ) = mod - 1 and
65- result .( BitwiseAndExpr ) .hasOperands ( arg , c )
66+ result .( SemBitAndExpr ) .hasOperands ( arg , c )
6667 )
6768}
6869
@@ -107,11 +108,11 @@ private predicate andmaskFactor(int mask, int factor) {
107108/** Holds if `e` is evenly divisible by `factor`. */
108109private predicate evenlyDivisibleExpr ( SemExpr e , int factor ) {
109110 exists ( SemConstantIntegerExpr c , int k | k = c .getIntValue ( ) |
110- e .( MulExpr ) .getAnOperand ( ) = c and factor = k .abs ( ) and factor >= 2
111+ e .( SemMulExpr ) .getAnOperand ( ) = c and factor = k .abs ( ) and factor >= 2
111112 or
112- e .( LShiftExpr ) . getRhs ( ) = c and factor = 2 .pow ( k ) and k > 0
113+ e .( SemShiftLeftExpr ) . getRightOperand ( ) = c and factor = 2 .pow ( k ) and k > 0
113114 or
114- e .( BitwiseAndExpr ) .getAnOperand ( ) = c and factor = max ( int f | andmaskFactor ( k , f ) )
115+ e .( SemBitAndExpr ) .getAnOperand ( ) = c and factor = max ( int f | andmaskFactor ( k , f ) )
115116 )
116117}
117118
@@ -223,49 +224,54 @@ private predicate ssaModulus(SemSsaVariable v, SemSsaReadPosition pos, SemBound
223224 */
224225cached
225226predicate semExprModulus ( SemExpr e , SemBound b , int val , int mod ) {
226- e = b .getExpr ( val ) and mod = 0
227- or
228- evenlyDivisibleExpr ( e , mod ) and val = 0 and b instanceof SemZeroBound
229- or
230- exists ( SemSsaVariable v , SemSsaReadPositionBlock bb |
231- ssaModulus ( v , bb , b , val , mod ) and
232- e = v .getAUse ( ) and
233- bb .getAnExpr ( ) = e
234- )
235- or
236- exists ( SemExpr mid , int val0 , int delta |
237- semExprModulus ( mid , b , val0 , mod ) and
238- semValueFlowStep ( e , mid , delta ) and
239- val = remainder ( val0 + delta , mod )
240- )
241- or
242- exists ( SemConditionalExpr cond , int v1 , int v2 , int m1 , int m2 |
243- cond = e and
244- condExprBranchModulus ( cond , true , b , v1 , m1 ) and
245- condExprBranchModulus ( cond , false , b , v2 , m2 ) and
246- mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 ) and
247- mod != 1 and
248- val = remainder ( v1 , mod )
249- )
250- or
251- exists ( SemBound b1 , SemBound b2 , int v1 , int v2 , int m1 , int m2 |
252- addModulus ( e , true , b1 , v1 , m1 ) and
253- addModulus ( e , false , b2 , v2 , m2 ) and
254- mod = m1 .gcd ( m2 ) and
255- mod != 1 and
256- val = remainder ( v1 + v2 , mod )
257- |
258- b = b1 and b2 instanceof SemZeroBound
227+ not ignoreExprModulus ( e ) and
228+ (
229+ e = b .getExpr ( val ) and mod = 0
259230 or
260- b = b2 and b1 instanceof SemZeroBound
261- )
262- or
263- exists ( int v1 , int v2 , int m1 , int m2 |
264- subModulus ( e , true , b , v1 , m1 ) and
265- subModulus ( e , false , any ( SemZeroBound zb ) , v2 , m2 ) and
266- mod = m1 .gcd ( m2 ) and
267- mod != 1 and
268- val = remainder ( v1 - v2 , mod )
231+ evenlyDivisibleExpr ( e , mod ) and
232+ val = 0 and
233+ b instanceof SemZeroBound
234+ or
235+ exists ( SemSsaVariable v , SemSsaReadPositionBlock bb |
236+ ssaModulus ( v , bb , b , val , mod ) and
237+ e = v .getAUse ( ) and
238+ bb .getAnExpr ( ) = e
239+ )
240+ or
241+ exists ( SemExpr mid , int val0 , int delta |
242+ semExprModulus ( mid , b , val0 , mod ) and
243+ semValueFlowStep ( e , mid , delta ) and
244+ val = remainder ( val0 + delta , mod )
245+ )
246+ or
247+ exists ( SemConditionalExpr cond , int v1 , int v2 , int m1 , int m2 |
248+ cond = e and
249+ condExprBranchModulus ( cond , true , b , v1 , m1 ) and
250+ condExprBranchModulus ( cond , false , b , v2 , m2 ) and
251+ mod = m1 .gcd ( m2 ) .gcd ( v1 - v2 ) and
252+ mod != 1 and
253+ val = remainder ( v1 , mod )
254+ )
255+ or
256+ exists ( SemBound b1 , SemBound b2 , int v1 , int v2 , int m1 , int m2 |
257+ addModulus ( e , true , b1 , v1 , m1 ) and
258+ addModulus ( e , false , b2 , v2 , m2 ) and
259+ mod = m1 .gcd ( m2 ) and
260+ mod != 1 and
261+ val = remainder ( v1 + v2 , mod )
262+ |
263+ b = b1 and b2 instanceof SemZeroBound
264+ or
265+ b = b2 and b1 instanceof SemZeroBound
266+ )
267+ or
268+ exists ( int v1 , int v2 , int m1 , int m2 |
269+ subModulus ( e , true , b , v1 , m1 ) and
270+ subModulus ( e , false , any ( SemZeroBound zb ) , v2 , m2 ) and
271+ mod = m1 .gcd ( m2 ) and
272+ mod != 1 and
273+ val = remainder ( v1 - v2 , mod )
274+ )
269275 )
270276}
271277
@@ -290,3 +296,25 @@ private predicate subModulus(SemExpr sub, boolean isLeft, SemBound b, int val, i
290296 semExprModulus ( rarg , b , val , mod ) and isLeft = false
291297 )
292298}
299+
300+ private predicate id ( SemBasicBlock x , SemBasicBlock y ) { x = y }
301+
302+ private predicate idOf ( SemBasicBlock x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
303+
304+ private int getId ( SemBasicBlock bb ) { idOf ( bb , result ) }
305+
306+ /**
307+ * Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
308+ * in an arbitrary 1-based numbering of the input edges to `phi`.
309+ */
310+ private predicate rankedPhiInput (
311+ SemSsaPhiNode phi , SemSsaVariable inp , SemSsaReadPositionPhiInputEdge edge , int r
312+ ) {
313+ edge .phiInput ( phi , inp ) and
314+ edge =
315+ rank [ r ] ( SemSsaReadPositionPhiInputEdge e |
316+ e .phiInput ( phi , _)
317+ |
318+ e order by getId ( e .getOrigBlock ( ) )
319+ )
320+ }
0 commit comments