Skip to content

Commit 7dc7938

Browse files
committed
Swift: introduce Node.asPattern()
1 parent a715ebe commit 7dc7938

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ class ExprCfgNode extends CfgNode {
118118
Expr getExpr() { result = e }
119119
}
120120

121+
/** A control-flow node that wraps a pattern. */
122+
class PatternCfgNode extends CfgNode {
123+
Pattern p;
124+
125+
PatternCfgNode() { p = this.getNode().asAstNode() }
126+
127+
/** Gets the underlying pattern. */
128+
Pattern getPattern() { result = p }
129+
}
130+
121131
/** A control-flow node that wraps a property getter. */
122132
class PropertyGetterCfgNode extends CfgNode {
123133
override PropertyGetterElement n;

swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
4040
override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) }
4141
}
4242

43+
private class PatternNodeImpl extends PatternNode, NodeImpl {
44+
override Location getLocationImpl() { result = pattern.getLocation() }
45+
46+
override string toStringImpl() { result = pattern.toString() }
47+
48+
override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) }
49+
}
50+
4351
private class SsaDefinitionNodeImpl extends SsaDefinitionNode, NodeImpl {
4452
override Location getLocationImpl() { result = def.getLocation() }
4553

@@ -63,6 +71,7 @@ private module Cached {
6371
cached
6472
newtype TNode =
6573
TExprNode(CfgNode n, Expr e) { hasExprNode(n, e) } or
74+
TPatternNode(CfgNode n, Pattern p) { hasPatternNode(n, p) } or
6675
TSsaDefinitionNode(Ssa::Definition def) or
6776
TInoutReturnNode(ParamDecl param) { modifiableParam(param) } or
6877
TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
@@ -231,6 +240,11 @@ private predicate hasExprNode(CfgNode n, Expr e) {
231240
n.(PropertyObserverCfgNode).getAssignExpr() = e
232241
}
233242

243+
private predicate hasPatternNode(PatternCfgNode n, Pattern p) {
244+
n.getPattern() = p and
245+
p = p.resolve() // no need to turn hidden-AST patterns (`let`s, parens) into data flow nodes
246+
}
247+
234248
import Cached
235249

236250
/** Holds if `n` should be hidden from path explanations. */

swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ class Node extends TNode {
3737
*/
3838
Expr asExpr() { none() }
3939

40+
/**
41+
* Gets this node's underlying pattern, if any.
42+
*/
43+
Pattern asPattern() { none() }
44+
4045
/**
4146
* Gets this data flow node's corresponding control flow node.
4247
*/
@@ -66,6 +71,20 @@ class ExprNode extends Node, TExprNode {
6671
override ControlFlowNode getCfgNode() { result = n }
6772
}
6873

74+
/**
75+
* A pattern, viewed as a node in a data flow graph.
76+
*/
77+
class PatternNode extends Node, TPatternNode {
78+
CfgNode n;
79+
Pattern pattern;
80+
81+
PatternNode() { this = TPatternNode(n, pattern) }
82+
83+
override Pattern asPattern() { result = pattern }
84+
85+
override ControlFlowNode getCfgNode() { result = n }
86+
}
87+
6988
/**
7089
* The value of a parameter at function entry, viewed as a node in a data
7190
* flow graph.

0 commit comments

Comments
 (0)