Skip to content

Commit 3bf6c0f

Browse files
committed
Rangeanalysis: Focus pre-bound calculation.
1 parent c14d917 commit 3bf6c0f

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

shared/rangeanalysis/codeql/rangeanalysis/RangeAnalysis.qll

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,47 @@ module RangeStage<
11321132
bindingset[x, y]
11331133
private float truncatingDiv(float x, float y) { result = (x - (x % y)) / y }
11341134

1135+
/**
1136+
* Holds if `e1 + delta` is a valid bound for `e2`.
1137+
* - `upper = true` : `e2 <= e1 + delta`
1138+
* - `upper = false` : `e2 >= e1 + delta`
1139+
*
1140+
* This is restricted to simple forward-flowing steps and disregards phi-nodes.
1141+
*/
1142+
private predicate preBoundStep(Sem::Expr e2, Sem::Expr e1, D::Delta delta, boolean upper) {
1143+
boundFlowStep(e2, e1, delta, upper)
1144+
or
1145+
exists(Sem::SsaVariable v, SsaReadPositionBlock bb |
1146+
boundFlowStepSsa(v, bb, e1, delta, upper, _) and
1147+
bb.getAnSsaRead(v) = e2
1148+
)
1149+
}
1150+
1151+
/**
1152+
* Holds if simple forward-flowing steps from `e` can reach an expression that
1153+
* has multiple incoming bound-flow edges, that is, it has multiple ways to
1154+
* get a valid bound.
1155+
*/
1156+
private predicate reachesBoundMergepoint(Sem::Expr e, boolean upper) {
1157+
2 <= strictcount(Sem::Expr mid | preBoundStep(e, mid, _, upper))
1158+
or
1159+
exists(Sem::SsaPhiNode v, SsaReadPositionBlock bb |
1160+
boundFlowStepSsa(v, bb, _, _, upper, _) and
1161+
bb.getAnSsaRead(v) = e
1162+
)
1163+
or
1164+
exists(Sem::Expr e2 |
1165+
preBoundStep(e2, e, _, upper) and
1166+
reachesBoundMergepoint(e2, upper)
1167+
)
1168+
}
1169+
1170+
pragma[nomagic]
1171+
private predicate relevantPreBoundStep(Sem::Expr e2, Sem::Expr e1, D::Delta delta, boolean upper) {
1172+
preBoundStep(e2, e1, delta, upper) and
1173+
reachesBoundMergepoint(e2, upper)
1174+
}
1175+
11351176
/**
11361177
* Holds if `b + delta` is a valid bound for `e` that can be found using only
11371178
* simple forward-flowing steps and disregarding phi-nodes.
@@ -1155,17 +1196,10 @@ module RangeStage<
11551196
baseBound(e, b, delta, upper)
11561197
or
11571198
exists(Sem::Expr mid, D::Delta d1, D::Delta d2 |
1158-
boundFlowStep(e, mid, d1, upper) and
1199+
relevantPreBoundStep(e, mid, d1, upper) and
11591200
preBounded(mid, b, d2, upper) and
11601201
delta = D::fromFloat(D::toFloat(d1) + D::toFloat(d2))
11611202
)
1162-
or
1163-
exists(Sem::SsaVariable v, SsaReadPositionBlock bb, Sem::Expr mid, D::Delta d1, D::Delta d2 |
1164-
boundFlowStepSsa(v, bb, mid, d1, upper, _) and
1165-
preBounded(mid, b, d2, upper) and
1166-
delta = D::fromFloat(D::toFloat(d1) + D::toFloat(d2)) and
1167-
bb.getAnSsaRead(v) = e
1168-
)
11691203
}
11701204

11711205
private predicate bestPreBound(Sem::Expr e, SemBound b, D::Delta delta, boolean upper) {

0 commit comments

Comments
 (0)