Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cbe16e5

Browse files
committed
C++: Pull rounding functions out to new predicates
1 parent 006594f commit cbe16e5

1 file changed

Lines changed: 68 additions & 60 deletions

File tree

cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,50 @@ predicate analyzableDef(RangeSsaDefinition def, LocalScopeVariable v) {
293293
assignmentDef(def, v, _) or defDependsOnDef(def, v, _, _)
294294
}
295295

296+
/**
297+
* Computes `x + y`, rounded towards +Inf. This is the general case where both
298+
* `x` and `y` may be large numbers.
299+
*/
300+
bindingset[x, y]
301+
private float addRoundingUp(float x, float y) {
302+
if (x + y) - x < y or (x + y) - y < x
303+
then result = (x + y).nextUp()
304+
else result = (x + y)
305+
}
306+
307+
/**
308+
* Computes `x + y`, rounded towards -Inf. This is the general case where both
309+
* `x` and `y` may be large numbers.
310+
*/
311+
bindingset[x, y]
312+
private float addRoundingDown(float x, float y) {
313+
if (x + y) - x > y or (x + y) - y > x
314+
then result = (x + y).nextDown()
315+
else result = (x + y)
316+
}
317+
318+
/**
319+
* Computes `x + small`, rounded towards +Inf, where `small` is a small
320+
* constant.
321+
*/
322+
bindingset[x, small]
323+
private float addRoundingUpSmall(float x, float small) {
324+
if (x + small) - x < small
325+
then result = (x + small).nextUp()
326+
else result = (x + small)
327+
}
328+
329+
/**
330+
* Computes `x + small`, rounded towards -Inf, where `small` is a small
331+
* constant.
332+
*/
333+
bindingset[x, small]
334+
private float addRoundingDownSmall(float x, float small) {
335+
if (x + small) - x > small
336+
then result = (x + small).nextDown()
337+
else result = (x + small)
338+
}
339+
296340
/**
297341
* Gets the truncated lower bounds of the fully converted expression.
298342
*/
@@ -469,20 +513,14 @@ float getLowerBoundsImpl(Expr expr) {
469513
exists (AddExpr addExpr, float xLow, float yLow
470514
| expr = addExpr and
471515
xLow = getFullyConvertedLowerBounds(addExpr.getLeftOperand()) and
472-
yLow = getFullyConvertedLowerBounds(addExpr.getRightOperand())
473-
| // Make sure that we round towards -Inf, not to nearest.
474-
if (xLow+yLow)-xLow > yLow or (xLow+yLow)-yLow > xLow
475-
then result = (xLow+yLow).nextDown()
476-
else result = xLow+yLow)
516+
yLow = getFullyConvertedLowerBounds(addExpr.getRightOperand()) and
517+
result = addRoundingDown(xLow, yLow))
477518
or
478519
exists (SubExpr subExpr, float xLow, float yHigh
479520
| expr = subExpr and
480521
xLow = getFullyConvertedLowerBounds(subExpr.getLeftOperand()) and
481-
yHigh = getFullyConvertedUpperBounds(subExpr.getRightOperand())
482-
| // Make sure that we round towards -Inf, not to nearest.
483-
if (xLow-yHigh)-xLow > -yHigh or (xLow-yHigh)+yHigh > xLow
484-
then result = (xLow-yHigh).nextDown()
485-
else result = xLow-yHigh)
522+
yHigh = getFullyConvertedUpperBounds(subExpr.getRightOperand()) and
523+
result = addRoundingDown(xLow, -yHigh))
486524
or
487525
exists (PrefixIncrExpr incrExpr, float xLow
488526
| expr = incrExpr and
@@ -491,11 +529,8 @@ float getLowerBoundsImpl(Expr expr) {
491529
or
492530
exists (PrefixDecrExpr decrExpr, float xLow
493531
| expr = decrExpr and
494-
xLow = getFullyConvertedLowerBounds(decrExpr.getOperand())
495-
| // Make sure that we round towards -Inf, not to nearest.
496-
if (xLow-1)-xLow > -1
497-
then result = (xLow-1).nextDown()
498-
else result = xLow-1)
532+
xLow = getFullyConvertedLowerBounds(decrExpr.getOperand()) and
533+
result = addRoundingDownSmall(xLow, -1))
499534
or
500535
// `PostfixIncrExpr` and `PostfixDecrExpr` return the value of their
501536
// operand. The incrementing/decrementing behavior is handled in
@@ -600,28 +635,19 @@ float getUpperBoundsImpl(Expr expr) {
600635
exists (AddExpr addExpr, float xHigh, float yHigh
601636
| expr = addExpr and
602637
xHigh = getFullyConvertedUpperBounds(addExpr.getLeftOperand()) and
603-
yHigh = getFullyConvertedUpperBounds(addExpr.getRightOperand())
604-
| // Make sure that we round towards +Inf, not to nearest.
605-
if (xHigh+yHigh)-xHigh < yHigh or (xHigh+yHigh)-yHigh < xHigh
606-
then result = (xHigh+yHigh).nextUp()
607-
else result = xHigh+yHigh)
638+
yHigh = getFullyConvertedUpperBounds(addExpr.getRightOperand()) and
639+
result = addRoundingUp(xHigh, yHigh))
608640
or
609641
exists (SubExpr subExpr, float xHigh, float yLow
610642
| expr = subExpr and
611643
xHigh = getFullyConvertedUpperBounds(subExpr.getLeftOperand()) and
612-
yLow = getFullyConvertedLowerBounds(subExpr.getRightOperand())
613-
| // Make sure that we round towards +Inf, not to nearest.
614-
if (xHigh-yLow)-xHigh < -yLow or (xHigh-yLow)+yLow < xHigh
615-
then result = (xHigh-yLow).nextUp()
616-
else result = xHigh-yLow)
644+
yLow = getFullyConvertedLowerBounds(subExpr.getRightOperand()) and
645+
result = addRoundingUp(xHigh, -yLow))
617646
or
618647
exists (PrefixIncrExpr incrExpr, float xHigh
619648
| expr = incrExpr and
620-
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand())
621-
| // Make sure that we round towards +Inf, not to nearest.
622-
if (xHigh+1)-xHigh < 1
623-
then result = (xHigh+1).nextUp()
624-
else result = xHigh+1)
649+
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand()) and
650+
result = addRoundingUpSmall(xHigh, 1))
625651
or
626652
exists (PrefixDecrExpr decrExpr, float xHigh
627653
| expr = decrExpr and
@@ -813,22 +839,16 @@ float getDefLowerBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
813839
| def = assignAdd and
814840
assignAdd.getLValue() = nextDef.getAUse(v) and
815841
lhsLB = getDefLowerBounds(nextDef, v) and
816-
rhsLB = getFullyConvertedLowerBounds(assignAdd.getRValue())
817-
| // Make sure that we round towards -Inf, not to nearest.
818-
if (lhsLB+rhsLB)-lhsLB > rhsLB or (lhsLB+rhsLB)-rhsLB > lhsLB
819-
then result = (lhsLB+rhsLB).nextDown()
820-
else result = lhsLB+rhsLB)
842+
rhsLB = getFullyConvertedLowerBounds(assignAdd.getRValue()) and
843+
result = addRoundingDown(lhsLB, rhsLB))
821844
or
822845
exists (
823846
AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsLB, float rhsUB
824847
| def = assignSub and
825848
assignSub.getLValue() = nextDef.getAUse(v) and
826849
lhsLB = getDefLowerBounds(nextDef, v) and
827-
rhsUB = getFullyConvertedUpperBounds(assignSub.getRValue())
828-
| // Make sure that we round towards -Inf, not to nearest.
829-
if (lhsLB-rhsUB)-lhsLB > -rhsUB or (lhsLB-rhsUB)+rhsUB > lhsLB
830-
then result = (lhsLB-rhsUB).nextDown()
831-
else result = lhsLB-rhsUB)
850+
rhsUB = getFullyConvertedUpperBounds(assignSub.getRValue()) and
851+
result = addRoundingDown(lhsLB, -rhsUB))
832852
or
833853
exists (IncrementOperation incr, float newLB
834854
| def = incr and
@@ -839,11 +859,8 @@ float getDefLowerBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
839859
exists (DecrementOperation decr, float newLB
840860
| def = decr and
841861
decr.getOperand() = v.getAnAccess() and
842-
newLB = getFullyConvertedLowerBounds(decr.getOperand())
843-
| // Make sure that we round towards -Inf, not to nearest.
844-
if (newLB-1)-newLB > -1
845-
then result = (newLB-1).nextDown()
846-
else result = newLB-1)
862+
newLB = getFullyConvertedLowerBounds(decr.getOperand()) and
863+
result = addRoundingDownSmall(newLB, -1))
847864
or
848865
// Phi nodes.
849866
result = getPhiLowerBounds(v, def)
@@ -865,31 +882,22 @@ float getDefUpperBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
865882
| def = assignAdd and
866883
assignAdd.getLValue() = nextDef.getAUse(v) and
867884
lhsUB = getDefUpperBounds(nextDef, v) and
868-
rhsUB = getFullyConvertedUpperBounds(assignAdd.getRValue())
869-
| // Make sure that we round towards +Inf, not to nearest.
870-
if (lhsUB+rhsUB)-lhsUB < rhsUB or (lhsUB+rhsUB)-rhsUB < lhsUB
871-
then result = (lhsUB+rhsUB).nextUp()
872-
else result = lhsUB+rhsUB)
885+
rhsUB = getFullyConvertedUpperBounds(assignAdd.getRValue()) and
886+
result = addRoundingUp(lhsUB, rhsUB))
873887
or
874888
exists (
875889
AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsUB, float rhsLB
876890
| def = assignSub and
877891
assignSub.getLValue() = nextDef.getAUse(v) and
878892
lhsUB = getDefUpperBounds(nextDef, v) and
879-
rhsLB = getFullyConvertedLowerBounds(assignSub.getRValue())
880-
| // Make sure that we round towards +Inf, not to nearest.
881-
if (lhsUB-rhsLB)-lhsUB < -rhsLB or (lhsUB-rhsLB)+rhsLB < lhsUB
882-
then result = (lhsUB-rhsLB).nextUp()
883-
else result = lhsUB-rhsLB)
893+
rhsLB = getFullyConvertedLowerBounds(assignSub.getRValue()) and
894+
result = addRoundingUp(lhsUB, -rhsLB))
884895
or
885896
exists (IncrementOperation incr, float newUB
886897
| def = incr and
887898
incr.getOperand() = v.getAnAccess() and
888-
newUB = getFullyConvertedUpperBounds(incr.getOperand())
889-
| // Make sure that we round towards +Inf, not to nearest.
890-
if (newUB+1)-newUB < 1
891-
then result = (newUB+1).nextUp()
892-
else result = newUB+1)
899+
newUB = getFullyConvertedUpperBounds(incr.getOperand()) and
900+
result = addRoundingUpSmall(newUB, 1))
893901
or
894902
exists (DecrementOperation decr, float newUB
895903
| def = decr and

0 commit comments

Comments
 (0)