Skip to content

Commit 6d859da

Browse files
authored
Merge pull request #14656 from aschackmull/shared/range-utils
Rangeanalysis: Share ssaRead predicate
2 parents b54b5ae + 048a7c4 commit 6d859da

File tree

10 files changed

+127
-191
lines changed

10 files changed

+127
-191
lines changed

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticSSA.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class SemSsaExplicitUpdate extends SemSsaVariable {
2323
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
2424

2525
final SemExpr getSourceExpr() { result = sourceExpr }
26+
27+
final SemExpr getDefiningExpr() { result = sourceExpr }
2628
}
2729

2830
class SemSsaPhiNode extends SemSsaVariable {

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
151151
) {
152152
exists(Bounds::SemSsaBound phibound, int v, int m |
153153
edge.phiInput(phi, inp) and
154-
phibound.getAVariable() = phi and
154+
phibound.getVariable() = phi and
155155
ssaModulus(inp, edge, phibound, v, m) and
156156
mod = m.gcd(v) and
157157
mod != 1
@@ -233,7 +233,7 @@ module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig
233233
) {
234234
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
235235
or
236-
b.(Bounds::SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
236+
b.(Bounds::SemSsaBound).getVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
237237
or
238238
exists(SemExpr e, int val0, int delta |
239239
semExprModulus(e, b, val0, mod) and

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@ private import RangeAnalysisImpl
88
private import codeql.rangeanalysis.RangeAnalysis
99

1010
module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
11-
/**
12-
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
13-
*
14-
* This predicate is to keep the results identical to the original Java implementation. It should be
15-
* removed once we have the new implementation matching the old results exactly.
16-
*/
17-
predicate ignoreSsaReadCopy(SemExpr e) { none() }
18-
1911
/**
2012
* Ignore the bound on this expression.
2113
*
@@ -24,40 +16,6 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
2416
*/
2517
predicate ignoreExprBound(SemExpr e) { none() }
2618

27-
/**
28-
* Ignore any inferred zero lower bound on this expression.
29-
*
30-
* This predicate is to keep the results identical to the original Java implementation. It should be
31-
* removed once we have the new implementation matching the old results exactly.
32-
*/
33-
predicate ignoreZeroLowerBound(SemExpr e) { none() }
34-
35-
/**
36-
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
37-
*
38-
* This predicate is to keep the results identical to the original Java implementation. It should be
39-
* removed once we have the new implementation matching the old results exactly.
40-
*/
41-
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
42-
43-
/**
44-
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
45-
*
46-
* This predicate is to keep the results identical to the original Java implementation. It should be
47-
* removed once we have the new implementation matching the old results exactly.
48-
*/
49-
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
50-
51-
/**
52-
* Adds additional results to `ssaRead()` that are specific to Java.
53-
*
54-
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
55-
* in exactly the same way as the old Java implementation. Once the new implementation matches the
56-
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
57-
* or not they come from a post-increment/decrement expression.
58-
*/
59-
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
60-
6119
/**
6220
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
6321
*/

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,21 @@ module Sem implements Semantic {
5252

5353
class NegateExpr = SemNegateExpr;
5454

55-
class AddOneExpr = SemAddOneExpr;
55+
class PreIncExpr = SemAddOneExpr;
5656

57-
class SubOneExpr = SemSubOneExpr;
57+
class PreDecExpr = SemSubOneExpr;
58+
59+
class PostIncExpr extends SemUnaryExpr {
60+
PostIncExpr() { none() }
61+
}
62+
63+
class PostDecExpr extends SemUnaryExpr {
64+
PostDecExpr() { none() }
65+
}
66+
67+
class CopyValueExpr extends SemUnaryExpr {
68+
CopyValueExpr() { this instanceof SemCopyValueExpr or this instanceof SemStoreExpr }
69+
}
5870

5971
class ConditionalExpr = SemConditionalExpr;
6072

@@ -116,7 +128,7 @@ module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
116128
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
117129

118130
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
119-
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
131+
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
120132
}
121133
}
122134

@@ -134,7 +146,7 @@ module RelativeBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
134146
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
135147

136148
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
137-
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
149+
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
138150
}
139151
}
140152

@@ -150,7 +162,7 @@ module AllBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
150162
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
151163

152164
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
153-
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
165+
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
154166
}
155167
}
156168

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
99
private import codeql.rangeanalysis.RangeAnalysis
1010

