Skip to content

Commit e8e9403

Browse files
authored
Merge pull request #19093 from aschackmull/java/caching
Java: Adjust caching of BasicBlocks, BaseSSA, and CompileTimeConstants
2 parents 4572376 + dc0ca1a commit e8e9403

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

java/ql/lib/semmle/code/java/Expr.qll

+2-2
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class CompileTimeConstantExpr extends Expr {
180180
/**
181181
* Gets the string value of this expression, where possible.
182182
*/
183-
pragma[nomagic]
183+
cached
184184
string getStringValue() {
185185
result = this.(StringLiteral).getValue()
186186
or
@@ -205,7 +205,7 @@ class CompileTimeConstantExpr extends Expr {
205205
/**
206206
* Gets the boolean value of this expression, where possible.
207207
*/
208-
pragma[nomagic]
208+
cached
209209
boolean getBooleanValue() {
210210
// Literal value.
211211
result = this.(BooleanLiteral).getBooleanValue()

java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll

+28-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,31 @@
55
import java
66
import Dominance
77

8+
cached
9+
private module BasicBlockStage {
10+
cached
11+
predicate ref() { any() }
12+
13+
cached
14+
predicate backref() {
15+
(exists(any(BasicBlock bb).getABBSuccessor()) implies any()) and
16+
(exists(any(BasicBlock bb).getNode(_)) implies any()) and
17+
(exists(any(BasicBlock bb).length()) implies any())
18+
}
19+
}
20+
821
/**
922
* A control-flow node that represents the start of a basic block.
1023
*
1124
* A basic block is a series of nodes with no control-flow branching, which can
1225
* often be treated as a unit in analyses.
1326
*/
1427
class BasicBlock extends ControlFlowNode {
28+
cached
1529
BasicBlock() {
16-
not exists(this.getAPredecessor()) and exists(this.getASuccessor())
30+
BasicBlockStage::ref() and
31+
not exists(this.getAPredecessor()) and
32+
exists(this.getASuccessor())
1733
or
1834
strictcount(this.getAPredecessor()) > 1
1935
or
@@ -24,7 +40,10 @@ class BasicBlock extends ControlFlowNode {
2440

2541
/** Gets an immediate successor of this basic block. */
2642
cached
27-
BasicBlock getABBSuccessor() { result = this.getLastNode().getASuccessor() }
43+
BasicBlock getABBSuccessor() {
44+
BasicBlockStage::ref() and
45+
result = this.getLastNode().getASuccessor()
46+
}
2847

2948
/** Gets an immediate predecessor of this basic block. */
3049
BasicBlock getABBPredecessor() { result.getABBSuccessor() = this }
@@ -35,7 +54,9 @@ class BasicBlock extends ControlFlowNode {
3554
/** Gets the control-flow node at a specific (zero-indexed) position in this basic block. */
3655
cached
3756
ControlFlowNode getNode(int pos) {
38-
result = this and pos = 0
57+
BasicBlockStage::ref() and
58+
result = this and
59+
pos = 0
3960
or
4061
exists(ControlFlowNode mid, int mid_pos | pos = mid_pos + 1 |
4162
this.getNode(mid_pos) = mid and
@@ -52,7 +73,10 @@ class BasicBlock extends ControlFlowNode {
5273

5374
/** Gets the number of control-flow nodes contained in this basic block. */
5475
cached
55-
int length() { result = strictcount(this.getANode()) }
76+
int length() {
77+
BasicBlockStage::ref() and
78+
result = strictcount(this.getANode())
79+
}
5680

5781
/** Holds if this basic block strictly dominates `node`. */
5882
predicate bbStrictlyDominates(BasicBlock node) { bbStrictlyDominates(this, node) }

java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll

+20-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,26 @@
1414
import java
1515
private import codeql.ssa.Ssa as SsaImplCommon
1616

17+
cached
18+
private module BaseSsaStage {
19+
cached
20+
predicate ref() { any() }
21+
22+
cached
23+
predicate backref() {
24+
(exists(TLocalVar(_, _)) implies any()) and
25+
(exists(any(BaseSsaSourceVariable v).getAnAccess()) implies any()) and
26+
(exists(getAUse(_)) implies any())
27+
}
28+
}
29+
30+
cached
1731
private newtype TBaseSsaSourceVariable =
1832
TLocalVar(Callable c, LocalScopeVariable v) {
19-
c = v.getCallable() or c = v.getAnAccess().getEnclosingCallable()
33+
BaseSsaStage::ref() and
34+
c = v.getCallable()
35+
or
36+
c = v.getAnAccess().getEnclosingCallable()
2037
}
2138

2239
/**
@@ -31,6 +48,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable {
3148
*/
3249
cached
3350
VarAccess getAnAccess() {
51+
BaseSsaStage::ref() and
3452
exists(LocalScopeVariable v, Callable c |
3553
this = TLocalVar(c, v) and result = v.getAnAccess() and result.getEnclosingCallable() = c
3654
)
@@ -188,6 +206,7 @@ cached
188206
private module Cached {
189207
cached
190208
VarRead getAUse(Impl::Definition def) {
209+
BaseSsaStage::ref() and
191210
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
192211
Impl::ssaDefReachesRead(v, def, bb, i) and
193212
result.getControlFlowNode() = bb.getNode(i) and

java/ql/lib/semmle/code/java/environment/SystemProperty.qll

+12-6
Original file line numberDiff line numberDiff line change
@@ -269,18 +269,24 @@ private MethodCall getSystemPropertyFromSpringProperties(string propertyName) {
269269
* for final variables.
270270
*/
271271
private predicate localExprFlowPlusInitializers(Expr e1, Expr e2) {
272+
e1 = e2 or
272273
localFlowPlusInitializers(DataFlow::exprNode(e1), DataFlow::exprNode(e2))
273274
}
274275

276+
private predicate localFlowPlusInitializers(DataFlow::Node pred, DataFlow::Node succ) =
277+
fastTC(localFlowStepPlusInitializers/2)(pred, succ)
278+
275279
/**
276-
* Holds if data can flow from `pred` to `succ` in zero or more
277-
* local (intra-procedural) steps or via instance or static variable intializers
280+
* Holds if data can flow from `pred` to `succ` in a
281+
* local (intra-procedural) step or via instance or static variable intializers
278282
* for final variables.
279283
*/
280-
private predicate localFlowPlusInitializers(DataFlow::Node pred, DataFlow::Node succ) {
281-
exists(Variable v | v.isFinal() and pred.asExpr() = v.getInitializer() |
282-
DataFlow::localFlow(DataFlow::exprNode(v.getAnAccess()), succ)
284+
private predicate localFlowStepPlusInitializers(DataFlow::Node pred, DataFlow::Node succ) {
285+
exists(Variable v |
286+
v.isFinal() and
287+
pred.asExpr() = v.getInitializer() and
288+
succ.asExpr() = v.getAnAccess()
283289
)
284290
or
285-
DataFlow::localFlow(pred, succ)
291+
DataFlow::localFlowStep(pred, succ)
286292
}

0 commit comments

Comments
 (0)