Skip to content

Commit 20d9aaf

Browse files
authored
Merge pull request github#9516 from MathiasVP/revert-9419-revert-9373-cfg-for-key-paths
Swift: Reintroduce control-flow for key paths
2 parents 84518c8 + 89bda04 commit 20d9aaf

File tree

7 files changed

+415
-16
lines changed

7 files changed

+415
-16
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ private module JoinBlockPredecessors {
207207
isPropertySetterElement(n, _, result)
208208
or
209209
isPropertyObserverElement(n, _, result)
210+
or
211+
result = n.(KeyPathElement).getAst()
212+
or
213+
result = n.(FuncDeclElement).getAst()
210214
}
211215

212216
int getId(JoinBlockPredecessor jbp) {

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ newtype TControlFlowElement =
1010
} or
1111
TPropertyObserverElement(AccessorDecl observer, AssignExpr assign) {
1212
isPropertyObserverElement(observer, assign)
13-
}
13+
} or
14+
TKeyPathElement(KeyPathExpr expr)
1415

1516
predicate isLValue(Expr e) { any(AssignExpr assign).getDest() = e }
1617

@@ -171,4 +172,18 @@ class FuncDeclElement extends ControlFlowElement, TFuncDeclElement {
171172
override string toString() { result = func.toString() }
172173

173174
override Location getLocation() { result = func.getLocation() }
175+
176+
AbstractFunctionDecl getAst() { result = func }
177+
}
178+
179+
class KeyPathElement extends ControlFlowElement, TKeyPathElement {
180+
KeyPathExpr expr;
181+
182+
KeyPathElement() { this = TKeyPathElement(expr) }
183+
184+
override Location getLocation() { result = expr.getLocation() }
185+
186+
KeyPathExpr getAst() { result = expr }
187+
188+
override string toString() { result = expr.toString() }
174189
}

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,23 @@ module CfgScope {
4747
}
4848

4949
private class BodyStmtCallableScope extends Range_ instanceof AbstractFunctionDecl {
50-
final override predicate entry(ControlFlowElement first) {
51-
exists(Decls::FuncDeclTree tree |
52-
tree.getAst() = this and
53-
first = tree
54-
)
55-
}
50+
Decls::FuncDeclTree tree;
5651

57-
final override predicate exit(ControlFlowElement last, Completion c) {
58-
exists(Decls::FuncDeclTree tree |
59-
tree.getAst() = this and
60-
tree.last(last, c)
61-
)
62-
}
52+
BodyStmtCallableScope() { tree.getAst() = this }
53+
54+
final override predicate entry(ControlFlowElement first) { first(tree, first) }
55+
56+
final override predicate exit(ControlFlowElement last, Completion c) { last(tree, last, c) }
57+
}
58+
59+
private class KeyPathScope extends Range_ instanceof KeyPathExpr {
60+
AstControlFlowTree tree;
61+
62+
KeyPathScope() { tree.getAst() = this.getParsedRoot().getFullyConverted() }
63+
64+
final override predicate entry(ControlFlowElement first) { first(tree, first) }
65+
66+
final override predicate exit(ControlFlowElement last, Completion c) { last(tree, last, c) }
6367
}
6468
}
6569

@@ -1112,6 +1116,20 @@ module Exprs {
11121116
}
11131117
}
11141118

1119+
class KeyPathTree extends AstLeafTree {
1120+
override KeyPathExpr ast;
1121+
}
1122+
1123+
class KeyPathApplicationTree extends AstStandardPostOrderTree {
1124+
override KeyPathApplicationExpr ast;
1125+
1126+
final override ControlFlowElement getChildElement(int i) {
1127+
i = 0 and result.asAstNode() = ast.getBase().getFullyConverted()
1128+
or
1129+
i = 1 and result.asAstNode() = ast.getKeyPath().getFullyConverted()
1130+
}
1131+
}
1132+
11151133
private class InOutTree extends AstStandardPostOrderTree {
11161134
override InOutExpr ast;
11171135

@@ -1648,7 +1666,9 @@ private module Cached {
16481666
result = scopeOfAst(n.asAstNode()) or
16491667
result = scopeOfAst(n.(PropertyGetterElement).getRef()) or
16501668
result = scopeOfAst(n.(PropertySetterElement).getAssignExpr()) or
1651-
result = scopeOfAst(n.(PropertyObserverElement).getAssignExpr())
1669+
result = scopeOfAst(n.(PropertyObserverElement).getAssignExpr()) or
1670+
result = n.(FuncDeclElement).getAst() or
1671+
result = n.(KeyPathElement).getAst()
16521672
}
16531673

16541674
cached

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ private import swift
22
private import codeql.swift.generated.GetImmediateParent
33

44
module CallableBase {
5-
class TypeRange = @abstract_function_decl;
5+
class TypeRange = @abstract_function_decl or @key_path_expr;
66

77
class Range extends Scope::Range, TypeRange { }
88
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
private import swift
22
private import DataFlowPrivate
33
private import DataFlowPublic
4+
private import codeql.swift.controlflow.ControlFlowGraph
45

56
newtype TReturnKind = TNormalReturnKind()
67

@@ -53,7 +54,7 @@ class DataFlowCall extends ExprNode {
5354
cached
5455
private module Cached {
5556
cached
56-
newtype TDataFlowCallable = TDataFlowFunc(FuncDecl func)
57+
newtype TDataFlowCallable = TDataFlowFunc(CfgScope scope)
5758

5859
/** Gets a viable run-time target for the call `call`. */
5960
cached

0 commit comments

Comments
 (0)