Skip to content

Commit 2606abf

Browse files
committed
C++: sign analysis in potentiallyOverflowingExpr
1 parent 868b238 commit 2606abf

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

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

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import experimental.semmle.code.cpp.semantic.SemanticCFG
7373
import experimental.semmle.code.cpp.semantic.SemanticType
7474
import experimental.semmle.code.cpp.semantic.SemanticOpcode
7575
private import ConstantAnalysis
76+
private import Sign
7677
import experimental.semmle.code.cpp.semantic.SemanticLocation
7778

7879
/**
@@ -248,8 +249,9 @@ signature module OverflowSig<DeltaSig D> {
248249
}
249250

250251
module RangeStage<
251-
DeltaSig D, BoundSig<D> Bounds, OverflowSig<D> OverflowParam, LangSig<D> LangParam,
252-
UtilSig<D> UtilParam> {
252+
DeltaSig D, BoundSig<D> Bounds, OverflowSig<D> OverflowParam, LangSig<D> LangParam,
253+
UtilSig<D> UtilParam>
254+
{
253255
private import Bounds
254256
private import LangParam
255257
private import UtilParam
@@ -932,35 +934,70 @@ UtilSig<D> UtilParam> {
932934

933935
predicate bounded(
934936
SemExpr e, SemBound b, D::Delta delta, boolean upper, boolean fromBackEdge, D::Delta origdelta,
935-
SemReason reason) {
936-
initialBounded(e, b, delta, upper, fromBackEdge, origdelta, reason) and
937-
(
938-
semExprDoesntOverflow(upper.booleanNot(), e)
939-
or
940-
not potentiallyOverflowingExpr(upper.booleanNot(), e)
941-
)
937+
SemReason reason
938+
) {
939+
initialBounded(e, b, delta, upper, fromBackEdge, origdelta, reason) and
940+
(
941+
semExprDoesntOverflow(upper.booleanNot(), e)
942+
or
943+
not potentiallyOverflowingExpr(upper.booleanNot(), e)
944+
)
942945
}
943946

944947
predicate potentiallyOverflowingExpr(boolean positively, SemExpr expr) {
945-
positively in [true, false] and
946948
(
947949
expr.getOpcode() instanceof Opcode::Add or
948-
expr.getOpcode() instanceof Opcode::PointerAdd or
950+
expr.getOpcode() instanceof Opcode::PointerAdd
951+
) and
952+
(
953+
positively = true and
954+
(
955+
not semExprSign(expr.(SemBinaryExpr).getLeftOperand()) = TPos()
956+
or
957+
not semExprSign(expr.(SemBinaryExpr).getRightOperand()) = TPos()
958+
)
959+
or
960+
positively = false and
961+
(
962+
not semExprSign(expr.(SemBinaryExpr).getLeftOperand()) = TNeg()
963+
or
964+
not semExprSign(expr.(SemBinaryExpr).getRightOperand()) = TNeg()
965+
)
966+
)
967+
or
968+
(
949969
expr.getOpcode() instanceof Opcode::Sub or
950-
expr.getOpcode() instanceof Opcode::PointerSub or
970+
expr.getOpcode() instanceof Opcode::PointerSub
971+
) and
972+
(
973+
positively = true and
974+
(
975+
not semExprSign(expr.(SemBinaryExpr).getLeftOperand()) = TPos()
976+
or
977+
not semExprSign(expr.(SemBinaryExpr).getRightOperand()) = TNeg()
978+
)
979+
or
980+
positively = false and
981+
(
982+
not semExprSign(expr.(SemBinaryExpr).getLeftOperand()) = TNeg()
983+
or
984+
not semExprSign(expr.(SemBinaryExpr).getRightOperand()) = TPos()
985+
)
986+
)
987+
or
988+
positively in [true, false] and
989+
(
951990
expr.getOpcode() instanceof Opcode::Mul or
952991
expr.getOpcode() instanceof Opcode::ShiftLeft
953992
)
954993
or
955994
positively = false and
956995
(
957996
expr.getOpcode() instanceof Opcode::Negate or
958-
expr.getOpcode() instanceof Opcode::SubOne
997+
expr.getOpcode() instanceof Opcode::SubOne or
998+
expr.(SemDivExpr).getSemType() instanceof SemFloatingPointType
959999
)
9601000
or
961-
positively = false and
962-
expr.(SemDivExpr).getSemType() instanceof SemFloatingPointType
963-
or
9641001
positively = true and
9651002
expr.getOpcode() instanceof Opcode::AddOne
9661003
}

0 commit comments

Comments
 (0)