@@ -263,9 +263,11 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
263
263
264
264
/**
265
265
* Holds if this upper bound check ensures the non-constant operand is less
266
- * than or equal to `2^(bitsize) - 1`. In this case, the upper bound check
267
- * is a barrier guard. `architectureBitSize` is used if the constant operand
268
- * is `math.MaxInt` or `math.MaxUint`.
266
+ * than or equal to `2^(b) - 1` for some `b` which is a valid bit size less
267
+ * than `bitSize`. In this case, the upper bound check is a barrier guard,
268
+ * because the flow should be for `b` instead of `bitSize`.
269
+ * `architectureBitSize` is used if the constant operand is `math.MaxInt` or
270
+ * `math.MaxUint`.
269
271
*
270
272
* Note that we have to use floats here because integers in CodeQL are
271
273
* represented by 32-bit signed integers, which cannot represent some of the
@@ -274,7 +276,8 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
274
276
predicate isBoundFor ( int bitSize , int architectureBitSize ) {
275
277
bitSize = validBitSize ( ) and
276
278
architectureBitSize = [ 32 , 64 ] and
277
- exists ( float bound , float strictnessOffset |
279
+ exists ( float bound , int b , float strictnessOffset |
280
+ b = max ( int a | a = validBitSize ( ) and a < bitSize ) and
278
281
// For `x < c` the bound is `c-1`. For `x >= c` we will be an upper bound
279
282
// on the `branch` argument of `checks` is false, which is equivalent to
280
283
// `x < c`.
@@ -292,7 +295,7 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
292
295
then bound = getMaxIntValue ( architectureBitSize , false )
293
296
else bound = expr .getAnOperand ( ) .getExactValue ( ) .toFloat ( )
294
297
) and
295
- bound - strictnessOffset < 2 .pow ( bitSize ) - 1
298
+ bound - strictnessOffset <= 2 .pow ( b ) - 1
296
299
)
297
300
}
298
301
0 commit comments