1111
module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
12-
/**
13-
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
14-
*
15-
* This predicate is to keep the results identical to the original Java implementation. It should be
16-
* removed once we have the new implementation matching the old results exactly.
17-
*/
18-
predicate ignoreSsaReadCopy(SemExpr e) { none() }
19-
2012
/**
2113
* Ignore the bound on this expression.
2214
*
@@ -56,40 +48,6 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
5648
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
5749
}
5850

59-
/**
60-
* Ignore any inferred zero lower bound on this expression.
61-
*
62-
* This predicate is to keep the results identical to the original Java implementation. It should be
63-
* removed once we have the new implementation matching the old results exactly.
64-
*/
65-
predicate ignoreZeroLowerBound(SemExpr e) { none() }
66-
67-
/**
68-
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
69-
*
70-
* This predicate is to keep the results identical to the original Java implementation. It should be
71-
* removed once we have the new implementation matching the old results exactly.
72-
*/
73-
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
74-
75-
/**
76-
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
77-
*
78-
* This predicate is to keep the results identical to the original Java implementation. It should be
79-
* removed once we have the new implementation matching the old results exactly.
80-
*/
81-
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
82-
83-
/**
84-
* Adds additional results to `ssaRead()` that are specific to Java.
85-
*
86-
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
87-
* in exactly the same way as the old Java implementation. Once the new implementation matches the
88-
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
89-
* or not they come from a post-increment/decrement expression.
90-
*/
91-
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
92-
9351
/**
9452
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
9553
*/

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,27 @@ module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
1212
/**
1313
* Gets an expression that equals `v - d`.
1414
*/
15-
SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
15+
private SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
1616
// There are various language-specific extension points that can be removed once we no longer
1717
// expect to match the original Java implementation's results exactly.
1818
result = v.getAUse() and delta = D::fromInt(0)
1919
or
2020
exists(D::Delta d1, SemConstantIntegerExpr c |
2121
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
22-
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue()) and
23-
not Lang::ignoreSsaReadArithmeticExpr(result)
22+
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue())
2423
)
2524
or
2625
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
2726
result = sub and
2827
sub.getLeftOperand() = semSsaRead(v, d1) and
2928
sub.getRightOperand() = c and
30-
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue()) and
31-
not Lang::ignoreSsaReadArithmeticExpr(result)
29+
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue())
3230
)
3331
or
3432
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
35-
delta = D::fromFloat(0) and
36-
not Lang::ignoreSsaReadAssignment(v)
33+
delta = D::fromFloat(0)
3734
or
38-
result = Lang::specificSsaRead(v, delta)
39-
or
40-
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta) and
41-
not Lang::ignoreSsaReadCopy(result)
35+
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta)
4236
or
4337
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
4438
}

cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ private import RangeUtils
1515
private import Sign
1616

