Skip to content

Commit 269f0c6

Browse files
committed
Swift: Flow through varargs.
1 parent 3fe8655 commit 269f0c6

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ private module Cached {
190190
// flow through unary `+` (which does nothing)
191191
nodeFrom.asExpr() = nodeTo.asExpr().(UnaryPlusExpr).getOperand()
192192
or
193+
// flow through varargs expansions (that wrap an `ArrayExpr` where varargs enter a call)
194+
nodeFrom.asExpr() = nodeTo.asExpr().(VarargExpansionExpr).getSubExpr()
195+
or
193196
// flow through nil-coalescing operator `??`
194197
exists(BinaryExpr nco |
195198
nco.getOperator().(FreeFunction).getName() = "??(_:_:)" and
@@ -799,11 +802,14 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
799802
node2.(KeyPathReturnNodeImpl).getKeyPathExpr() = component.getKeyPathExpr()
800803
)
801804
or
802-
// read of an array member via subscript operator
805+
// read of an array or variadic sequence type member via subscript operator
803806
exists(SubscriptExpr subscript |
804807
subscript.getBase() = node1.asExpr() and
805808
subscript = node2.asExpr() and
806-
subscript.getBase().getType() instanceof ArrayType and
809+
(
810+
subscript.getBase().getType() instanceof ArrayType or
811+
subscript.getBase().getType() instanceof VariadicSequenceType
812+
) and
807813
c.isSingleton(any(Content::ArrayContent ac))
808814
)
809815
or

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,25 @@ edges
404404
| test.swift:756:15:756:19 | .v2 [some:0] | test.swift:756:15:756:21 | ...! |
405405
| test.swift:757:15:757:15 | mo1 [v3] | test.swift:732:9:732:9 | self [v3] |
406406
| test.swift:757:15:757:15 | mo1 [v3] | test.swift:757:15:757:19 | .v3 |
407+
| test.swift:763:19:763:28 | args [Array element] | test.swift:765:15:765:15 | args [Array element] |
408+
| test.swift:765:15:765:15 | args [Array element] | test.swift:765:15:765:21 | ...[...] |
407409
| test.swift:768:19:768:24 | v | test.swift:769:15:769:15 | v |
410+
| test.swift:775:29:775:40 | args [Array element] | test.swift:778:15:778:15 | args [Array element] |
411+
| test.swift:775:29:775:40 | args [Array element] | test.swift:779:15:779:15 | args [Array element] |
412+
| test.swift:775:29:775:40 | args [Array element] | test.swift:786:15:786:15 | args [Array element] |
413+
| test.swift:778:15:778:15 | args [Array element] | test.swift:778:15:778:21 | ...[...] |
414+
| test.swift:779:15:779:15 | args [Array element] | test.swift:779:15:779:21 | ...[...] |
415+
| test.swift:785:21:785:29 | enter #keyPath(...) [Array element] | test.swift:785:27:785:29 | KeyPathComponent [Array element] |
416+
| test.swift:785:27:785:29 | KeyPathComponent [Array element] | test.swift:785:21:785:29 | exit #keyPath(...) |
417+
| test.swift:786:15:786:15 | args [Array element] | test.swift:785:21:785:29 | enter #keyPath(...) [Array element] |
418+
| test.swift:786:15:786:15 | args [Array element] | test.swift:786:15:786:38 | \\...[...] |
419+
| test.swift:790:24:790:31 | [...] [Array element] | test.swift:763:19:763:28 | args [Array element] |
420+
| test.swift:790:24:790:31 | [...] [Array element] | test.swift:790:24:790:31 | [...] [Array element] |
421+
| test.swift:790:24:790:31 | call to source() | test.swift:790:24:790:31 | [...] [Array element] |
408422
| test.swift:791:18:791:25 | call to source() | test.swift:768:19:768:24 | v |
423+
| test.swift:792:21:792:31 | [...] [Array element] | test.swift:775:29:775:40 | args [Array element] |
424+
| test.swift:792:21:792:31 | [...] [Array element] | test.swift:792:21:792:31 | [...] [Array element] |
425+
| test.swift:792:24:792:31 | call to source() | test.swift:792:21:792:31 | [...] [Array element] |
409426
nodes
410427
| file://:0:0:0:0 | .a [x] | semmle.label | .a [x] |
411428
| file://:0:0:0:0 | .str | semmle.label | .str |
@@ -851,9 +868,28 @@ nodes
851868
| test.swift:756:15:756:21 | ...! | semmle.label | ...! |
852869
| test.swift:757:15:757:15 | mo1 [v3] | semmle.label | mo1 [v3] |
853870
| test.swift:757:15:757:19 | .v3 | semmle.label | .v3 |
871+
| test.swift:763:19:763:28 | args [Array element] | semmle.label | args [Array element] |
872+
| test.swift:765:15:765:15 | args [Array element] | semmle.label | args [Array element] |
873+
| test.swift:765:15:765:21 | ...[...] | semmle.label | ...[...] |
854874
| test.swift:768:19:768:24 | v | semmle.label | v |
855875
| test.swift:769:15:769:15 | v | semmle.label | v |
876+
| test.swift:775:29:775:40 | args [Array element] | semmle.label | args [Array element] |
877+
| test.swift:778:15:778:15 | args [Array element] | semmle.label | args [Array element] |
878+
| test.swift:778:15:778:21 | ...[...] | semmle.label | ...[...] |
879+
| test.swift:779:15:779:15 | args [Array element] | semmle.label | args [Array element] |
880+
| test.swift:779:15:779:21 | ...[...] | semmle.label | ...[...] |
881+
| test.swift:785:21:785:29 | enter #keyPath(...) [Array element] | semmle.label | enter #keyPath(...) [Array element] |
882+
| test.swift:785:21:785:29 | exit #keyPath(...) | semmle.label | exit #keyPath(...) |
883+
| test.swift:785:27:785:29 | KeyPathComponent [Array element] | semmle.label | KeyPathComponent [Array element] |
884+
| test.swift:786:15:786:15 | args [Array element] | semmle.label | args [Array element] |
885+
| test.swift:786:15:786:38 | \\...[...] | semmle.label | \\...[...] |
886+
| test.swift:790:24:790:31 | [...] [Array element] | semmle.label | [...] [Array element] |
887+
| test.swift:790:24:790:31 | [...] [Array element] | semmle.label | [...] [Array element] |
888+
| test.swift:790:24:790:31 | call to source() | semmle.label | call to source() |
856889
| test.swift:791:18:791:25 | call to source() | semmle.label | call to source() |
890+
| test.swift:792:21:792:31 | [...] [Array element] | semmle.label | [...] [Array element] |
891+
| test.swift:792:21:792:31 | [...] [Array element] | semmle.label | [...] [Array element] |
892+
| test.swift:792:24:792:31 | call to source() | semmle.label | call to source() |
857893
subpaths
858894
| 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 |
859895
| 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 ... |
@@ -902,6 +938,7 @@ subpaths
902938
| test.swift:756:15:756:15 | mo1 [v2, some:0] | test.swift:731:9:731:9 | self [v2, some:0] | file://:0:0:0:0 | .v2 [some:0] | test.swift:756:15:756:19 | .v2 [some:0] |
903939
| test.swift:756:15:756:15 | mo1 [v2] | test.swift:731:9:731:9 | self [v2] | file://:0:0:0:0 | .v2 | test.swift:756:15:756:19 | .v2 |
904940
| test.swift:757:15:757:15 | mo1 [v3] | test.swift:732:9:732:9 | self [v3] | file://:0:0:0:0 | .v3 | test.swift:757:15:757:19 | .v3 |
941+
| test.swift:786:15:786:15 | args [Array element] | test.swift:785:21:785:29 | enter #keyPath(...) [Array element] | test.swift:785:21:785:29 | exit #keyPath(...) | test.swift:786:15:786:38 | \\...[...] |
905942
#select
906943
| test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 | result |
907944
| test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:9:15:9:15 | t1 | result |
@@ -1001,4 +1038,8 @@ subpaths
10011038
| test.swift:754:15:754:15 | v3 | test.swift:744:10:744:17 | call to source() | test.swift:754:15:754:15 | v3 | result |
10021039
| test.swift:756:15:756:21 | ...! | test.swift:746:14:746:21 | call to source() | test.swift:756:15:756:21 | ...! | result |
10031040
| test.swift:757:15:757:19 | .v3 | test.swift:747:14:747:21 | call to source() | test.swift:757:15:757:19 | .v3 | result |
1041+
| test.swift:765:15:765:21 | ...[...] | test.swift:790:24:790:31 | call to source() | test.swift:765:15:765:21 | ...[...] | result |
10041042
| test.swift:769:15:769:15 | v | test.swift:791:18:791:25 | call to source() | test.swift:769:15:769:15 | v | result |
1043+
| test.swift:778:15:778:21 | ...[...] | test.swift:792:24:792:31 | call to source() | test.swift:778:15:778:21 | ...[...] | result |
1044+
| test.swift:779:15:779:21 | ...[...] | test.swift:792:24:792:31 | call to source() | test.swift:779:15:779:21 | ...[...] | result |
1045+
| test.swift:786:15:786:38 | \\...[...] | test.swift:792:24:792:31 | call to source() | test.swift:786:15:786:38 | \\...[...] | result |

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,3 +939,6 @@
939939
| test.swift:785:9:785:9 | myKeyPath | test.swift:785:9:785:9 | SSA def(myKeyPath) |
940940
| test.swift:785:21:785:29 | #keyPath(...) | test.swift:785:9:785:9 | myKeyPath |
941941
| test.swift:785:21:785:29 | enter #keyPath(...) | test.swift:785:27:785:29 | KeyPathComponent |
942+
| test.swift:790:24:790:31 | [...] | test.swift:790:24:790:31 | [...] |
943+
| test.swift:791:28:791:31 | [...] | test.swift:791:28:791:31 | [...] |
944+
| test.swift:792:21:792:31 | [...] | test.swift:792:21:792:31 | [...] |

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ func testWriteOptional() {
762762

763763
func testVarargs1(args: Int...) {
764764
sink(arg: args)
765-
sink(arg: args[0]) // $ MISSING: flow=790
765+
sink(arg: args[0]) // $ flow=790
766766
}
767767

768768
func testVarargs2(_ v: Int, _ args: Int...) {
@@ -775,15 +775,15 @@ func testVarargs2(_ v: Int, _ args: Int...) {
775775
func testVarargs3(_ v: Int, _ args: Int...) {
776776
sink(arg: v)
777777
sink(arg: args)
778-
sink(arg: args[0])
779-
sink(arg: args[1]) // $ MISSING: flow=792
778+
sink(arg: args[0]) // $ SPURIOUS: flow=792
779+
sink(arg: args[1]) // $ flow=792
780780

781781
for arg in args {
782782
sink(arg: arg) // $ MISSING: flow=792
783783
}
784784

785785
let myKeyPath = \[Int][1]
786-
sink(arg: args[keyPath: myKeyPath]) // $ MISSING: flow=792
786+
sink(arg: args[keyPath: myKeyPath]) // $ flow=792
787787
}
788788

789789
func testVarargsCaller() {

0 commit comments

Comments
 (0)