Skip to content

Commit 0e5255e

Browse files
committed
Swift: switch to shared, parameterized CFG library
1 parent 307da34 commit 0e5255e

File tree

10 files changed

+157
-1201
lines changed

10 files changed

+157
-1201
lines changed

swift/ql/lib/codeql/swift/controlflow/BasicBlocks.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof EntryNod
167167
class EntryBasicBlock extends BasicBlock {
168168
EntryBasicBlock() { entryBB(this) }
169169

170-
override CfgScope getScope() { this.getFirstNode() = TEntryNode(result) }
170+
override CfgScope getScope() { this.getFirstNode() = any(EntryNode node | node.getScope() = result) }
171171
}
172172

173173
/**

swift/ql/lib/codeql/swift/controlflow/CfgNodes.qll

Lines changed: 24 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -7,104 +7,35 @@ private import internal.ControlFlowGraphImpl
77
private import internal.ControlFlowElements
88
private import internal.Splitting
99

10-
/** An entry node for a given scope. */
11-
class EntryNode extends ControlFlowNode, TEntryNode {
12-
private CfgScope scope;
13-
14-
EntryNode() { this = TEntryNode(scope) }
15-
16-
final override EntryBasicBlock getBasicBlock() { result = ControlFlowNode.super.getBasicBlock() }
17-
18-
final override Location getLocation() { result = scope.getLocation() }
19-
20-
final override string toString() { result = "enter " + scope }
21-
}
22-
23-
/** An exit node for a given scope, annotated with the type of exit. */
24-
class AnnotatedExitNode extends ControlFlowNode, TAnnotatedExitNode {
25-
private CfgScope scope;
26-
private boolean normal;
27-
28-
AnnotatedExitNode() { this = TAnnotatedExitNode(scope, normal) }
29-
30-
/** Holds if this node represent a normal exit. */
31-
final predicate isNormal() { normal = true }
32-
33-
final override AnnotatedExitBasicBlock getBasicBlock() {
34-
result = ControlFlowNode.super.getBasicBlock()
35-
}
36-
37-
final override Location getLocation() { result = scope.getLocation() }
38-
39-
final override string toString() {
40-
exists(string s |
41-
normal = true and s = "normal"
42-
or
43-
normal = false and s = "abnormal"
44-
|
45-
result = "exit " + scope + " (" + s + ")"
46-
)
47-
}
48-
}
49-
50-
/** An exit node for a given scope. */
51-
class ExitNode extends ControlFlowNode, TExitNode {
52-
private CfgScope scope;
53-
54-
ExitNode() { this = TExitNode(scope) }
55-
56-
final override Location getLocation() { result = scope.getLocation() }
57-
58-
final override string toString() { result = "exit " + scope }
59-
}
60-
6110
/**
6211
* A node for an AST node.
6312
*
6413
* Each AST node maps to zero or more `CfgNode`s: zero when the node is unreachable
6514
* (dead) code or not important for control flow, and multiple when there are different
6615
* splits for the AST node.
6716
*/
68-
class CfgNode extends ControlFlowNode, TElementNode {
69-
private Splits splits;
70-
ControlFlowElement n;
17+
class CfgNode extends ControlFlowNode instanceof AstCfgNode {
18+
final override ControlFlowElement getNode() { result = this.getAstNode() }
7119

72-
CfgNode() { this = TElementNode(_, n, splits) }
73-
74-
final override ControlFlowElement getNode() { result = n }
75-
76-
override Location getLocation() { result = n.getLocation() }
77-
78-
final override string toString() {
79-
exists(string s | s = n.toString() |
80-
result = "[" + this.getSplitsString() + "] " + s
81-
or
82-
not exists(this.getSplitsString()) and result = s
83-
)
84-
}
20+
/** Gets a split for this control flow node, if any. */
21+
final Split getASplit() { result = super.getASplit() }
8522

8623
/** Gets a comma-separated list of strings for each split in this node, if any. */
87-
final string getSplitsString() {
88-
result = splits.toString() and
89-
result != ""
90-
}
91-
92-
/** Gets a split for this control flow node, if any. */
93-
final Split getASplit() { result = splits.getASplit() }
24+
final string getSplitsString() { result = super.getSplitsString() }
9425

9526
/** Gets the AST representation of this control flow node, if any. */
9627
Expr getAst() {
97-
result = n.asAstNode()
28+
result = this.getNode().asAstNode()
9829
or
99-
result = n.(PropertyGetterElement).getRef()
30+
result = this.getNode().(PropertyGetterElement).getRef()
10031
or
101-
result = n.(PropertySetterElement).getAssignExpr()
32+
result = this.getNode().(PropertySetterElement).getAssignExpr()
10233
or
103-
result = n.(PropertyObserverElement).getAssignExpr()
34+
result = this.getNode().(PropertyObserverElement).getAssignExpr()
10435
or
105-
result = n.(ClosureElement).getAst()
36+
result = this.getNode().(ClosureElement).getAst()
10637
or
107-
result = n.(KeyPathElement).getAst()
38+
result = this.getNode().(KeyPathElement).getAst()
10839
}
10940
}
11041

@@ -130,7 +61,11 @@ class PatternCfgNode extends CfgNode {
13061

13162
/** A control-flow node that wraps a property getter. */
13263
class PropertyGetterCfgNode extends CfgNode {
133-
override PropertyGetterElement n;
64+
PropertyGetterElement n;
65+
66+
PropertyGetterCfgNode() {
67+
n = this.getAstNode()
68+
}
13469

13570
Expr getRef() { result = n.getRef() }
13671

@@ -141,8 +76,11 @@ class PropertyGetterCfgNode extends CfgNode {
14176

14277
/** A control-flow node that wraps a property setter. */
14378
class PropertySetterCfgNode extends CfgNode {
144-
override PropertySetterElement n;
79+
PropertySetterElement n;
14580

81+
PropertySetterCfgNode() {
82+
n = this.getAstNode()
83+
}
14684
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
14785

14886
CfgNode getBase() { result.getAst() = n.getBase() }
@@ -153,8 +91,11 @@ class PropertySetterCfgNode extends CfgNode {
15391
}
15492

15593
class PropertyObserverCfgNode extends CfgNode {
156-
override PropertyObserverElement n;
94+
PropertyObserverElement n;
15795

96+
PropertyObserverCfgNode() {
97+
n = this.getAstNode()
98+
}
15899
AssignExpr getAssignExpr() { result = n.getAssignExpr() }
159100

160101
CfgNode getBase() { result.getAst() = n.getBase() }

swift/ql/lib/codeql/swift/controlflow/ControlFlowGraph.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CfgScope extends Scope instanceof CfgScope::Range_ {
2727
*
2828
* Only nodes that can be reached from an entry point are included in the CFG.
2929
*/
30-
class ControlFlowNode extends TCfgNode {
30+
class ControlFlowNode extends Node {
3131
/** Gets a textual representation of this control flow node. */
3232
string toString() { none() }
3333

@@ -50,7 +50,7 @@ class ControlFlowNode extends TCfgNode {
5050
BasicBlock getBasicBlock() { result.getANode() = this }
5151

5252
/** Gets a successor node of a given type, if any. */
53-
final ControlFlowNode getASuccessor(SuccessorType t) { result = getASuccessor(this, t) }
53+
final ControlFlowNode getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
5454

5555
/** Gets an immediate successor, if any. */
5656
final ControlFlowNode getASuccessor() { result = this.getASuccessor(_) }

swift/ql/lib/codeql/swift/controlflow/internal/AstControlFlowTrees.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
private import swift
22
private import Completion
3-
private import ControlFlowGraphImplShared
3+
private import ControlFlowGraphParameter::CfgImpl
44
private import ControlFlowElements
55

66
abstract class AstControlFlowTree extends ControlFlowTree {

0 commit comments

Comments
 (0)