Files
kotlin-fork/compiler/fir/analysis-tests/testData/resolve/smartcasts/loops/endlessLoops.dot
T
pyos a9be27e330 FIR CFG: add union nodes
Quick quiz:

 Q: In a CFG, what does `a -> b -> c -> d` mean?
 A: `a`, then `b`, then `c`, then `d`.

 Q: In a CFG, what does `a -> b -> d; a -> c -> d` mean?
 A: `a`, then `b` or `c`, then `d`.

 Q: So how do you encode "a, then (b, then c) or (c, then b), then d`?
 A: You can't.

Problem is, you need to, because that's what `a; run2({ b }, { c }); d`
does when `run2` has a contract that it calls both its lambda arguments
in-place: `shuffle(listOf(block1, block2)).forEach { it() }` is a
perfectly valid implementation for it, as little sense as that makes.

So that's what union nodes solve. When a node implements
`UnionNodeMarker`, its inputs are interpreted as "all visited in some
order" instead of the normal "one of the inputs is visited".

Currently this is used for data flow. It *should* also be used for
control flow, but it isn't. But it should be. But that's not so easy.

BTW, `try` exit is NOT a union node; although lambdas in one branch can
be completed according to types' of lambdas in another, data does not
flow between the branches anyway (since we don't know how much of the
`try` executed before jumping into `catch`, and `catch`es are mutually
exclusive) so a `try` expression is more like `when` than a function
call with called-in-place-exactly-once arguments. The fact that
`exitTryExpression` used `processUnionOfArguments` in a weird way
should've hinted at that, but now we know for certain.
2022-12-08 10:19:29 +00:00

647 lines
24 KiB
Plaintext
Vendored

