Skip to content

Commit 12cba79

Browse files
committed
Java/C++: Move range util guard-controls predicates to shared pack.
1 parent f2ca52d commit 12cba79

File tree

8 files changed

+50
-113
lines changed

8 files changed

+50
-113
lines changed

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

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,4 @@ predicate semImplies_v2(SemGuard g1, boolean b1, SemGuard g2, boolean b2) {
3535
Specific::implies_v2(g1, b1, g2, b2)
3636
}
3737

38-
/**
39-
* Holds if `guard` directly controls the position `controlled` with the
40-
* value `testIsTrue`.
41-
*/
42-
pragma[nomagic]
43-
predicate semGuardDirectlyControlsSsaRead(
44-
SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue
45-
) {
46-
guard.directlyControls(controlled.(SemSsaReadPositionBlock).getBlock(), testIsTrue)
47-
or
48-
exists(SemSsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
49-
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
50-
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
51-
)
52-
}
53-
54-
/**
55-
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
56-
*/
57-
predicate semGuardControlsSsaRead(SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue) {
58-
semGuardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
59-
or
60-
exists(SemGuard guard0, boolean testIsTrue0 |
61-
semImplies_v2(guard0, testIsTrue0, guard, testIsTrue) and
62-
semGuardControlsSsaRead(guard0, controlled, testIsTrue0)
63-
)
64-
}
65-
6638
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,6 @@ module Sem implements Semantic {
7878

7979
predicate implies_v2 = semImplies_v2/4;
8080

81-
predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3;
82-
83-
predicate guardControlsSsaRead = semGuardControlsSsaRead/3;
84-
8581
class Type = SemType;
8682

8783
class IntegerType = SemIntegerType;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
294294
) {
295295
exists(boolean testIsTrue, SemRelationalExpr comp |
296296
pos.hasReadOfVar(v) and
297-
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
297+
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
298298
not unknownSign(lowerbound)
299299
|
300300
testIsTrue = true and
@@ -318,7 +318,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
318318
) {
319319
exists(boolean testIsTrue, SemRelationalExpr comp |
320320
pos.hasReadOfVar(v) and
321-
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
321+
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
322322
not unknownSign(upperbound)
323323
|
324324
testIsTrue = true and
@@ -343,7 +343,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
343343
private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isEq) {
344344
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
345345
pos.hasReadOfVar(pragma[only_bind_into](v)) and
346-
semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
346+
guardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
347347
e = ssaRead(pragma[only_bind_into](v), D::fromInt(0)) and
348348
guard.isEquality(eqbound, e, polarity) and
349349
isEq = polarity.booleanXor(testIsTrue).booleanNot() and

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,6 @@ module Sem implements Semantic {
223223
GL::implies_v2(g1, b1, g2, b2)
224224
}
225225

226-
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
227-
RU::guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
228-
}
229-
230-
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
231-
RU::guardControlsSsaRead(guard, controlled, testIsTrue)
232-
}
233-
234226
class Type = J::Type;
235227

236228
class IntegerType extends J::IntegralType {
@@ -267,6 +259,8 @@ module Sem implements Semantic {
267259
{
268260
BasicBlock getOrigBlock() { result = super.getOrigBlock() }
269261

262+
BasicBlock getPhiBlock() { result = super.getPhiBlock() }
263+
270264
predicate phiInput(SsaPhiNode phi, SsaVariable inp) { super.phiInput(phi, inp) }
271265
}
272266

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

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ private import semmle.code.java.Constants
1010
private import semmle.code.java.dataflow.RangeAnalysis
1111
private import codeql.rangeanalysis.internal.RangeUtils
1212

13-
private predicate backEdge = MakeUtils<Sem, IntDelta>::backEdge/3;
13+
private module U = MakeUtils<Sem, IntDelta>;
14+
15+
private predicate backEdge = U::backEdge/3;
16+
17+
predicate ssaRead = U::ssaRead/2;
18+
19+
predicate guardDirectlyControlsSsaRead = U::guardDirectlyControlsSsaRead/3;
20+
21+
predicate guardControlsSsaRead = U::guardControlsSsaRead/3;
1422

1523
/**
1624
* Holds if `v` is an input to `phi` that is not along a back edge, and the
@@ -149,67 +157,6 @@ class ConstantStringExpr extends Expr {
149157
string getStringValue() { constantStringExpr(this, result) }
150158
}
151159

152-
bindingset[f]
153-
private predicate okInt(float f) { -2.pow(31) <= f and f <= 2.pow(31) - 1 }
154-
155-
/**
156-
* Gets an expression that equals `v - d`.
157-
*/
158-
Expr ssaRead(SsaVariable v, int delta) {
159-
result = v.getAUse() and delta = 0
160-
or
161-
exists(int d1, ConstantIntegerExpr c |
162-
result.(AddExpr).hasOperands(ssaRead(v, d1), c) and
163-
delta = d1 - c.getIntValue() and
164-
okInt(d1.(float) - c.getIntValue().(float))
165-
)
166-
or
167-
exists(SubExpr sub, int d1, ConstantIntegerExpr c |
168-
result = sub and
169-
sub.getLeftOperand() = ssaRead(v, d1) and
170-
sub.getRightOperand() = c and
171-
delta = d1 + c.getIntValue() and
172-
okInt(d1.(float) + c.getIntValue().(float))
173-
)
174-
or
175-
v.(SsaExplicitUpdate).getDefiningExpr().(PreIncExpr) = result and delta = 0
176-
or
177-
v.(SsaExplicitUpdate).getDefiningExpr().(PreDecExpr) = result and delta = 0
178-
or
179-
v.(SsaExplicitUpdate).getDefiningExpr().(PostIncExpr) = result and delta = 1 // x++ === ++x - 1
180-
or
181-
v.(SsaExplicitUpdate).getDefiningExpr().(PostDecExpr) = result and delta = -1 // x-- === --x + 1
182-
or
183-
v.(SsaExplicitUpdate).getDefiningExpr().(Assignment) = result and delta = 0
184-
or
185-
result.(AssignExpr).getSource() = ssaRead(v, delta)
186-
}
187-
188-
/**
189-
* Holds if `guard` directly controls the position `controlled` with the
190-
* value `testIsTrue`.
191-
*/
192-
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
193-
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
194-
or
195-
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
196-
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
197-
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
198-
)
199-
}
200-
201-
/**
202-
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
203-
*/
204-
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
205-
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
206-
or
207-
exists(Guard guard0, boolean testIsTrue0 |
208-
implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
209-
guardControlsSsaRead(guard0, controlled, testIsTrue0)
210-
)
211-
}
212-
213160
/**
214161
* Gets a condition that tests whether `v` equals `e + delta`.
215162
*

shared/rangeanalysis/codeql/rangeanalysis/ModulusAnalysis.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ module ModulusAnalysis<
1717
LocationSig Location, Semantic Sem, DeltaSig D, BoundSig<Location, Sem, D> Bounds,
1818
UtilSig<Sem, D> U>
1919
{
20+
private import internal.RangeUtils::MakeUtils<Sem, D>
21+
2022
bindingset[pos, v]
2123
pragma[inline_late]
2224
private predicate hasReadOfVarInlineLate(Sem::SsaReadPosition pos, Sem::SsaVariable v) {
@@ -35,7 +37,7 @@ module ModulusAnalysis<
3537
exists(Sem::Guard guard, boolean testIsTrue |
3638
hasReadOfVarInlineLate(pos, v) and
3739
guard = U::semEqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
38-
Sem::guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
40+
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
3941
)
4042
}
4143

@@ -107,7 +109,7 @@ module ModulusAnalysis<
107109
exists(Sem::Guard guard, boolean testIsTrue |
108110
pos.hasReadOfVar(v) and
109111
guard = moduloCheck(v, val, mod, testIsTrue) and
110-
Sem::guardControlsSsaRead(guard, pos, testIsTrue)
112+
guardControlsSsaRead(guard, pos, testIsTrue)
111113
)
112114
}
113115

shared/rangeanalysis/codeql/rangeanalysis/RangeAnalysis.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,12 @@ signature module Semantic {
160160
predicate directlyControls(BasicBlock controlled, boolean branch);
161161

162162
predicate isEquality(Expr e1, Expr e2, boolean polarity);
163+
164+
predicate hasBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch);
163165
}
164166

165167
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2);
166168

167-
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue);
168-
169-
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue);
170-
171169
class Type;
172170

173171
class IntegerType extends Type {
@@ -199,6 +197,8 @@ signature module Semantic {
199197
class SsaReadPositionPhiInputEdge extends SsaReadPosition {
200198
BasicBlock getOrigBlock();
201199

200+
BasicBlock getPhiBlock();
201+
202202
predicate phiInput(SsaPhiNode phi, SsaVariable inp);
203203
}
204204

@@ -699,7 +699,7 @@ module RangeStage<
699699
exists(Sem::Guard guard, boolean testIsTrue |
700700
pos.hasReadOfVar(v) and
701701
guard = boundFlowCond(v, e, delta, upper, testIsTrue) and
702-
Sem::guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
702+
guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
703703
reason = TSemCondReason(guard)
704704
)
705705
}
@@ -712,7 +712,7 @@ module RangeStage<
712712
exists(Sem::Guard guard, boolean testIsTrue |
713713
pos.hasReadOfVar(v) and
714714
guard = semEqFlowCond(v, e, delta, false, testIsTrue) and
715-
Sem::guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
715+
guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and
716716
reason = TSemCondReason(guard)
717717
)
718718
}

shared/rangeanalysis/codeql/rangeanalysis/internal/RangeUtils.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,32 @@ module MakeUtils<Semantic Lang, DeltaSig D> {
3535
result.(Lang::CopyValueExpr).getOperand() = ssaRead(v, delta)
3636
}
3737

38+
/**
39+
* Holds if `guard` directly controls the position `controlled` with the
40+
* value `testIsTrue`.
41+
*/
42+
pragma[nomagic]
43+
predicate guardDirectlyControlsSsaRead(Lang::Guard guard, Lang::SsaReadPosition controlled, boolean testIsTrue) {
44+
guard.directlyControls(controlled.(Lang::SsaReadPositionBlock).getBlock(), testIsTrue)
45+
or
46+
exists(Lang::SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
47+
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
48+
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
49+
)
50+
}
51+
52+
/**
53+
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
54+
*/
55+
predicate guardControlsSsaRead(Lang::Guard guard, Lang::SsaReadPosition controlled, boolean testIsTrue) {
56+
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
57+
or
58+
exists(Lang::Guard guard0, boolean testIsTrue0 |
59+
Lang::implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
60+
guardControlsSsaRead(guard0, controlled, testIsTrue0)
61+
)
62+
}
63+
3864
/**
3965
* Holds if `inp` is an input to `phi` along a back edge.
4066
*/

0 commit comments

Comments
 (0)