Skip to content

Commit a1234d4

Browse files
authored
Merge pull request github#13905 from geoffw0/forceunwrap
Swift: Flow through ForceValueExpr on LHS of assignment
2 parents 0ca3f33 + 2b0fcab commit a1234d4

File tree

5 files changed

+205
-0
lines changed

5 files changed

+205
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
5+
* Flow through forced optional unwrapping (`!`) on the left side of assignment now works in most cases.

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,14 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
703703
init.isFailable()
704704
)
705705
or
706+
// assignment to an optional via `!`, e.g. `optional! = ...`
707+
exists(ForceValueExpr fve, AssignExpr assign |
708+
fve = assign.getDest() and
709+
node1.asExpr() = assign.getSource() and
710+
node2.asExpr() = fve.getSubExpr() and
711+
c instanceof OptionalSomeContentSet
712+
)
713+
or
706714
// creation of an array `[v1,v2]`
707715
exists(ArrayExpr arr |
708716
node1.asExpr() = arr.getAnElement() and

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
edges
22
| file://:0:0:0:0 | self [a, x] | file://:0:0:0:0 | .a [x] |
33
| file://:0:0:0:0 | self [str] | file://:0:0:0:0 | .str |
4+
| file://:0:0:0:0 | self [v2, some:0] | file://:0:0:0:0 | .v2 [some:0] |
5+
| file://:0:0:0:0 | self [v2] | file://:0:0:0:0 | .v2 |
6+
| file://:0:0:0:0 | self [v3] | file://:0:0:0:0 | .v3 |
47
| file://:0:0:0:0 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] |
58
| file://:0:0:0:0 | self [x] | file://:0:0:0:0 | .x |
9+
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v2] |
10+
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v3] |
611
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [x] |
12+
| file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [v2, some:0] |
713
| file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] |
814
| test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 |
915
| test.swift:6:19:6:26 | call to source() | test.swift:9:15:9:15 | t1 |
@@ -349,18 +355,64 @@ edges
349355
| test.swift:706:21:706:28 | call to source() | test.swift:706:20:706:29 | [...] [Array element] |
350356
| test.swift:707:15:707:15 | set2 [Collection element] | test.swift:707:15:707:34 | call to randomElement() [some:0] |
351357
| test.swift:707:15:707:34 | call to randomElement() [some:0] | test.swift:707:15:707:35 | ...! |
358+
| test.swift:712:9:712:9 | self [v2, some:0] | file://:0:0:0:0 | self [v2, some:0] |
359+
| test.swift:712:9:712:9 | self [v2] | file://:0:0:0:0 | self [v2] |
360+
| test.swift:712:9:712:9 | value | file://:0:0:0:0 | value |
361+
| test.swift:712:9:712:9 | value [some:0] | file://:0:0:0:0 | value [some:0] |
362+
| test.swift:713:9:713:9 | self [v3] | file://:0:0:0:0 | self [v3] |
363+
| test.swift:713:9:713:9 | value | file://:0:0:0:0 | value |
364+
| test.swift:723:5:723:5 | v1 [some:0] | test.swift:733:15:733:15 | v1 [some:0] |
365+
| test.swift:723:11:723:18 | call to source() | test.swift:723:5:723:5 | v1 [some:0] |
366+
| test.swift:724:10:724:17 | call to source() | test.swift:724:10:724:17 | call to source() [some:0] |
367+
| test.swift:724:10:724:17 | call to source() | test.swift:734:15:734:17 | ...! |
368+
| test.swift:724:10:724:17 | call to source() [some:0] | test.swift:734:15:734:15 | v2 [some:0] |
369+
| test.swift:725:10:725:17 | call to source() | test.swift:735:15:735:15 | v3 |
370+
| test.swift:727:5:727:5 | [post] mo1 [v2, some:0] | test.swift:728:5:728:5 | mo1 [v2, some:0] |
371+
| test.swift:727:5:727:5 | [post] mo1 [v2] | test.swift:728:5:728:5 | mo1 [v2] |
372+
| test.swift:727:14:727:21 | call to source() | test.swift:712:9:712:9 | value |
373+
| test.swift:727:14:727:21 | call to source() | test.swift:727:5:727:5 | [post] mo1 [v2] |
374+
| test.swift:727:14:727:21 | call to source() | test.swift:727:14:727:21 | call to source() [some:0] |
375+
| test.swift:727:14:727:21 | call to source() [some:0] | test.swift:712:9:712:9 | value [some:0] |
376+
| test.swift:727:14:727:21 | call to source() [some:0] | test.swift:727:5:727:5 | [post] mo1 [v2, some:0] |
377+
| test.swift:728:5:728:5 | [post] mo1 [v3] | test.swift:738:15:738:15 | mo1 [v3] |
378+
| test.swift:728:5:728:5 | mo1 [v2, some:0] | test.swift:737:15:737:15 | mo1 [v2, some:0] |
379+
| test.swift:728:5:728:5 | mo1 [v2] | test.swift:737:15:737:15 | mo1 [v2] |
380+
| test.swift:728:14:728:21 | call to source() | test.swift:713:9:713:9 | value |
381+
| test.swift:728:14:728:21 | call to source() | test.swift:728:5:728:5 | [post] mo1 [v3] |
382+
| test.swift:733:15:733:15 | v1 [some:0] | test.swift:733:15:733:17 | ...! |
383+
| test.swift:734:15:734:15 | v2 [some:0] | test.swift:734:15:734:17 | ...! |
384+
| test.swift:737:15:737:15 | mo1 [v2, some:0] | test.swift:712:9:712:9 | self [v2, some:0] |
385+
| test.swift:737:15:737:15 | mo1 [v2, some:0] | test.swift:737:15:737:19 | .v2 [some:0] |
386+
| test.swift:737:15:737:15 | mo1 [v2] | test.swift:712:9:712:9 | self [v2] |
387+
| test.swift:737:15:737:15 | mo1 [v2] | test.swift:737:15:737:19 | .v2 |
388+
| test.swift:737:15:737:19 | .v2 | test.swift:737:15:737:21 | ...! |
389+
| test.swift:737:15:737:19 | .v2 [some:0] | test.swift:737:15:737:21 | ...! |
390+
| test.swift:738:15:738:15 | mo1 [v3] | test.swift:713:9:713:9 | self [v3] |
391+
| test.swift:738:15:738:15 | mo1 [v3] | test.swift:738:15:738:19 | .v3 |
352392
nodes
353393
| file://:0:0:0:0 | .a [x] | semmle.label | .a [x] |
354394
| file://:0:0:0:0 | .str | semmle.label | .str |
395+
| file://:0:0:0:0 | .v2 | semmle.label | .v2 |
396+
| file://:0:0:0:0 | .v2 [some:0] | semmle.label | .v2 [some:0] |
397+
| file://:0:0:0:0 | .v3 | semmle.label | .v3 |
355398
| file://:0:0:0:0 | .x | semmle.label | .x |
356399
| file://:0:0:0:0 | .x [some:0] | semmle.label | .x [some:0] |
400+
| file://:0:0:0:0 | [post] self [v2, some:0] | semmle.label | [post] self [v2, some:0] |
401+
| file://:0:0:0:0 | [post] self [v2] | semmle.label | [post] self [v2] |
402+
| file://:0:0:0:0 | [post] self [v3] | semmle.label | [post] self [v3] |
357403
| file://:0:0:0:0 | [post] self [x, some:0] | semmle.label | [post] self [x, some:0] |
358404
| file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] |
359405
| file://:0:0:0:0 | self [a, x] | semmle.label | self [a, x] |
360406
| file://:0:0:0:0 | self [str] | semmle.label | self [str] |
407+
| file://:0:0:0:0 | self [v2, some:0] | semmle.label | self [v2, some:0] |
408+
| file://:0:0:0:0 | self [v2] | semmle.label | self [v2] |
409+
| file://:0:0:0:0 | self [v3] | semmle.label | self [v3] |
361410
| file://:0:0:0:0 | self [x, some:0] | semmle.label | self [x, some:0] |
362411
| file://:0:0:0:0 | self [x] | semmle.label | self [x] |
363412
| file://:0:0:0:0 | value | semmle.label | value |
413+
| file://:0:0:0:0 | value | semmle.label | value |
414+
| file://:0:0:0:0 | value | semmle.label | value |
415+
| file://:0:0:0:0 | value [some:0] | semmle.label | value [some:0] |
364416
| file://:0:0:0:0 | value [some:0] | semmle.label | value [some:0] |
365417
| test.swift:6:19:6:26 | call to source() | semmle.label | call to source() |
366418
| test.swift:7:15:7:15 | t1 | semmle.label | t1 |
@@ -735,6 +787,37 @@ nodes
735787
| test.swift:707:15:707:15 | set2 [Collection element] | semmle.label | set2 [Collection element] |
736788
| test.swift:707:15:707:34 | call to randomElement() [some:0] | semmle.label | call to randomElement() [some:0] |
737789
| test.swift:707:15:707:35 | ...! | semmle.label | ...! |
790+
| test.swift:712:9:712:9 | self [v2, some:0] | semmle.label | self [v2, some:0] |
791+
| test.swift:712:9:712:9 | self [v2] | semmle.label | self [v2] |
792+
| test.swift:712:9:712:9 | value | semmle.label | value |
793+
| test.swift:712:9:712:9 | value [some:0] | semmle.label | value [some:0] |
794+
| test.swift:713:9:713:9 | self [v3] | semmle.label | self [v3] |
795+
| test.swift:713:9:713:9 | value | semmle.label | value |
796+
| test.swift:723:5:723:5 | v1 [some:0] | semmle.label | v1 [some:0] |
797+
| test.swift:723:11:723:18 | call to source() | semmle.label | call to source() |
798+
| test.swift:724:10:724:17 | call to source() | semmle.label | call to source() |
799+
| test.swift:724:10:724:17 | call to source() [some:0] | semmle.label | call to source() [some:0] |
800+
| test.swift:725:10:725:17 | call to source() | semmle.label | call to source() |
801+
| test.swift:727:5:727:5 | [post] mo1 [v2, some:0] | semmle.label | [post] mo1 [v2, some:0] |
802+
| test.swift:727:5:727:5 | [post] mo1 [v2] | semmle.label | [post] mo1 [v2] |
803+
| test.swift:727:14:727:21 | call to source() | semmle.label | call to source() |
804+
| test.swift:727:14:727:21 | call to source() [some:0] | semmle.label | call to source() [some:0] |
805+
| test.swift:728:5:728:5 | [post] mo1 [v3] | semmle.label | [post] mo1 [v3] |
806+
| test.swift:728:5:728:5 | mo1 [v2, some:0] | semmle.label | mo1 [v2, some:0] |
807+
| test.swift:728:5:728:5 | mo1 [v2] | semmle.label | mo1 [v2] |
808+
| test.swift:728:14:728:21 | call to source() | semmle.label | call to source() |
809+
| test.swift:733:15:733:15 | v1 [some:0] | semmle.label | v1 [some:0] |
810+
| test.swift:733:15:733:17 | ...! | semmle.label | ...! |
811+
| test.swift:734:15:734:15 | v2 [some:0] | semmle.label | v2 [some:0] |
812+
| test.swift:734:15:734:17 | ...! | semmle.label | ...! |
813+
| test.swift:735:15:735:15 | v3 | semmle.label | v3 |
814+
| test.swift:737:15:737:15 | mo1 [v2, some:0] | semmle.label | mo1 [v2, some:0] |
815+
| test.swift:737:15:737:15 | mo1 [v2] | semmle.label | mo1 [v2] |
816+
| test.swift:737:15:737:19 | .v2 | semmle.label | .v2 |
817+
| test.swift:737:15:737:19 | .v2 [some:0] | semmle.label | .v2 [some:0] |
818+
| test.swift:737:15:737:21 | ...! | semmle.label | ...! |
819+
| test.swift:738:15:738:15 | mo1 [v3] | semmle.label | mo1 [v3] |
820+
| test.swift:738:15:738:19 | .v3 | semmle.label | .v3 |
738821
subpaths
739822
| 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 |
740823
| 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 ... |
@@ -776,6 +859,12 @@ subpaths
776859
| test.swift:622:18:622:18 | s [x] | test.swift:615:8:615:11 | s [x] | test.swift:615:3:617:3 | self[return] [s, x] | test.swift:622:12:622:19 | call to S2.init(s:) [s, x] |
777860
| test.swift:624:13:624:13 | s2 [s, x] | test.swift:623:11:623:17 | enter #keyPath(...) [s, x] | test.swift:623:11:623:17 | exit #keyPath(...) | test.swift:624:13:624:26 | \\...[...] |
778861
| test.swift:630:15:630:15 | array [Array element] | test.swift:629:13:629:22 | enter #keyPath(...) [Array element] | test.swift:629:13:629:22 | exit #keyPath(...) | test.swift:630:15:630:31 | \\...[...] |
862+
| test.swift:727:14:727:21 | call to source() | test.swift:712:9:712:9 | value | file://:0:0:0:0 | [post] self [v2] | test.swift:727:5:727:5 | [post] mo1 [v2] |
863+
| test.swift:727:14:727:21 | call to source() [some:0] | test.swift:712:9:712:9 | value [some:0] | file://:0:0:0:0 | [post] self [v2, some:0] | test.swift:727:5:727:5 | [post] mo1 [v2, some:0] |
864+
| test.swift:728:14:728:21 | call to source() | test.swift:713:9:713:9 | value | file://:0:0:0:0 | [post] self [v3] | test.swift:728:5:728:5 | [post] mo1 [v3] |
865+
| test.swift:737:15:737:15 | mo1 [v2, some:0] | test.swift:712:9:712:9 | self [v2, some:0] | file://:0:0:0:0 | .v2 [some:0] | test.swift:737:15:737:19 | .v2 [some:0] |
866+
| test.swift:737:15:737:15 | mo1 [v2] | test.swift:712:9:712:9 | self [v2] | file://:0:0:0:0 | .v2 | test.swift:737:15:737:19 | .v2 |
867+
| test.swift:738:15:738:15 | mo1 [v3] | test.swift:713:9:713:9 | self [v3] | file://:0:0:0:0 | .v3 | test.swift:738:15:738:19 | .v3 |
779868
#select
780869
| test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 | result |
781870
| test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:9:15:9:15 | t1 | result |
@@ -867,3 +956,8 @@ subpaths
867956
| test.swift:697:15:697:35 | ...! | test.swift:696:17:696:24 | call to source() | test.swift:697:15:697:35 | ...! | result |
868957
| test.swift:704:15:704:35 | ...! | test.swift:703:17:703:24 | call to source() | test.swift:704:15:704:35 | ...! | result |
869958
| test.swift:707:15:707:35 | ...! | test.swift:706:21:706:28 | call to source() | test.swift:707:15:707:35 | ...! | result |
959+
| test.swift:733:15:733:17 | ...! | test.swift:723:11:723:18 | call to source() | test.swift:733:15:733:17 | ...! | result |
960+
| test.swift:734:15:734:17 | ...! | test.swift:724:10:724:17 | call to source() | test.swift:734:15:734:17 | ...! | result |
961+
| test.swift:735:15:735:15 | v3 | test.swift:725:10:725:17 | call to source() | test.swift:735:15:735:15 | v3 | result |
962+
| test.swift:737:15:737:21 | ...! | test.swift:727:14:727:21 | call to source() | test.swift:737:15:737:21 | ...! | result |
963+
| test.swift:738:15:738:19 | .v3 | test.swift:728:14:728:21 | call to source() | test.swift:738:15:738:19 | .v3 | result |

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,3 +830,67 @@
830830
| test.swift:706:9:706:9 | set2 | test.swift:706:9:706:9 | SSA def(set2) |
831831
| test.swift:706:16:706:30 | call to Set<Element>.init(_:) | test.swift:706:9:706:9 | set2 |
832832
| test.swift:707:15:707:34 | call to randomElement() | test.swift:707:15:707:35 | ...! |
833+
| test.swift:710:8:710:8 | SSA def(self) | test.swift:710:8:710:8 | self[return] |
834+
| test.swift:710:8:710:8 | self | test.swift:710:8:710:8 | SSA def(self) |
835+
| test.swift:711:9:711:9 | self | test.swift:711:9:711:9 | SSA def(self) |
836+
| test.swift:711:9:711:9 | self | test.swift:711:9:711:9 | SSA def(self) |
837+
| test.swift:711:9:711:9 | self | test.swift:711:9:711:9 | SSA def(self) |
838+
| test.swift:711:9:711:9 | value | test.swift:711:9:711:9 | SSA def(value) |
839+
| test.swift:712:9:712:9 | self | test.swift:712:9:712:9 | SSA def(self) |
840+
| test.swift:712:9:712:9 | self | test.swift:712:9:712:9 | SSA def(self) |
841+
| test.swift:712:9:712:9 | self | test.swift:712:9:712:9 | SSA def(self) |
842+
| test.swift:712:9:712:9 | value | test.swift:712:9:712:9 | SSA def(value) |
843+
| test.swift:713:9:713:9 | self | test.swift:713:9:713:9 | SSA def(self) |
844+
| test.swift:713:9:713:9 | self | test.swift:713:9:713:9 | SSA def(self) |
845+
| test.swift:713:9:713:9 | self | test.swift:713:9:713:9 | SSA def(self) |
846+
| test.swift:713:9:713:9 | value | test.swift:713:9:713:9 | SSA def(value) |
847+
| test.swift:717:9:717:9 | SSA def(v1) | test.swift:723:5:723:5 | v1 |
848+
| test.swift:717:9:717:9 | v1 | test.swift:717:9:717:9 | SSA def(v1) |
849+
| test.swift:717:9:717:17 | ... as ... | test.swift:717:9:717:9 | v1 |
850+
| test.swift:717:21:717:21 | 0 | test.swift:717:9:717:17 | ... as ... |
851+
| test.swift:718:9:718:17 | ... as ... | test.swift:718:9:718:9 | v2 |
852+
| test.swift:718:21:718:21 | 0 | test.swift:718:9:718:17 | ... as ... |
853+
| test.swift:719:9:719:17 | ... as ... | test.swift:719:9:719:9 | v3 |
854+
| test.swift:719:21:719:21 | 0 | test.swift:719:9:719:17 | ... as ... |
855+
| test.swift:720:9:720:9 | SSA def(mo1) | test.swift:726:5:726:5 | mo1 |
856+
| test.swift:720:9:720:9 | mo1 | test.swift:720:9:720:9 | SSA def(mo1) |
857+
| test.swift:720:15:720:27 | call to MyOptionals.init() | test.swift:720:9:720:9 | mo1 |
858+
| test.swift:721:9:721:9 | SSA def(mo2) | test.swift:729:5:729:5 | mo2 |
859+
| test.swift:721:9:721:9 | mo2 | test.swift:721:9:721:9 | SSA def(mo2) |
860+
| test.swift:721:9:721:26 | ... as ... | test.swift:721:9:721:9 | mo2 |
861+
| test.swift:721:30:721:42 | call to MyOptionals.init() | test.swift:721:9:721:26 | ... as ... |
862+
| test.swift:723:5:723:5 | v1 | test.swift:723:5:723:7 | ...! |
863+
| test.swift:723:5:723:5 | v1 | test.swift:733:15:733:15 | v1 |
864+
| test.swift:724:5:724:17 | SSA def(v2) | test.swift:734:15:734:15 | v2 |
865+
| test.swift:724:10:724:17 | call to source() | test.swift:724:5:724:17 | SSA def(v2) |
866+
| test.swift:725:5:725:17 | SSA def(v3) | test.swift:735:15:735:15 | v3 |
867+
| test.swift:725:10:725:17 | call to source() | test.swift:725:5:725:17 | SSA def(v3) |
868+
| test.swift:726:5:726:5 | [post] mo1 | test.swift:727:5:727:5 | mo1 |
869+
| test.swift:726:5:726:5 | mo1 | test.swift:727:5:727:5 | mo1 |
870+
| test.swift:726:5:726:9 | .v1 | test.swift:726:5:726:11 | ...! |
871+
| test.swift:727:5:727:5 | [post] mo1 | test.swift:728:5:728:5 | mo1 |
872+
| test.swift:727:5:727:5 | mo1 | test.swift:728:5:728:5 | mo1 |
873+
| test.swift:728:5:728:5 | [post] mo1 | test.swift:736:15:736:15 | mo1 |
874+
| test.swift:728:5:728:5 | mo1 | test.swift:736:15:736:15 | mo1 |
875+
| test.swift:729:5:729:5 | mo2 | test.swift:729:5:729:8 | ...! |
876+
| test.swift:729:5:729:5 | mo2 | test.swift:730:5:730:5 | mo2 |
877+
| test.swift:729:5:729:10 | .v1 | test.swift:729:5:729:12 | ...! |
878+
| test.swift:730:5:730:5 | mo2 | test.swift:730:5:730:8 | ...! |
879+
| test.swift:730:5:730:5 | mo2 | test.swift:731:5:731:5 | mo2 |
880+
| test.swift:731:5:731:5 | mo2 | test.swift:731:5:731:8 | ...! |
881+
| test.swift:731:5:731:5 | mo2 | test.swift:739:15:739:15 | mo2 |
882+
| test.swift:733:15:733:15 | v1 | test.swift:733:15:733:17 | ...! |
883+
| test.swift:734:15:734:15 | v2 | test.swift:734:15:734:17 | ...! |
884+
| test.swift:736:15:736:15 | [post] mo1 | test.swift:737:15:737:15 | mo1 |
885+
| test.swift:736:15:736:15 | mo1 | test.swift:737:15:737:15 | mo1 |
886+
| test.swift:736:15:736:19 | .v1 | test.swift:736:15:736:21 | ...! |
887+
| test.swift:737:15:737:15 | [post] mo1 | test.swift:738:15:738:15 | mo1 |
888+
| test.swift:737:15:737:15 | mo1 | test.swift:738:15:738:15 | mo1 |
889+
| test.swift:737:15:737:19 | .v2 | test.swift:737:15:737:21 | ...! |
890+
| test.swift:739:15:739:15 | mo2 | test.swift:739:15:739:18 | ...! |
891+
| test.swift:739:15:739:15 | mo2 | test.swift:740:15:740:15 | mo2 |
892+
| test.swift:739:15:739:20 | .v1 | test.swift:739:15:739:22 | ...! |
893+
| test.swift:740:15:740:15 | mo2 | test.swift:740:15:740:18 | ...! |
894+
| test.swift:740:15:740:15 | mo2 | test.swift:741:15:741:15 | mo2 |
895+
| test.swift:740:15:740:20 | .v2 | test.swift:740:15:740:22 | ...! |
896+
| test.swift:741:15:741:15 | mo2 | test.swift:741:15:741:18 | ...! |

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,3 +706,37 @@ func testSetCollections() {
706706
let set2 = Set([source()])
707707
sink(arg: set2.randomElement()!) // $ flow=706
708708
}
709+
710+
struct MyOptionals {
711+
var v1 : Int? = 0
712+
var v2 : Int? = 0
713+
var v3 : Int! = 0
714+
}
715+
716+
func testWriteOptional() {
717+
var v1 : Int? = 0
718+
var v2 : Int? = 0
719+
var v3 : Int! = 0
720+
var mo1 = MyOptionals()
721+
var mo2 : MyOptionals! = MyOptionals()
722+
723+
v1! = source()
724+
v2 = source()
725+
v3 = source()
726+
mo1.v1! = source()
727+
mo1.v2 = source()
728+
mo1.v3 = source()
729+
mo2!.v1! = source()
730+
mo2!.v2 = source()
731+
mo2!.v3 = source()
732+
733+
sink(arg: v1!) // $ flow=723
734+
sink(arg: v2!) // $ flow=724
735+
sink(arg: v3) // $ flow=725
736+
sink(arg: mo1.v1!) // $ MISSING:flow=726
737+
sink(arg: mo1.v2!) // $ flow=727
738+
sink(arg: mo1.v3) // $ flow=728
739+
sink(arg: mo2!.v1!) // $ MISSING:flow=729
740+
sink(arg: mo2!.v2!) // $ MISSING:flow=730
741+
sink(arg: mo2!.v3) // $ MISSING:flow=731
742+
}

0 commit comments

Comments
 (0)