1717
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
18+
private import codeql.rangeanalysis.internal.RangeUtils::MakeUtils<Sem, D>
19+
1820
/**
1921
* An SSA definition for which the analysis can compute the sign.
2022
*
@@ -297,12 +299,12 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
297299
|
298300
testIsTrue = true and
299301
comp.getLesserOperand() = lowerbound and
300-
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
302+
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
301303
(if comp.isStrict() then isStrict = true else isStrict = false)
302304
or
303305
testIsTrue = false and
304306
comp.getGreaterOperand() = lowerbound and
305-
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
307+
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
306308
(if comp.isStrict() then isStrict = false else isStrict = true)
307309
)
308310
}
@@ -321,12 +323,12 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
321323
|
322324
testIsTrue = true and
323325
comp.getGreaterOperand() = upperbound and
324-
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
326+
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
325327
(if comp.isStrict() then isStrict = true else isStrict = false)
326328
or
327329
testIsTrue = false and
328330
comp.getLesserOperand() = upperbound and
329-
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
331+
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
330332
(if comp.isStrict() then isStrict = false else isStrict = true)
331333
)
332334
}
@@ -342,7 +344,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
342344
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
343345
pos.hasReadOfVar(pragma[only_bind_into](v)) and
344346
semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
345-
e = Utils::semSsaRead(pragma[only_bind_into](v), D::fromInt(0)) and
347+
e = ssaRead(pragma[only_bind_into](v), D::fromInt(0)) and
346348
guard.isEquality(eqbound, e, polarity) and
347349
isEq = polarity.booleanXor(testIsTrue).booleanNot() and
348350
not unknownSign(eqbound)

java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ module Sem implements Semantic {
150150
}
151151
}
152152

153+
predicate isAssignOp(BinaryExpr bin) { bin instanceof AssignOp }
154+
153155
class RelationalExpr = J::ComparisonExpr;
154156

155157
abstract class UnaryExpr extends Expr {
@@ -176,18 +178,34 @@ module Sem implements Semantic {
176178
override Expr getOperand() { result = super.getExpr() }
177179
}
178180

179-
// TODO: Implement once utils are properly shared
180-
class AddOneExpr extends UnaryExpr {
181-
AddOneExpr() { none() }
181+
class PreIncExpr extends UnaryExpr instanceof J::PreIncExpr {
182+
override Expr getOperand() { result = super.getExpr() }
183+
}
182184

183-
override Expr getOperand() { none() }
185+
class PreDecExpr extends UnaryExpr instanceof J::PreDecExpr {
186+
override Expr getOperand() { result = super.getExpr() }
184187
}
185188

186-
// TODO: Implement once utils are properly shared
187-
class SubOneExpr extends UnaryExpr {
188-
SubOneExpr() { none() }
189+
class PostIncExpr extends UnaryExpr instanceof J::PostIncExpr {
190+
override Expr getOperand() { result = super.getExpr() }
191+
}
189192

190-
override Expr getOperand() { none() }
193+
class PostDecExpr extends UnaryExpr instanceof J::PostDecExpr {
194+
override Expr getOperand() { result = super.getExpr() }
195+
}
196+
197+
class CopyValueExpr extends UnaryExpr {
198+
CopyValueExpr() {
199+
this instanceof J::PlusExpr or
200+
this instanceof J::AssignExpr or
201+
this instanceof LocalVariableDeclExpr
202+
}
203+
204+
override Expr getOperand() {
205+
result = this.(J::PlusExpr).getExpr() or
206+
result = this.(J::AssignExpr).getSource() or
207+
result = this.(J::LocalVariableDeclExpr).getInit()
208+
}
191209
}
192210

193211
class ConditionalExpr = J::ConditionalExpr;
@@ -228,7 +246,9 @@ module Sem implements Semantic {
228246

229247
class SsaPhiNode extends SsaVariable instanceof SSA::SsaPhiNode { }
230248

231-
class SsaExplicitUpdate extends SsaVariable instanceof SSA::SsaExplicitUpdate { }
249+
class SsaExplicitUpdate extends SsaVariable instanceof SSA::SsaExplicitUpdate {
250+
Expr getDefiningExpr() { result = super.getDefiningExpr() }
251+
}
232252

233253
final private class FinalSsaReadPosition = SsaReadPos::SsaReadPosition;
234254

@@ -295,8 +315,6 @@ module IntDelta implements DeltaSig {
295315
}
296316

297317
module JavaLangImpl implements LangSig<Sem, IntDelta> {
298-
predicate ignoreSsaReadCopy(Sem::Expr e) { none() }
299-
300318
/**
301319
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
302320
*/
@@ -355,14 +373,6 @@ module JavaLangImpl implements LangSig<Sem, IntDelta> {
355373

356374
predicate ignoreExprBound(Sem::Expr e) { none() }
357375

358-
predicate ignoreZeroLowerBound(Sem::Expr e) { none() }
359-
360-
predicate ignoreSsaReadArithmeticExpr(Sem::Expr e) { none() }
361-
362-
predicate ignoreSsaReadAssignment(Sem::SsaVariable v) { none() }
363-
364-
Sem::Expr specificSsaRead(Sem::SsaVariable v, int delta) { none() }
365-
366376
predicate additionalValueFlowStep(Sem::Expr dest, Sem::Expr src, int delta) { none() }
367377

368378
Sem::Type getAlternateType(Sem::Expr e) { none() }
@@ -376,8 +386,6 @@ module Utils implements UtilSig<Sem, IntDelta> {
376386
private import RangeUtils as RU
377387
private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon as SsaReadPos
378388

379-
Sem::Expr semSsaRead(Sem::SsaVariable v, int delta) { result = RU::ssaRead(v, delta) }
380-
381389
Sem::Guard semEqFlowCond(
382390
Sem::SsaVariable v, Sem::Expr e, int delta, boolean isEq, boolean testIsTrue
383391
) {
@@ -411,7 +419,7 @@ module Bounds implements BoundSig<Location, Sem, IntDelta> {
411419
class SemZeroBound = ZeroBound;
412420

413421
class SemSsaBound extends SsaBound {
414-
Sem::SsaVariable getAVariable() { result = super.getSsa() }
422+
Sem::SsaVariable getVariable() { result = super.getSsa() }
415423
}
416424
}
417425

0 commit comments

Comments
 (0)