Skip to content

Commit 45ae4ed

Browse files
authored
Merge pull request #14711 from aschackmull/shared/rangeutil-share2
Java/C++/RangeAnalysis: Move a couple of utility predicates to shared qlpack
2 parents a8eed6b + 12cba79 commit 45ae4ed

File tree

11 files changed

+107
-173
lines changed

11 files changed

+107
-173
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ class SemBasicBlock extends Specific::BasicBlock {
1212
/** Holds if this block (transitively) dominates `otherblock`. */
1313
final predicate bbDominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
1414

15-
/** Holds if this block has dominance information. */
16-
final predicate hasDominanceInformation() { Specific::hasDominanceInformation(this) }
17-
1815
/** Gets an expression that is evaluated in this basic block. */
1916
final SemExpr getAnExpr() { result.getBasicBlock() = this }
2017

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ module SemanticExprConfig {
122122
dominator.dominates(dominated)
123123
}
124124

125-
predicate hasDominanceInformation(BasicBlock block) { any() }
126-
127125
private predicate id(Cpp::Locatable x, Cpp::Locatable y) { x = y }
128126

129127
private predicate idOf(Cpp::Locatable x, int y) = equivalenceRelation(id/2)(x, y)

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/SemanticSSA.qll

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -63,36 +63,3 @@ class SemSsaReadPositionBlock extends SemSsaReadPosition {
6363

6464
SemExpr getAnExpr() { result = this.getBlock().getAnExpr() }
6565
}
66-
67-
/**
68-
* Holds if `inp` is an input to `phi` along a back edge.
69-
*/
70-
predicate semBackEdge(SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge) {
71-
edge.phiInput(phi, inp) and
72-
// Conservatively assume that every edge is a back edge if we don't have dominance information.
73-
(
74-
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
75-
irreducibleSccEdge(edge.getOrigBlock(), phi.getBasicBlock()) or
76-
not edge.getOrigBlock().hasDominanceInformation()
77-
)
78-
}
79-
80-
/**
81-
* Holds if the edge from b1 to b2 is part of a multiple-entry cycle in an irreducible control flow
82-
* graph.
83-
*
84-
* An ireducible control flow graph is one where the usual dominance-based back edge detection does
85-
* not work, because there is a cycle with multiple entry points, meaning there are
86-
* mutually-reachable basic blocks where neither dominates the other. For such a graph, we first
87-
* remove all detectable back-edges using the normal condition that the predecessor block is
88-
* dominated by the successor block, then mark all edges in a cycle in the resulting graph as back
89-
* edges.
90-
*/
91-
private predicate irreducibleSccEdge(SemBasicBlock b1, SemBasicBlock b2) {
92-
trimmedEdge(b1, b2) and trimmedEdge+(b2, b1)
93-
}
94-
95-
private predicate trimmedEdge(SemBasicBlock pred, SemBasicBlock succ) {
96-
pred.getASuccessor() = succ and
97-
not succ.bbDominates(pred)
98-
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,12 @@ module Sem implements Semantic {
7272

7373
class BasicBlock = SemBasicBlock;
7474

75+
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
76+
7577
class Guard = SemGuard;
7678

7779
predicate implies_v2 = semImplies_v2/4;
7880

79-
predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3;
80-
81-
predicate guardControlsSsaRead = semGuardControlsSsaRead/3;
82-
8381
class Type = SemType;
8482

8583
class IntegerType = SemIntegerType;
@@ -100,8 +98,6 @@ module Sem implements Semantic {
10098

10199
class SsaReadPositionBlock = SemSsaReadPositionBlock;
102100

103-
predicate backEdge = semBackEdge/3;
104-
105101
predicate conversionCannotOverflow(Type fromType, Type toType) {
106102
SemanticType::conversionCannotOverflow(fromType, toType)
107103
}

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: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -211,22 +211,18 @@ module Sem implements Semantic {
211211

212212
class BasicBlock = J::BasicBlock;
213213

214-
class Guard extends GL::Guard {
214+
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
215+
216+
final private class FinalGuard = GL::Guard;
217+
218+
class Guard extends FinalGuard {
215219
Expr asExpr() { result = this }
216220
}
217221

218222
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
219223
GL::implies_v2(g1, b1, g2, b2)
220224
}
221225

222-
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
223-
RU::guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
224-
}
225-
226-
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
227-
RU::guardControlsSsaRead(guard, controlled, testIsTrue)
228-
}
229-
230226
class Type = J::Type;
231227

232228
class IntegerType extends J::IntegralType {
@@ -261,17 +257,17 @@ module Sem implements Semantic {
261257

262258
class SsaReadPositionPhiInputEdge extends SsaReadPosition instanceof SsaReadPos::SsaReadPositionPhiInputEdge
263259
{
260+
BasicBlock getOrigBlock() { result = super.getOrigBlock() }
261+
262+
BasicBlock getPhiBlock() { result = super.getPhiBlock() }
263+
264264
predicate phiInput(SsaPhiNode phi, SsaVariable inp) { super.phiInput(phi, inp) }
265265
}
266266

267267
class SsaReadPositionBlock extends SsaReadPosition instanceof SsaReadPos::SsaReadPositionBlock {
268268
BasicBlock getBlock() { result = super.getBlock() }
269269
}
270270

271-
predicate backEdge(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge) {
272-
RU::backEdge(phi, inp, edge)
273-
}
274-
275271
predicate conversionCannotOverflow = safeCast/2;
276272
}
277273

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

Lines changed: 12 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ private import SSA
77
private import semmle.code.java.controlflow.internal.GuardsLogic
88
private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon
99
private import semmle.code.java.Constants
10+
private import semmle.code.java.dataflow.RangeAnalysis
11+
private import codeql.rangeanalysis.internal.RangeUtils
12+
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;
1022

1123
/**
1224
* Holds if `v` is an input to `phi` that is not along a back edge, and the
@@ -145,79 +157,6 @@ class ConstantStringExpr extends Expr {
145157
string getStringValue() { constantStringExpr(this, result) }
146158
}
147159

148-
bindingset[f]
149-
private predicate okInt(float f) { -2.pow(31) <= f and f <= 2.pow(31) - 1 }
150-
151-
/**
152-
* Gets an expression that equals `v - d`.
153-
*/
154-
Expr ssaRead(SsaVariable v, int delta) {
155-
result = v.getAUse() and delta = 0
156-
or
157-
exists(int d1, ConstantIntegerExpr c |
158-
result.(AddExpr).hasOperands(ssaRead(v, d1), c) and
159-
delta = d1 - c.getIntValue() and
160-
okInt(d1.(float) - c.getIntValue().(float))
161-
)
162-
or
163-
exists(SubExpr sub, int d1, ConstantIntegerExpr c |
164-
result = sub and
165-
sub.getLeftOperand() = ssaRead(v, d1) and
166-
sub.getRightOperand() = c and
167-
delta = d1 + c.getIntValue() and
168-
okInt(d1.(float) + c.getIntValue().(float))
169-
)
170-
or
171-
v.(SsaExplicitUpdate).getDefiningExpr().(PreIncExpr) = result and delta = 0
172-
or
173-
v.(SsaExplicitUpdate).getDefiningExpr().(PreDecExpr) = result and delta = 0
174-
or
175-
v.(SsaExplicitUpdate).getDefiningExpr().(PostIncExpr) = result and delta = 1 // x++ === ++x - 1
176-
or
177-
v.(SsaExplicitUpdate).getDefiningExpr().(PostDecExpr) = result and delta = -1 // x-- === --x + 1
178-
or
179-
v.(SsaExplicitUpdate).getDefiningExpr().(Assignment) = result and delta = 0
180-
or
181-
result.(AssignExpr).getSource() = ssaRead(v, delta)
182-
}
183-
184-
/**
185-
* Holds if `inp` is an input to `phi` along a back edge.
186-
*/
187-
predicate backEdge(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge) {
188-
edge.phiInput(phi, inp) and
189-
// Conservatively assume that every edge is a back edge if we don't have dominance information.
190-
(
191-
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
192-
not hasDominanceInformation(edge.getOrigBlock())
193-
)
194-
}
195-
196-
/**
197-
* Holds if `guard` directly controls the position `controlled` with the
198-
* value `testIsTrue`.
199-
*/
200-
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
201-
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
202-
or
203-
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
204-
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
205-
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
206-
)
207-
}
208-
209-
/**
210-
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
211-
*/
212-
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
213-
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
214-
or
215-
exists(Guard guard0, boolean testIsTrue0 |
216-
implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
217-
guardControlsSsaRead(guard0, controlled, testIsTrue0)
218-
)
219-
}
220-
221160
/**
222161
* Gets a condition that tests whether `v` equals `e + delta`.
223162
*

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

0 commit comments

Comments
 (0)