@@ -263,9 +263,11 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
263263
264264 /**
265265 * 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`.
269271 *
270272 * Note that we have to use floats here because integers in CodeQL are
271273 * represented by 32-bit signed integers, which cannot represent some of the
@@ -274,7 +276,8 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
274276 predicate isBoundFor ( int bitSize , int architectureBitSize ) {
275277 bitSize = validBitSize ( ) and
276278 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
278281 // For `x < c` the bound is `c-1`. For `x >= c` we will be an upper bound
279282 // on the `branch` argument of `checks` is false, which is equivalent to
280283 // `x < c`.
@@ -292,7 +295,7 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode {
292295 then bound = getMaxIntValue ( architectureBitSize , false )
293296 else bound = expr .getAnOperand ( ) .getExactValue ( ) .toFloat ( )
294297 ) and
295- bound - strictnessOffset < 2 .pow ( bitSize ) - 1
298+ bound - strictnessOffset <= 2 .pow ( b ) - 1
296299 )
297300 }
298301
0 commit comments