Skip to content

Commit cb749bd

Browse files
committed
Swift: CFG for normal autoclosure exprs
1 parent 661da76 commit cb749bd

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cached
44
newtype TControlFlowElement =
55
TAstElement(AstNode n) or
66
TFuncDeclElement(Function func) { func.hasBody() } or
7-
TClosureElement(ExplicitClosureExpr clos) or
7+
TClosureElement(ClosureExpr clos) { isNormalAutoClosureOrExplicitClosure(clos) } or
88
TPropertyGetterElement(Decl accessor, Expr ref) { isPropertyGetterElement(accessor, ref) } or
99
TPropertySetterElement(Accessor accessor, AssignExpr assign) {
1010
isPropertySetterElement(accessor, assign)
@@ -41,6 +41,13 @@ predicate isPropertyGetterElement(PropertyGetterElement pge, Accessor accessor,
4141
pge = TPropertyGetterElement(accessor, ref)
4242
}
4343

44+
predicate isNormalAutoClosureOrExplicitClosure(ClosureExpr clos) {
45+
clos instanceof AutoClosureExpr and
46+
exists(CallExpr call | call.getAnArgument().getExpr() = clos)
47+
or
48+
clos instanceof ExplicitClosureExpr
49+
}
50+
4451
private predicate hasDirectToImplementationSemantics(Expr e) {
4552
e.(MemberRefExpr).hasDirectToImplementationSemantics()
4653
or
@@ -195,13 +202,13 @@ class KeyPathElement extends ControlFlowElement, TKeyPathElement {
195202
}
196203

197204
class ClosureElement extends ControlFlowElement, TClosureElement {
198-
ExplicitClosureExpr expr;
205+
ClosureExpr expr;
199206

200207
ClosureElement() { this = TClosureElement(expr) }
201208

202209
override Location getLocation() { result = expr.getLocation() }
203210

204-
ExplicitClosureExpr getAst() { result = expr }
211+
ClosureExpr getAst() { result = expr }
205212

206213
override string toString() { result = expr.toString() }
207214
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ module CfgScope {
6767
final override predicate exit(ControlFlowElement last, Completion c) { last(tree, last, c) }
6868
}
6969

70-
private class ClosureExprScope extends Range_ instanceof ExplicitClosureExpr {
70+
private class ClosureExprScope extends Range_ instanceof ClosureExpr {
7171
Exprs::ClosureExprTree tree;
7272

73-
ClosureExprScope() { tree.getAst() = this }
73+
ClosureExprScope() {
74+
isNormalAutoClosureOrExplicitClosure(this) and
75+
tree.getAst() = this
76+
}
7477

7578
final override predicate entry(ControlFlowElement first) { first(tree, first) }
7679

@@ -1139,11 +1142,11 @@ module Exprs {
11391142
}
11401143

11411144
class ClosureExprTree extends StandardPreOrderTree, TClosureElement {
1142-
ExplicitClosureExpr expr;
1145+
ClosureExpr expr;
11431146

11441147
ClosureExprTree() { this = TClosureElement(expr) }
11451148

1146-
ExplicitClosureExpr getAst() { result = expr }
1149+
ClosureExpr getAst() { result = expr }
11471150

11481151
final override ControlFlowElement getChildElement(int i) {
11491152
result.asAstNode() = expr.getParam(i)

swift/ql/test/library-tests/controlflow/graph/Cfg.expected

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,5 +6317,22 @@ cfg.swift:
63176317
# 555| call to usesAutoclosure(_:)
63186318
#-----| -> exit autoclosureTest() (normal)
63196319

6320+
# 555| 1
6321+
#-----| -> return ...
6322+
6323+
# 555| enter { ... }
6324+
#-----| -> { ... }
6325+
6326+
# 555| exit { ... }
6327+
6328+
# 555| exit { ... } (normal)
6329+
#-----| -> exit { ... }
6330+
6331+
# 555| return ...
6332+
#-----| -> exit { ... } (normal)
6333+
6334+
# 555| { ... }
6335+
#-----| -> 1
6336+
63206337
# 555| { ... }
63216338
#-----| -> call to usesAutoclosure(_:)

swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ edges
560560
| test.swift:873:21:873:31 | [...] [Collection element] | test.swift:856:29:856:40 | args [Collection element] |
561561
| test.swift:873:21:873:31 | [...] [Collection element] | test.swift:873:21:873:31 | [...] [Collection element] |
562562
| test.swift:873:24:873:31 | call to source() | test.swift:873:21:873:31 | [...] [Collection element] |
563+
| test.swift:881:19:881:26 | call to source() | test.swift:877:13:877:18 | call to ... |
563564
nodes
564565
| file://:0:0:0:0 | .a [x] | semmle.label | .a [x] |
565566
| file://:0:0:0:0 | .s [x] | semmle.label | .s [x] |
@@ -1164,6 +1165,8 @@ nodes
11641165
| test.swift:873:21:873:31 | [...] [Collection element] | semmle.label | [...] [Collection element] |
11651166
| test.swift:873:21:873:31 | [...] [Collection element] | semmle.label | [...] [Collection element] |
11661167
| test.swift:873:24:873:31 | call to source() | semmle.label | call to source() |
1168+
| test.swift:877:13:877:18 | call to ... | semmle.label | call to ... |
1169+
| test.swift:881:19:881:26 | call to source() | semmle.label | call to source() |
11671170
subpaths
11681171
| test.swift:75:22:75:22 | x | test.swift:65:16:65:28 | arg1 | test.swift:65:1:70:1 | arg2[return] | test.swift:75:32:75:32 | [post] y |
11691172
| test.swift:114:19:114:19 | arg | test.swift:109:9:109:14 | arg | test.swift:110:12:110:12 | arg | test.swift:114:12:114:22 | call to ... |
@@ -1355,3 +1358,4 @@ subpaths
13551358
| test.swift:859:15:859:21 | ...[...] | test.swift:873:24:873:31 | call to source() | test.swift:859:15:859:21 | ...[...] | result |
13561359
| test.swift:860:15:860:21 | ...[...] | test.swift:873:24:873:31 | call to source() | test.swift:860:15:860:21 | ...[...] | result |
13571360
| test.swift:867:15:867:38 | \\...[...] | test.swift:873:24:873:31 | call to source() | test.swift:867:15:867:38 | \\...[...] | result |
1361+
| test.swift:877:13:877:18 | call to ... | test.swift:881:19:881:26 | call to source() | test.swift:877:13:877:18 | call to ... | result |

swift/ql/test/library-tests/dataflow/dataflow/test.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ func testVarargsCaller() {
874874
}
875875

876876
func usesAutoclosure(_ expr: @autoclosure () -> Int) {
877-
sink(arg: expr())
877+
sink(arg: expr()) // $ flow=881
878878
}
879879

880880
func autoclosureTest() {

0 commit comments

Comments
 (0)