@@ -1397,6 +1397,20 @@ predicate nonNanGuardedVariable(Expr guard, VariableAccess v, boolean branch) {
1397
1397
nanExcludingComparison ( guard , branch )
1398
1398
}
1399
1399
1400
+ /**
1401
+ * Adjusts a lower bound to its meaning for integral types.
1402
+ *
1403
+ * Examples:
1404
+ * `>= 3.0` becomes `3.0`
1405
+ * ` > 3.0` becomes `4.0`
1406
+ * `>= 3.5` becomes `4.0`
1407
+ * ` > 3.5` becomes `4.0`
1408
+ */
1409
+ bindingset [ strictness, lb]
1410
+ private float adjustLowerBoundIntegral ( RelationStrictness strictness , float lb ) {
1411
+ if strictness = Nonstrict ( ) and lb .floor ( ) = lb then result = lb else result = safeFloor ( lb ) + 1
1412
+ }
1413
+
1400
1414
/**
1401
1415
* If the guard is a comparison of the form `p*v + q <CMP> r`, then this
1402
1416
* predicate uses the bounds information for `r` to compute a lower bound
@@ -1408,15 +1422,27 @@ private predicate lowerBoundFromGuard(Expr guard, VariableAccess v, float lb, bo
1408
1422
|
1409
1423
if nonNanGuardedVariable ( guard , v , branch )
1410
1424
then
1411
- if
1412
- strictness = Nonstrict ( ) or
1413
- not getVariableRangeType ( v .getTarget ( ) ) instanceof IntegralType
1414
- then lb = childLB
1415
- else lb = childLB + 1
1425
+ if getVariableRangeType ( v .getTarget ( ) ) instanceof IntegralType
1426
+ then lb = adjustLowerBoundIntegral ( strictness , childLB )
1427
+ else lb = childLB
1416
1428
else lb = varMinVal ( v .getTarget ( ) )
1417
1429
)
1418
1430
}
1419
1431
1432
+ /**
1433
+ * Adjusts an upper bound to its meaning for integral types.
1434
+ *
1435
+ * Examples:
1436
+ * `<= 3.0` becomes `3.0`
1437
+ * ` < 3.0` becomes `2.0`
1438
+ * `<= 3.5` becomes `3.0`
1439
+ * ` < 3.5` becomes `3.0`
1440
+ */
1441
+ bindingset [ strictness, ub]
1442
+ private float adjustUpperBoundIntegral ( RelationStrictness strictness , float ub ) {
1443
+ if strictness = Strict ( ) and ub .floor ( ) = ub then result = ub - 1 else result = safeFloor ( ub )
1444
+ }
1445
+
1420
1446
/**
1421
1447
* If the guard is a comparison of the form `p*v + q <CMP> r`, then this
1422
1448
* predicate uses the bounds information for `r` to compute a upper bound
@@ -1428,11 +1454,9 @@ private predicate upperBoundFromGuard(Expr guard, VariableAccess v, float ub, bo
1428
1454
|
1429
1455
if nonNanGuardedVariable ( guard , v , branch )
1430
1456
then
1431
- if
1432
- strictness = Nonstrict ( ) or
1433
- not getVariableRangeType ( v .getTarget ( ) ) instanceof IntegralType
1434
- then ub = childUB
1435
- else ub = childUB - 1
1457
+ if getVariableRangeType ( v .getTarget ( ) ) instanceof IntegralType
1458
+ then ub = adjustUpperBoundIntegral ( strictness , childUB )
1459
+ else ub = childUB
1436
1460
else ub = varMaxVal ( v .getTarget ( ) )
1437
1461
)
1438
1462
}
@@ -1472,7 +1496,7 @@ private predicate boundFromGuard(
1472
1496
* lower or upper bound for `v`.
1473
1497
*/
1474
1498
private predicate linearBoundFromGuard (
1475
- ComparisonOperation guard , VariableAccess v , float p , float q , float boundValue ,
1499
+ ComparisonOperation guard , VariableAccess v , float p , float q , float r ,
1476
1500
boolean isLowerBound , // Is this a lower or an upper bound?
1477
1501
RelationStrictness strictness , boolean branch // Which control-flow branch is this bound valid on?
1478
1502
) {
@@ -1487,11 +1511,11 @@ private predicate linearBoundFromGuard(
1487
1511
|
1488
1512
isLowerBound = directionIsGreater ( dir ) and
1489
1513
strictness = st and
1490
- getBounds ( rhs , boundValue , isLowerBound )
1514
+ getBounds ( rhs , r , isLowerBound )
1491
1515
or
1492
1516
isLowerBound = directionIsLesser ( dir ) and
1493
1517
strictness = Nonstrict ( ) and
1494
- exprTypeBounds ( rhs , boundValue , isLowerBound )
1518
+ exprTypeBounds ( rhs , r , isLowerBound )
1495
1519
)
1496
1520
or
1497
1521
// For x == RHS, we create the following bounds:
@@ -1502,7 +1526,7 @@ private predicate linearBoundFromGuard(
1502
1526
exists ( Expr lhs , Expr rhs |
1503
1527
linearAccess ( lhs , v , p , q ) and
1504
1528
eqOpWithSwapAndNegate ( guard , lhs , rhs , true , branch ) and
1505
- getBounds ( rhs , boundValue , isLowerBound ) and
1529
+ getBounds ( rhs , r , isLowerBound ) and
1506
1530
strictness = Nonstrict ( )
1507
1531
)
1508
1532
// x != RHS and !x are handled elsewhere
0 commit comments