Skip to content

Commit 87c144d

Browse files
committed
C++: Throw away the sign analysis when analyzing add expressions: instead, we now recursively analyze both operands.
1 parent 28998cc commit 87c144d

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -591,24 +591,6 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
591591
delta = D::fromInt(0) and
592592
(upper = true or upper = false)
593593
or
594-
exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) |
595-
// `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
596-
not x instanceof SemConstantIntegerExpr and
597-
not e1 instanceof SemConstantIntegerExpr and
598-
if strictlyPositiveIntegralExpr(x)
599-
then upper = false and delta = D::fromInt(1)
600-
else
601-
if semPositive(x)
602-
then upper = false and delta = D::fromInt(0)
603-
else
604-
if strictlyNegativeIntegralExpr(x)
605-
then upper = true and delta = D::fromInt(-1)
606-
else
607-
if semNegative(x)
608-
then upper = true and delta = D::fromInt(0)
609-
else none()
610-
)
611-
or
612594
exists(SemExpr x, SemSubExpr sub |
613595
e2 = sub and
614596
sub.getLeftOperand() = e1 and
@@ -1043,13 +1025,44 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
10431025
delta = D::fromFloat(f) and
10441026
if semPositive(e) then f >= 0 else any()
10451027
)
1028+
or
1029+
exists(
1030+
SemBound bLeft, SemBound bRight, D::Delta dLeft, D::Delta dRight, boolean fbeLeft,
1031+
boolean fbeRight, D::Delta odLeft, D::Delta odRight, SemReason rLeft, SemReason rRight
1032+
|
1033+
boundedAddOperand(e, upper, bLeft, false, dLeft, fbeLeft, odLeft, rLeft) and
1034+
boundedAddOperand(e, upper, bRight, true, dRight, fbeRight, odRight, rRight) and
1035+
delta = D::fromFloat(D::toFloat(dLeft) + D::toFloat(dRight)) and
1036+
fromBackEdge = fbeLeft.booleanOr(fbeRight)
1037+
|
1038+
b = bLeft and origdelta = odLeft and reason = rLeft and bRight instanceof SemZeroBound
1039+
or
1040+
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
1041+
)
10461042
)
10471043
}
10481044

1045+
pragma[nomagic]
10491046
private predicate boundedConditionalExpr(
10501047
SemConditionalExpr cond, SemBound b, boolean upper, boolean branch, D::Delta delta,
10511048
boolean fromBackEdge, D::Delta origdelta, SemReason reason
10521049
) {
10531050
bounded(cond.getBranchExpr(branch), b, delta, upper, fromBackEdge, origdelta, reason)
10541051
}
1052+
1053+
pragma[nomagic]
1054+
private predicate boundedAddOperand(
1055+
SemAddExpr add, boolean upper, SemBound b, boolean isLeft, D::Delta delta, boolean fromBackEdge,
1056+
D::Delta origdelta, SemReason reason
1057+
) {
1058+
// `semValueFlowStep` already handles the case where one of the operands is a constant.
1059+
not semValueFlowStep(add, _, _) and
1060+
(
1061+
isLeft = true and
1062+
bounded(add.getLeftOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1063+
or
1064+
isLeft = false and
1065+
bounded(add.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1066+
)
1067+
}
10551068
}

0 commit comments

Comments
 (0)