Skip to content

Commit e53b22d

Browse files
committed
SSA/VariableCapture: Use shared BasicBlock signature.
1 parent bb3abc8 commit e53b22d

File tree

5 files changed

+52
-96
lines changed

5 files changed

+52
-96
lines changed

shared/controlflow/codeql/controlflow/BasicBlock.qll

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ signature module CfgSig<LocationSig Location> {
164164
* means that the edge `(bb1, bb2)` dominates `bb3`.
165165
*/
166166
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2);
167+
168+
/** Holds if `bb` is an entry basic block. */
169+
predicate entryBlock(BasicBlock bb);
167170
}
168171

169172
/**
@@ -398,6 +401,9 @@ module Make<LocationSig Location, InputSig<Location> Input> implements CfgSig<Lo
398401
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
399402
}
400403

404+
/** Holds if `bb` is an entry basic block. */
405+
predicate entryBlock(BasicBlock bb) { nodeIsDominanceEntry(bb.getFirstNode()) }
406+
401407
cached
402408
private module Cached {
403409
private Node nodeGetAPredecessor(Node node, SuccessorType s) {
@@ -466,9 +472,6 @@ module Make<LocationSig Location, InputSig<Location> Input> implements CfgSig<Lo
466472
cached
467473
Node getNode(BasicBlock bb, int pos) { bbIndex(bb.getFirstNode(), result, pos) }
468474

469-
/** Holds if `bb` is an entry basic block. */
470-
private predicate entryBB(BasicBlock bb) { nodeIsDominanceEntry(bb.getFirstNode()) }
471-
472475
cached
473476
predicate bbSuccessor(BasicBlock bb1, BasicBlock bb2, SuccessorType t) {
474477
bb2.getFirstNode() = nodeGetASuccessor(bb1.getLastNode(), t)
@@ -483,7 +486,7 @@ module Make<LocationSig Location, InputSig<Location> Input> implements CfgSig<Lo
483486
/** Holds if `dom` is an immediate dominator of `bb`. */
484487
cached
485488
predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
486-
idominance(entryBB/1, succBB/2)(_, dom, bb)
489+
idominance(entryBlock/1, succBB/2)(_, dom, bb)
487490

488491
/** Holds if `pred` is a basic block predecessor of `succ`. */
489492
private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }

shared/dataflow/codeql/dataflow/VariableCapture.qll

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,14 @@ module;
88
private import codeql.util.Boolean
99
private import codeql.util.Unit
1010
private import codeql.util.Location
11+
private import codeql.controlflow.BasicBlock as BB
1112
private import codeql.ssa.Ssa as Ssa
1213

13-
signature module InputSig<LocationSig Location> {
14-
/**
15-
* A basic block, that is, a maximal straight-line sequence of control flow nodes
16-
* without branches or joins.
17-
*/
18-
class BasicBlock {
19-
/** Gets a textual representation of this basic block. */
20-
string toString();
21-
22-
/** Gets the `i`th node in this basic block. */
23-
ControlFlowNode getNode(int i);
14+
signature class BasicBlockSig;
2415

25-
/** Gets the length of this basic block. */
26-
int length();
27-
28-
/** Gets the enclosing callable. */
29-
Callable getEnclosingCallable();
30-
31-
/** Gets the location of this basic block. */
32-
Location getLocation();
33-
34-
BasicBlock getASuccessor();
35-
36-
BasicBlock getImmediateDominator();
37-
38-
predicate inDominanceFrontier(BasicBlock df);
39-
}
40-
41-
/** A control flow node. */
42-
class ControlFlowNode {
43-
/** Gets a textual representation of this control flow node. */
44-
string toString();
45-
46-
/** Gets the location of this control flow node. */
47-
Location getLocation();
48-
}
49-
50-
/** Holds if `bb` is a control-flow entry point. */
51-
default predicate entryBlock(BasicBlock bb) { not exists(bb.getImmediateDominator()) }
16+
signature module InputSig<LocationSig Location, BasicBlockSig BasicBlock> {
17+
/** Gets the enclosing callable of the basic block. */
18+
Callable basicBlockGetEnclosingCallable(BasicBlock bb);
5219

5320
/** A variable that is captured in a closure. */
5421
class CapturedVariable {
@@ -134,7 +101,9 @@ signature module InputSig<LocationSig Location> {
134101
}
135102
}
136103

137-
signature module OutputSig<LocationSig Location, InputSig<Location> I> {
104+
signature module OutputSig<
105+
LocationSig Location, BasicBlockSig BasicBlock, InputSig<Location, BasicBlock> I>
106+
{
138107
/**
139108
* A data flow node that we need to reference in the step relations for
140109
* captured variables.
@@ -236,9 +205,18 @@ signature module OutputSig<LocationSig Location, InputSig<Location> I> {
236205
* Constructs the type `ClosureNode` and associated step relations, which are
237206
* intended to be included in the data-flow node and step relations.
238207
*/
239-
module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig<Location, Input> {
208+
module Flow<
209+
LocationSig Location, BB::CfgSig<Location> Cfg, InputSig<Location, Cfg::BasicBlock> Input>
210+
implements OutputSig<Location, Cfg::BasicBlock, Input>
211+
{
240212
private import Input
241213

214+
final private class CfgBb = Cfg::BasicBlock;
215+
216+
private class BasicBlock extends CfgBb {
217+
Callable getEnclosingCallable() { result = basicBlockGetEnclosingCallable(this) }
218+
}
219+
242220
additional module ConsistencyChecks {
243221
final private class FinalExpr = Expr;
244222

@@ -318,12 +296,12 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
318296

319297
query predicate localDominator(RelevantBasicBlock bb, string msg) {
320298
msg = "BasicBlock has non-local dominator" and
321-
bb.getEnclosingCallable() != bb.getImmediateDominator().getEnclosingCallable()
299+
bb.getEnclosingCallable() != bb.getImmediateDominator().(BasicBlock).getEnclosingCallable()
322300
}
323301

324302
query predicate localSuccessor(RelevantBasicBlock bb, string msg) {
325303
msg = "BasicBlock has non-local successor" and
326-
bb.getEnclosingCallable() != bb.getASuccessor().getEnclosingCallable()
304+
bb.getEnclosingCallable() != bb.getASuccessor().(BasicBlock).getEnclosingCallable()
327305
}
328306

329307
query predicate uniqueDefiningScope(CapturedVariable v, string msg) {
@@ -650,7 +628,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
650628
/** Holds if `cc` needs a definition at the entry of its callable scope. */
651629
private predicate entryDef(CaptureContainer cc, BasicBlock bb, int i) {
652630
exists(Callable c |
653-
entryBlock(bb) and
631+
Cfg::entryBlock(bb) and
654632
pragma[only_bind_out](bb.getEnclosingCallable()) = c and
655633
i =
656634
min(int j |
@@ -666,14 +644,10 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
666644
)
667645
}
668646

669-
private module CaptureSsaInput implements Ssa::InputSig<Location> {
670-
final class BasicBlock = Input::BasicBlock;
671-
672-
final class ControlFlowNode = Input::ControlFlowNode;
673-
647+
private module CaptureSsaInput implements Ssa::InputSig<Location, Cfg::BasicBlock> {
674648
class SourceVariable = CaptureContainer;
675649

676-
predicate variableWrite(BasicBlock bb, int i, SourceVariable cc, boolean certain) {
650+
predicate variableWrite(Cfg::BasicBlock bb, int i, SourceVariable cc, boolean certain) {
677651
Cached::ref() and
678652
(
679653
exists(CapturedVariable v | cc = TVariable(v) and captureWrite(v, bb, i, true, _))
@@ -683,9 +657,9 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
683657
certain = true
684658
}
685659

686-
predicate variableRead(BasicBlock bb, int i, SourceVariable cc, boolean certain) {
660+
predicate variableRead(Cfg::BasicBlock bb, int i, SourceVariable cc, boolean certain) {
687661
(
688-
synthThisQualifier(bb, i) and cc = TThis(bb.getEnclosingCallable())
662+
synthThisQualifier(bb, i) and cc = TThis(bb.(BasicBlock).getEnclosingCallable())
689663
or
690664
exists(CapturedVariable v | cc = TVariable(v) |
691665
captureRead(v, bb, i, true, _) or synthRead(v, bb, i, true, _)
@@ -695,26 +669,30 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
695669
}
696670
}
697671

698-
private module CaptureSsa = Ssa::Make<Location, CaptureSsaInput>;
672+
private module CaptureSsa = Ssa::Make<Location, Cfg, CaptureSsaInput>;
699673

700674
private module DataFlowIntegrationInput implements CaptureSsa::DataFlowIntegrationInputSig {
701675
private import codeql.util.Void
702676

703-
class Expr instanceof Input::ControlFlowNode {
677+
class Expr instanceof Cfg::ControlFlowNode {
704678
string toString() { result = super.toString() }
705679

706-
predicate hasCfgNode(BasicBlock bb, int i) { bb.getNode(i) = this }
680+
predicate hasCfgNode(Cfg::BasicBlock bb, int i) { bb.getNode(i) = this }
707681
}
708682

709683
class GuardValue = Void;
710684

711685
class Guard extends Void {
712-
predicate hasValueBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue val) { none() }
686+
predicate hasValueBranchEdge(Cfg::BasicBlock bb1, Cfg::BasicBlock bb2, GuardValue val) {
687+
none()
688+
}
713689

714-
predicate valueControlsBranchEdge(BasicBlock bb1, BasicBlock bb2, GuardValue val) { none() }
690+
predicate valueControlsBranchEdge(Cfg::BasicBlock bb1, Cfg::BasicBlock bb2, GuardValue val) {
691+
none()
692+
}
715693
}
716694

717-
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, GuardValue val) { none() }
695+
predicate guardDirectlyControlsBlock(Guard guard, Cfg::BasicBlock bb, GuardValue val) { none() }
718696

719697
predicate includeWriteDefsInFlowStep() { none() }
720698

shared/dataflow/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ version: 2.0.14-dev
33
groups: shared
44
library: true
55
dependencies:
6+
codeql/controlflow: ${workspace}
67
codeql/ssa: ${workspace}
78
codeql/typetracking: ${workspace}
89
codeql/util: ${workspace}

shared/ssa/codeql/ssa/Ssa.qll

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,14 @@
55
overlay[local?]
66
module;
77

8+
private import codeql.controlflow.BasicBlock as BB
89
private import codeql.util.Location
910
private import codeql.util.Unit
1011

11-
/** Provides the input specification of the SSA implementation. */
12-
signature module InputSig<LocationSig Location> {
13-
/**
14-
* A basic block, that is, a maximal straight-line sequence of control flow nodes
15-
* without branches or joins.
16-
*/
17-
class BasicBlock {
18-
/** Gets a textual representation of this basic block. */
19-
string toString();
20-
21-
/** Gets the `i`th node in this basic block. */
22-
ControlFlowNode getNode(int i);
23-
24-
/** Gets the length of this basic block. */
25-
int length();
26-
27-
/** Gets the location of this basic block. */
28-
Location getLocation();
29-
30-
BasicBlock getASuccessor();
31-
32-
BasicBlock getImmediateDominator();
33-
34-
predicate inDominanceFrontier(BasicBlock df);
35-
}
36-
37-
/** A control flow node. */
38-
class ControlFlowNode {
39-
/** Gets a textual representation of this control flow node. */
40-
string toString();
41-
42-
/** Gets the location of this control flow node. */
43-
Location getLocation();
44-
}
12+
signature class BasicBlockSig;
4513

14+
/** Provides the input specification of the SSA implementation. */
15+
signature module InputSig<LocationSig Location, BasicBlockSig BasicBlock> {
4616
/** A variable that can be SSA converted. */
4717
class SourceVariable {
4818
/** Gets a textual representation of this variable. */
@@ -89,7 +59,10 @@ signature module InputSig<LocationSig Location> {
8959
* NB: If this predicate is exposed, it should be cached.
9060
* ```
9161
*/
92-
module Make<LocationSig Location, InputSig<Location> Input> {
62+
module Make<
63+
LocationSig Location, BB::CfgSig<Location> Cfg, InputSig<Location, Cfg::BasicBlock> Input>
64+
{
65+
private import Cfg
9366
private import Input
9467

9568
private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { result.getASuccessor() = bb }

shared/ssa/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ version: 2.0.6-dev
33
groups: shared
44
library: true
55
dependencies:
6+
codeql/controlflow: ${workspace}
67
codeql/util: ${workspace}
78
warnOnImplicitThis: true

0 commit comments

Comments
 (0)