Skip to content

Commit 19644a8

Browse files
committed
Rangeanalysis: Implement shared ssaRead predicate
1 parent e9cb272 commit 19644a8

File tree

5 files changed

+97
-16
lines changed

5 files changed

+97
-16
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/RangeAnalysisImpl.qll

Lines changed: 14 additions & 2 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

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

Lines changed: 29 additions & 9 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

shared/rangeanalysis/codeql/rangeanalysis/RangeAnalysis.qll

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ signature module Semantic {
106106

107107
class ShiftRightUnsignedExpr extends BinaryExpr;
108108

109+
default predicate isAssignOp(BinaryExpr bin) { none() }
110+
109111
class RelationalExpr extends Expr {
110112
Expr getLesserOperand();
111113

@@ -126,9 +128,15 @@ signature module Semantic {
126128

127129
class NegateExpr extends UnaryExpr;
128130

129-
class AddOneExpr extends UnaryExpr;
131+
class PreIncExpr extends UnaryExpr;
132+
133+
class PreDecExpr extends UnaryExpr;
134+
135+
class PostIncExpr extends UnaryExpr;
130136

131-
class SubOneExpr extends UnaryExpr;
137+
class PostDecExpr extends UnaryExpr;
138+
139+
class CopyValueExpr extends UnaryExpr;
132140

133141
class ConditionalExpr extends Expr {
134142
Expr getBranchExpr(boolean branch);
@@ -168,7 +176,9 @@ signature module Semantic {
168176

169177
class SsaPhiNode extends SsaVariable;
170178

171-
class SsaExplicitUpdate extends SsaVariable;
179+
class SsaExplicitUpdate extends SsaVariable {
180+
Expr getDefiningExpr();
181+
}
172182

173183
class SsaReadPosition {
174184
predicate hasReadOfVar(SsaVariable v);
@@ -1188,12 +1198,12 @@ module RangeStage<
11881198
positively = false and
11891199
(
11901200
expr instanceof Sem::NegateExpr or
1191-
expr instanceof Sem::SubOneExpr or
1201+
expr instanceof Sem::PreDecExpr or
11921202
getTrackedType(expr.(Sem::DivExpr)) instanceof Sem::FloatingPointType
11931203
)
11941204
or
11951205
positively = true and
1196-
expr instanceof Sem::AddOneExpr
1206+
expr instanceof Sem::PreIncExpr
11971207
}
11981208

11991209
/**
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
private import codeql.rangeanalysis.RangeAnalysis
2+
3+
module MakeUtils<Semantic Lang, DeltaSig D> {
4+
/**
5+
* Gets an expression that equals `v - d`.
6+
*/
7+
Lang::Expr ssaRead(Lang::SsaVariable v, D::Delta delta) {
8+
result = v.getAUse() and delta = D::fromInt(0)
9+
or
10+
exists(D::Delta d1, Lang::ConstantIntegerExpr c |
11+
result.(Lang::AddExpr).hasOperands(ssaRead(v, d1), c) and
12+
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue()) and
13+
// In the scope of `x += ..`, which is SSA translated as `x2 = x1 + ..`,
14+
// the variable `x1` is shadowed by `x2`, so there's no need to view this
15+
// as a read of `x1`.
16+
not Lang::isAssignOp(result)
17+
)
18+
or
19+
exists(Lang::SubExpr sub, D::Delta d1, Lang::ConstantIntegerExpr c |
20+
result = sub and
21+
sub.getLeftOperand() = ssaRead(v, d1) and
22+
sub.getRightOperand() = c and
23+
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue()) and
24+
not Lang::isAssignOp(result)
25+
)
26+
or
27+
result = v.(Lang::SsaExplicitUpdate).getDefiningExpr() and
28+
if result instanceof Lang::PostIncExpr
29+
then delta = D::fromFloat(1) // x++ === ++x - 1
30+
else
31+
if result instanceof Lang::PostDecExpr
32+
then delta = D::fromFloat(-1) // x-- === --x + 1
33+
else delta = D::fromFloat(0)
34+
or
35+
result.(Lang::CopyValueExpr).getOperand() = ssaRead(v, delta)
36+
}
37+
}

0 commit comments

Comments
 (0)