Skip to content

Commit e6aa2de

Browse files
committed
C++: semantic range analysis perf fixes
1 parent 1d56330 commit e6aa2de

File tree

4 files changed

+17
-7
lines changed

4 files changed

+17
-7
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ module SemanticExprConfig {
169169

170170
final override predicate hasRead(SsaVariable v) {
171171
exists(IR::Operand operand |
172-
operand.getDef() = v and not operand instanceof IR::PhiInputOperand
172+
operand.getDef() = v and
173+
not operand instanceof IR::PhiInputOperand and
174+
operand.getUse().getBlock() = block
173175
)
174176
}
175177
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ private predicate phiModulusInit(SemSsaPhiNode phi, SemBound b, int val, int mod
160160
/**
161161
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
162162
*/
163+
pragma[nomagic]
163164
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
164165
rix = 0 and
165166
phiModulusInit(phi, b, val, mod)
@@ -169,7 +170,7 @@ private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int
169170
val = remainder(v1, mod)
170171
|
171172
exists(int v2, int m2 |
172-
rankedPhiInput(phi, inp, edge, rix) and
173+
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
173174
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
174175
ssaModulus(inp, edge, b, v2, m2) and
175176
mod = m1.gcd(m2).gcd(v1 - v2)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private class ConvertOrBoxExpr extends SemUnaryExpr {
342342
* A cast that can be ignored for the purpose of range analysis.
343343
*/
344344
private class SafeCastExpr extends ConvertOrBoxExpr {
345-
SafeCastExpr() { conversionCannotOverflow(getTrackedType(getOperand()), getTrackedType(this)) }
345+
SafeCastExpr() { conversionCannotOverflow(getTrackedType(pragma[only_bind_into](getOperand())), getTrackedType(this)) }
346346
}
347347

348348
/**

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,12 @@ private class BinarySignExpr extends FlowSignExpr {
189189
BinarySignExpr() { binary = this }
190190

191191
override Sign getSignRestriction() {
192-
result =
193-
semExprSign(binary.getLeftOperand())
194-
.applyBinaryOp(semExprSign(binary.getRightOperand()), binary.getOpcode())
192+
exists(SemExpr left, SemExpr right |
193+
binaryExprOperands(binary, left, right) and
194+
result =
195+
semExprSign(pragma[only_bind_out](left))
196+
.applyBinaryOp(semExprSign(pragma[only_bind_out](right)), binary.getOpcode())
197+
)
195198
or
196199
exists(SemDivExpr div | div = binary |
197200
result = semExprSign(div.getLeftOperand()) and
@@ -201,6 +204,10 @@ private class BinarySignExpr extends FlowSignExpr {
201204
}
202205
}
203206

207+
private predicate binaryExprOperands(SemBinaryExpr binary, SemExpr left, SemExpr right) {
208+
binary.getLeftOperand() = left and binary.getRightOperand() = right
209+
}
210+
204211
/**
205212
* A `Convert`, `Box`, or `Unbox` expression.
206213
*/
@@ -221,7 +228,7 @@ private class UnarySignExpr extends FlowSignExpr {
221228
UnarySignExpr() { unary = this and not this instanceof SemCastExpr }
222229

223230
override Sign getSignRestriction() {
224-
result = semExprSign(unary.getOperand()).applyUnaryOp(unary.getOpcode())
231+
result = semExprSign(pragma[only_bind_out](unary.getOperand())).applyUnaryOp(unary.getOpcode())
225232
}
226233
}
227234

0 commit comments

Comments
 (0)