digraph endlessLoops_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function foo" style="filled" fillcolor=red];
1 [label="Exit function foo" style="filled" fillcolor=red];
}
0 -> {1};
subgraph cluster_1 {
color=red
2 [label="Enter class A" style="filled" fillcolor=red];
3 [label="Exit class A" style="filled" fillcolor=red];
}
2 -> {3} [color=green];
subgraph cluster_2 {
color=red
4 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
5 [label="Enter block"];
subgraph cluster_4 {
color=blue
6 [label="Enter while loop"];
subgraph cluster_5 {
color=blue
7 [label="Enter loop condition"];
8 [label="Const: Boolean(true)"];
9 [label="Exit loop condition"];
}
subgraph cluster_6 {
color=blue
10 [label="Enter loop block"];
subgraph cluster_7 {
color=blue
11 [label="Enter block"];
12 [label="Access variable R|<local>/x|"];
13 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_8 {
color=blue
14 [label="Enter when"];
subgraph cluster_9 {
color=blue
15 [label="Enter when branch condition "];
16 [label="Access variable R|<local>/b|"];
17 [label="Exit when branch condition"];
}
18 [label="Synthetic else branch"];
19 [label="Enter when branch result"];
subgraph cluster_10 {
color=blue
20 [label="Enter block"];
21 [label="Jump: break@@@[Boolean(true)] "];
22 [label="Stub" style="filled" fillcolor=gray];
23 [label="Exit block" style="filled" fillcolor=gray];
}
24 [label="Exit when branch result" style="filled" fillcolor=gray];
25 [label="Exit when"];
}
26 [label="Exit block"];
}
27 [label="Exit loop block"];
}
28 [label="Exit whileloop"];
}
29 [label="Access variable R|<local>/x|"];
30 [label="Smart cast: R|<local>/x|"];
31 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=yellow];
32 [label="Exit block"];
}
33 [label="Exit function test_1" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
9 -> {28} [style=dotted];
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {16};
16 -> {17};
17 -> {19 18};
18 -> {25};
19 -> {20};
20 -> {21};
21 -> {28};
21 -> {22} [style=dotted];
22 -> {23} [style=dotted];
23 -> {24} [style=dotted];
24 -> {25} [style=dotted];
25 -> {26};
26 -> {27};
27 -> {7} [color=green style=dashed];
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {32};
32 -> {33};
subgraph cluster_11 {
color=red
34 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
35 [label="Enter block"];
subgraph cluster_13 {
color=blue
36 [label="Enter while loop"];
subgraph cluster_14 {
color=blue
37 [label="Enter loop condition"];
38 [label="Const: Boolean(true)"];
39 [label="Exit loop condition"];
}
subgraph cluster_15 {
color=blue
40 [label="Enter loop block"];
subgraph cluster_16 {
color=blue
41 [label="Enter block"];
subgraph cluster_17 {
color=blue
42 [label="Enter when"];
subgraph cluster_18 {
color=blue
43 [label="Enter when branch condition "];
44 [label="Access variable R|<local>/b|"];
45 [label="Exit when branch condition"];
}
46 [label="Synthetic else branch"];
47 [label="Enter when branch result"];
subgraph cluster_19 {
color=blue
48 [label="Enter block"];
49 [label="Access variable R|<local>/x|"];
50 [label="Type operator: (R|<local>/x| as R|A|)"];
51 [label="Jump: break@@@[Boolean(true)] "];
52 [label="Stub" style="filled" fillcolor=gray];
53 [label="Exit block" style="filled" fillcolor=gray];
}
54 [label="Exit when branch result" style="filled" fillcolor=gray];
55 [label="Exit when"];
}
56 [label="Exit block"];
}
57 [label="Exit loop block"];
}
58 [label="Exit whileloop"];
}
59 [label="Access variable R|<local>/x|"];
60 [label="Smart cast: R|<local>/x|"];
61 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=yellow];
62 [label="Exit block"];
}
63 [label="Exit function test_2" style="filled" fillcolor=red];
}
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
39 -> {58} [style=dotted];
40 -> {41};
41 -> {42};
42 -> {43};
43 -> {44};
44 -> {45};
45 -> {47 46};
46 -> {55};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {51};
51 -> {58};
51 -> {52} [style=dotted];
52 -> {53} [style=dotted];
53 -> {54} [style=dotted];
54 -> {55} [style=dotted];
55 -> {56};
56 -> {57};
57 -> {37} [color=green style=dashed];
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
62 -> {63};
subgraph cluster_20 {
color=red
64 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_21 {
color=blue
65 [label="Enter block"];
subgraph cluster_22 {
color=blue
66 [label="Enter while loop"];
subgraph cluster_23 {
color=blue
67 [label="Enter loop condition"];
68 [label="Const: Boolean(true)"];
69 [label="Exit loop condition"];
}
subgraph cluster_24 {
color=blue
70 [label="Enter loop block"];
subgraph cluster_25 {
color=blue
71 [label="Enter block"];
72 [label="Access variable R|<local>/x|"];
73 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_26 {
color=blue
74 [label="Enter when"];
subgraph cluster_27 {
color=blue
75 [label="Enter when branch condition "];
76 [label="Access variable R|<local>/b|"];
77 [label="Exit when branch condition"];
}
78 [label="Synthetic else branch"];
79 [label="Enter when branch result"];
subgraph cluster_28 {
color=blue
80 [label="Enter block"];
81 [label="Jump: break@@@[Boolean(true)] "];
82 [label="Stub" style="filled" fillcolor=gray];
83 [label="Exit block" style="filled" fillcolor=gray];
}
84 [label="Exit when branch result" style="filled" fillcolor=gray];
85 [label="Exit when"];
}
subgraph cluster_29 {
color=blue
86 [label="Enter when"];
subgraph cluster_30 {
color=blue
87 [label="Enter when branch condition "];
88 [label="Access variable R|<local>/b|"];
89 [label="Exit when branch condition"];
}
90 [label="Synthetic else branch"];
91 [label="Enter when branch result"];
subgraph cluster_31 {
color=blue
92 [label="Enter block"];
93 [label="Jump: break@@@[Boolean(true)] "];
94 [label="Stub" style="filled" fillcolor=gray];
95 [label="Exit block" style="filled" fillcolor=gray];
}
96 [label="Exit when branch result" style="filled" fillcolor=gray];
97 [label="Exit when"];
}
98 [label="Exit block"];
}
99 [label="Exit loop block"];
}
100 [label="Exit whileloop"];
}
101 [label="Access variable R|<local>/x|"];
102 [label="Smart cast: R|<local>/x|"];
103 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=yellow];
104 [label="Exit block"];
}
105 [label="Exit function test_3" style="filled" fillcolor=red];
}
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
69 -> {100} [style=dotted];
70 -> {71};
71 -> {72};
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {77};
77 -> {79 78};
78 -> {85};
79 -> {80};
80 -> {81};
81 -> {100};
81 -> {82} [style=dotted];
82 -> {83} [style=dotted];
83 -> {84} [style=dotted];
84 -> {85} [style=dotted];
85 -> {86};
86 -> {87};
87 -> {88};
88 -> {89};
89 -> {91 90};
90 -> {97};
91 -> {92};
92 -> {93};
93 -> {100};
93 -> {94} [style=dotted];
94 -> {95} [style=dotted];
95 -> {96} [style=dotted];
96 -> {97} [style=dotted];
97 -> {98};
98 -> {99};
99 -> {67} [color=green style=dashed];
100 -> {101};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
subgraph cluster_32 {
color=red
106 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
107 [label="Enter block"];
subgraph cluster_34 {
color=blue
108 [label="Enter while loop"];
subgraph cluster_35 {
color=blue
109 [label="Enter loop condition"];
110 [label="Const: Boolean(true)"];
111 [label="Exit loop condition"];
}
subgraph cluster_36 {
color=blue
112 [label="Enter loop block"];
subgraph cluster_37 {
color=blue
113 [label="Enter block"];
subgraph cluster_38 {
color=blue
114 [label="Enter when"];
subgraph cluster_39 {
color=blue
115 [label="Enter when branch condition "];
116 [label="Access variable R|<local>/b|"];
117 [label="Exit when branch condition"];
}
118 [label="Synthetic else branch"];
119 [label="Enter when branch result"];
subgraph cluster_40 {
color=blue
120 [label="Enter block"];
121 [label="Access variable R|<local>/x|"];
122 [label="Type operator: (R|<local>/x| as R|A|)"];
123 [label="Jump: break@@@[Boolean(true)] "];
124 [label="Stub" style="filled" fillcolor=gray];
125 [label="Exit block" style="filled" fillcolor=gray];
}
126 [label="Exit when branch result" style="filled" fillcolor=gray];
127 [label="Exit when"];
}
128 [label="Jump: break@@@[Boolean(true)] "];
129 [label="Stub" style="filled" fillcolor=gray];
130 [label="Exit block" style="filled" fillcolor=gray];
}
131 [label="Exit loop block" style="filled" fillcolor=gray];
}
132 [label="Exit whileloop"];
}
133 [label="Access variable R|<local>/x|"];
134 [label="Function call: R|<local>/x|.<Unresolved name: foo>#()" style="filled" fillcolor=yellow];
135 [label="Exit block"];
}
136 [label="Exit function test_4" style="filled" fillcolor=red];
}
106 -> {107};
107 -> {108};
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
111 -> {132} [style=dotted];
112 -> {113};
113 -> {114};
114 -> {115};
115 -> {116};
116 -> {117};
117 -> {119 118};
118 -> {127};
119 -> {120};
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {132};
123 -> {124} [style=dotted];
124 -> {125} [style=dotted];
125 -> {126} [style=dotted];
126 -> {127} [style=dotted];
127 -> {128};
128 -> {132};
128 -> {129} [style=dotted];
129 -> {130} [style=dotted];
130 -> {131} [style=dotted];
131 -> {109} [color=green style=dotted];
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {136};
subgraph cluster_41 {
color=red
137 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_42 {
color=blue
138 [label="Enter block"];
subgraph cluster_43 {
color=blue
139 [label="Enter do-while loop"];
subgraph cluster_44 {
color=blue
140 [label="Enter loop block"];
subgraph cluster_45 {
color=blue
141 [label="Enter block"];
subgraph cluster_46 {
color=blue
142 [label="Enter when"];
subgraph cluster_47 {
color=blue
143 [label="Enter when branch condition "];
144 [label="Access variable R|<local>/b|"];
145 [label="Exit when branch condition"];
}
146 [label="Synthetic else branch"];
147 [label="Enter when branch result"];
subgraph cluster_48 {
color=blue
148 [label="Enter block"];
149 [label="Access variable R|<local>/x|"];
150 [label="Type operator: (R|<local>/x| as R|A|)"];
151 [label="Jump: break@@@[Boolean(true)] "];
152 [label="Stub" style="filled" fillcolor=gray];
153 [label="Exit block" style="filled" fillcolor=gray];
}
154 [label="Exit when branch result" style="filled" fillcolor=gray];
155 [label="Exit when"];
}
156 [label="Exit block"];
}
157 [label="Exit loop block"];
}
subgraph cluster_49 {
color=blue
158 [label="Enter loop condition"];
159 [label="Const: Boolean(true)"];
160 [label="Exit loop condition"];
}
161 [label="Exit do-whileloop"];
}
162 [label="Access variable R|<local>/x|"];
163 [label="Smart cast: R|<local>/x|"];
164 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=yellow];
165 [label="Exit block"];
}
166 [label="Exit function test_5" style="filled" fillcolor=red];
}
137 -> {138};
138 -> {139};
139 -> {140};
140 -> {141};
141 -> {142};
142 -> {143};
143 -> {144};
144 -> {145};
145 -> {147 146};
146 -> {155};
147 -> {148};
148 -> {149};
149 -> {150};
150 -> {151};
151 -> {161};
151 -> {152} [style=dotted];
152 -> {153} [style=dotted];
153 -> {154} [style=dotted];
154 -> {155} [style=dotted];
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
159 -> {160};
160 -> {161} [style=dotted];
160 -> {140} [color=green style=dashed];
161 -> {162};
162 -> {163};
163 -> {164};
164 -> {165};
165 -> {166};
subgraph cluster_50 {
color=red
167 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_51 {
color=blue
168 [label="Enter block"];
subgraph cluster_52 {
color=blue
169 [label="Enter do-while loop"];
subgraph cluster_53 {
color=blue
170 [label="Enter loop block"];
subgraph cluster_54 {
color=blue
171 [label="Enter block"];
172 [label="Access variable R|<local>/x|"];
173 [label="Type operator: (R|<local>/x| as R|A|)"];
subgraph cluster_55 {
color=blue
174 [label="Enter when"];
subgraph cluster_56 {
color=blue
175 [label="Enter when branch condition "];
176 [label="Access variable R|<local>/b|"];
177 [label="Exit when branch condition"];
}
178 [label="Synthetic else branch"];
179 [label="Enter when branch result"];
subgraph cluster_57 {
color=blue
180 [label="Enter block"];
181 [label="Jump: break@@@[Boolean(true)] "];
182 [label="Stub" style="filled" fillcolor=gray];
183 [label="Exit block" style="filled" fillcolor=gray];
}
184 [label="Exit when branch result" style="filled" fillcolor=gray];
185 [label="Exit when"];
}
186 [label="Exit block"];
}
187 [label="Exit loop block"];
}
subgraph cluster_58 {
color=blue
188 [label="Enter loop condition"];
189 [label="Const: Boolean(true)"];
190 [label="Exit loop condition"];
}
191 [label="Exit do-whileloop"];
}
192 [label="Access variable R|<local>/x|"];
193 [label="Smart cast: R|<local>/x|"];
194 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=yellow];
195 [label="Exit block"];
}
196 [label="Exit function test_6" style="filled" fillcolor=red];
}
167 -> {168};
168 -> {169};
169 -> {170};
170 -> {171};
171 -> {172};
172 -> {173};
173 -> {174};
174 -> {175};
175 -> {176};
176 -> {177};
177 -> {179 178};
178 -> {185};
179 -> {180};
180 -> {181};
181 -> {191};
181 -> {182} [style=dotted];
182 -> {183} [style=dotted];
183 -> {184} [style=dotted];
184 -> {185} [style=dotted];
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {189};
189 -> {190};
190 -> {191} [style=dotted];
190 -> {170} [color=green style=dashed];
191 -> {192};
192 -> {193};
193 -> {194};
194 -> {195};
195 -> {196};
subgraph cluster_59 {
color=red
197 [label="Enter function test_7" style="filled" fillcolor=red];
subgraph cluster_60 {
color=blue
198 [label="Enter block"];
subgraph cluster_61 {
color=blue
199 [label="Enter do-while loop"];
subgraph cluster_62 {
color=blue
200 [label="Enter loop block"];
subgraph cluster_63 {
color=blue
201 [label="Enter block"];
202 [label="Access variable R|<local>/x|"];
203 [label="Type operator: (R|<local>/x| as R|A|)"];
204 [label="Exit block"];
}
205 [label="Exit loop block"];
}
subgraph cluster_64 {
color=blue
206 [label="Enter loop condition"];
207 [label="Const: Boolean(true)"];
208 [label="Exit loop condition"];
}
209 [label="Exit do-whileloop" style="filled" fillcolor=gray];
}
210 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
211 [label="Smart cast: R|<local>/x|" style="filled" fillcolor=gray];
212 [label="Function call: R|<local>/x|.R|/A.foo|()" style="filled" fillcolor=gray];
213 [label="Exit block" style="filled" fillcolor=gray];
}
214 [label="Exit function test_7" style="filled" fillcolor=red style="filled" fillcolor=gray];
}
197 -> {198};
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {202};
202 -> {203};
203 -> {204};
204 -> {205};
205 -> {206};
206 -> {207};
207 -> {208};
208 -> {209} [style=dotted];
208 -> {200} [color=green style=dashed];
209 -> {210} [style=dotted];
210 -> {211} [style=dotted];
211 -> {212} [style=dotted];
212 -> {213} [style=dotted];
213 -> {214} [style=dotted];
}