diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/defaultArguments.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/defaultArguments.dot index efe34223ca1..1e397e7153b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/defaultArguments.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/defaultArguments.dot @@ -71,8 +71,8 @@ digraph defaultArguments_kt { 14 -> {15}; 16 -> {17}; 16 -> {16} [style=dashed]; - 17 -> {21}; - 17 -> {18} [color=red]; + 17 -> {21 19}; + 17 -> {18} [style=dotted]; 17 -> {21} [style=dashed]; 18 -> {19}; 19 -> {20}; @@ -80,7 +80,6 @@ digraph defaultArguments_kt { 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {19} [color=red]; - 25 -> {18} [color=green]; + 25 -> {18}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot index d89a8ad0608..10526d930c1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot @@ -209,8 +209,8 @@ digraph flowFromInplaceLambda_kt { } 60 -> {61}; 61 -> {62}; - 62 -> {70}; - 62 -> {63} [color=red]; + 62 -> {70 64}; + 62 -> {63} [style=dotted]; 62 -> {70} [style=dashed]; 63 -> {64}; 64 -> {65}; @@ -223,8 +223,7 @@ digraph flowFromInplaceLambda_kt { 72 -> {73}; 73 -> {74}; 74 -> {75}; - 75 -> {64} [color=red]; - 75 -> {63} [color=green]; + 75 -> {63}; subgraph cluster_20 { color=red @@ -286,18 +285,20 @@ digraph flowFromInplaceLambda_kt { } 76 -> {77}; 77 -> {78}; - 78 -> {97}; - 78 -> {79} [color=red]; + 78 -> {97 80}; + 78 -> {79} [style=dotted]; 78 -> {97} [style=dashed]; - 79 -> {80}; + 79 -> {81} [color=red]; + 79 -> {80} [color=green]; 80 -> {81}; 81 -> {82}; 82 -> {83}; 83 -> {84}; - 84 -> {105}; - 84 -> {85} [color=red]; + 84 -> {105 86}; + 84 -> {85} [style=dotted]; 84 -> {105} [style=dashed]; - 85 -> {86}; + 85 -> {87} [color=red]; + 85 -> {86} [color=green]; 86 -> {87}; 87 -> {88}; 88 -> {89}; @@ -315,8 +316,7 @@ digraph flowFromInplaceLambda_kt { 101 -> {102}; 102 -> {103}; 103 -> {104}; - 104 -> {81} [color=red]; - 104 -> {79} [color=green]; + 104 -> {79}; 105 -> {106}; 106 -> {107}; 107 -> {108}; @@ -327,8 +327,7 @@ digraph flowFromInplaceLambda_kt { 112 -> {113}; 113 -> {114}; 114 -> {115}; - 115 -> {87} [color=red]; - 115 -> {85} [color=green]; + 115 -> {85}; subgraph cluster_26 { color=red @@ -390,19 +389,21 @@ digraph flowFromInplaceLambda_kt { } 116 -> {117}; 117 -> {118}; - 118 -> {137}; - 118 -> {119} [color=red]; + 118 -> {137 120}; + 118 -> {119} [style=dotted]; 118 -> {137} [style=dashed]; - 119 -> {120}; + 119 -> {121} [color=red]; + 119 -> {120} [color=green]; 119 -> {118} [color=green style=dashed]; 120 -> {121}; 121 -> {122}; 122 -> {123}; 123 -> {124}; - 124 -> {145}; - 124 -> {125} [color=red]; + 124 -> {145 126}; + 124 -> {125} [style=dotted]; 124 -> {145} [style=dashed]; - 125 -> {126}; + 125 -> {127} [color=red]; + 125 -> {126} [color=green]; 125 -> {124} [color=green style=dashed]; 126 -> {127}; 127 -> {128}; @@ -421,8 +422,7 @@ digraph flowFromInplaceLambda_kt { 141 -> {142}; 142 -> {143}; 143 -> {144}; - 144 -> {121} [color=red]; - 144 -> {119} [color=green]; + 144 -> {119}; 145 -> {146}; 146 -> {147}; 147 -> {148}; @@ -433,8 +433,7 @@ digraph flowFromInplaceLambda_kt { 152 -> {153}; 153 -> {154}; 154 -> {155}; - 155 -> {127} [color=red]; - 155 -> {125} [color=green]; + 155 -> {125}; subgraph cluster_32 { color=red @@ -494,16 +493,18 @@ digraph flowFromInplaceLambda_kt { } 156 -> {157}; 157 -> {158}; - 158 -> {159 176}; + 158 -> {159 176 160}; 158 -> {176} [style=dashed]; - 159 -> {160}; + 159 -> {161} [color=red]; + 159 -> {160} [color=green]; 160 -> {161}; 161 -> {162}; 162 -> {163}; 163 -> {164}; - 164 -> {165 184}; + 164 -> {165 184 166}; 164 -> {184} [style=dashed]; - 165 -> {166}; + 165 -> {167} [color=red]; + 165 -> {166} [color=green]; 166 -> {167}; 167 -> {168}; 168 -> {169}; @@ -590,17 +591,19 @@ digraph flowFromInplaceLambda_kt { } 194 -> {195}; 195 -> {196}; - 196 -> {197 214}; + 196 -> {197 214 198}; 196 -> {214} [style=dashed]; - 197 -> {198}; + 197 -> {199} [color=red]; + 197 -> {198} [color=green]; 197 -> {196} [color=green style=dashed]; 198 -> {199}; 199 -> {200}; 200 -> {201}; 201 -> {202}; - 202 -> {203 222}; + 202 -> {203 222 204}; 202 -> {222} [style=dashed]; - 203 -> {204}; + 203 -> {205} [color=red]; + 203 -> {204} [color=green]; 203 -> {202} [color=green style=dashed]; 204 -> {205}; 205 -> {206}; @@ -688,16 +691,18 @@ digraph flowFromInplaceLambda_kt { } 232 -> {233}; 233 -> {234}; - 234 -> {235 252}; + 234 -> {235 252 236}; 234 -> {252} [style=dashed]; - 235 -> {236}; + 235 -> {237} [color=red]; + 235 -> {236} [color=green]; 236 -> {237}; 237 -> {238}; 238 -> {239}; 239 -> {240}; - 240 -> {241 260}; + 240 -> {241 260 242}; 240 -> {260} [style=dashed]; - 241 -> {242}; + 241 -> {243} [color=red]; + 241 -> {242} [color=green]; 242 -> {243}; 243 -> {244}; 244 -> {245}; @@ -787,16 +792,18 @@ digraph flowFromInplaceLambda_kt { } 270 -> {271}; 271 -> {272}; - 272 -> {289}; - 272 -> {273} [color=red]; + 272 -> {289 274}; + 272 -> {273} [style=dotted]; 272 -> {289} [style=dashed]; - 273 -> {274}; + 273 -> {279} [color=red]; + 273 -> {274} [color=green]; 274 -> {275}; 275 -> {276}; - 276 -> {301}; - 276 -> {277} [color=red]; + 276 -> {301 278}; + 276 -> {277} [style=dotted]; 276 -> {301} [style=dashed]; - 277 -> {278}; + 277 -> {279} [color=red]; + 277 -> {278} [color=green]; 278 -> {279}; 279 -> {280}; 280 -> {281}; @@ -818,8 +825,7 @@ digraph flowFromInplaceLambda_kt { 297 -> {298}; 298 -> {299}; 299 -> {300}; - 300 -> {279} [color=red]; - 300 -> {273} [color=green]; + 300 -> {273}; 301 -> {302}; 302 -> {303}; 303 -> {304}; @@ -831,8 +837,7 @@ digraph flowFromInplaceLambda_kt { 309 -> {310}; 310 -> {311}; 311 -> {312}; - 312 -> {279} [color=red]; - 312 -> {277} [color=green]; + 312 -> {277}; subgraph cluster_56 { color=red @@ -897,17 +902,19 @@ digraph flowFromInplaceLambda_kt { } 313 -> {314}; 314 -> {315}; - 315 -> {332}; - 315 -> {316} [color=red]; + 315 -> {332 317}; + 315 -> {316} [style=dotted]; 315 -> {332} [style=dashed]; - 316 -> {317}; + 316 -> {322} [color=red]; + 316 -> {317} [color=green]; 316 -> {315} [color=green style=dashed]; 317 -> {318}; 318 -> {319}; - 319 -> {344}; - 319 -> {320} [color=red]; + 319 -> {344 321}; + 319 -> {320} [style=dotted]; 319 -> {344} [style=dashed]; - 320 -> {321}; + 320 -> {322} [color=red]; + 320 -> {321} [color=green]; 320 -> {319} [color=green style=dashed]; 321 -> {322}; 322 -> {323}; @@ -930,8 +937,7 @@ digraph flowFromInplaceLambda_kt { 340 -> {341}; 341 -> {342}; 342 -> {343}; - 343 -> {322} [color=red]; - 343 -> {316} [color=green]; + 343 -> {316}; 344 -> {345}; 345 -> {346}; 346 -> {347}; @@ -943,8 +949,7 @@ digraph flowFromInplaceLambda_kt { 352 -> {353}; 353 -> {354}; 354 -> {355}; - 355 -> {322} [color=red]; - 355 -> {320} [color=green]; + 355 -> {320}; subgraph cluster_62 { color=red @@ -1007,14 +1012,16 @@ digraph flowFromInplaceLambda_kt { } 356 -> {357}; 357 -> {358}; - 358 -> {359 373}; + 358 -> {359 373 360}; 358 -> {373} [style=dashed]; - 359 -> {360}; + 359 -> {365} [color=red]; + 359 -> {360} [color=green]; 360 -> {361}; 361 -> {362}; - 362 -> {363 385}; + 362 -> {363 385 364}; 362 -> {385} [style=dashed]; - 363 -> {364}; + 363 -> {365} [color=red]; + 363 -> {364} [color=green]; 364 -> {365}; 365 -> {366}; 366 -> {367}; @@ -1109,15 +1116,17 @@ digraph flowFromInplaceLambda_kt { } 397 -> {398}; 398 -> {399}; - 399 -> {400 414}; + 399 -> {400 414 401}; 399 -> {414} [style=dashed]; - 400 -> {401}; + 400 -> {406} [color=red]; + 400 -> {401} [color=green]; 400 -> {399} [color=green style=dashed]; 401 -> {402}; 402 -> {403}; - 403 -> {404 426}; + 403 -> {404 426 405}; 403 -> {426} [style=dashed]; - 404 -> {405}; + 404 -> {406} [color=red]; + 404 -> {405} [color=green]; 404 -> {403} [color=green style=dashed]; 405 -> {406}; 406 -> {407}; @@ -1213,14 +1222,16 @@ digraph flowFromInplaceLambda_kt { } 438 -> {439}; 439 -> {440}; - 440 -> {441 455}; + 440 -> {441 455 442}; 440 -> {455} [style=dashed]; - 441 -> {442}; + 441 -> {447} [color=red]; + 441 -> {442} [color=green]; 442 -> {443}; 443 -> {444}; - 444 -> {445 467}; + 444 -> {445 467 446}; 444 -> {467} [style=dashed]; - 445 -> {446}; + 445 -> {447} [color=red]; + 445 -> {446} [color=green]; 446 -> {447}; 447 -> {448}; 448 -> {449}; @@ -1296,15 +1307,17 @@ digraph flowFromInplaceLambda_kt { } 479 -> {480}; 480 -> {481}; - 481 -> {493}; - 481 -> {482} [color=red]; + 481 -> {493 483}; + 481 -> {482} [style=dotted]; 481 -> {493} [style=dashed]; - 482 -> {483}; + 482 -> {487} [color=red]; + 482 -> {483} [color=green]; 483 -> {484}; - 484 -> {498}; - 484 -> {485} [color=red]; + 484 -> {498 486}; + 484 -> {485} [style=dotted]; 484 -> {498} [style=dashed]; - 485 -> {486}; + 485 -> {487} [color=red]; + 485 -> {486} [color=green]; 486 -> {487}; 487 -> {488}; 488 -> {489}; @@ -1315,14 +1328,12 @@ digraph flowFromInplaceLambda_kt { 494 -> {495}; 495 -> {496}; 496 -> {497}; - 497 -> {487} [color=red]; - 497 -> {482} [color=green]; + 497 -> {482}; 498 -> {499}; 499 -> {500}; 500 -> {501}; 501 -> {502}; - 502 -> {487} [color=red]; - 502 -> {485} [color=green]; + 502 -> {485}; subgraph cluster_86 { color=red @@ -1367,9 +1378,10 @@ digraph flowFromInplaceLambda_kt { } 503 -> {504}; 504 -> {505}; - 505 -> {506 514}; + 505 -> {506 514 507}; 505 -> {514} [style=dashed]; - 506 -> {507}; + 506 -> {508} [color=red]; + 506 -> {507} [color=green]; 507 -> {508}; 508 -> {509}; 509 -> {510}; @@ -1378,16 +1390,17 @@ digraph flowFromInplaceLambda_kt { 512 -> {513}; 514 -> {515}; 515 -> {516}; - 516 -> {521}; - 516 -> {517} [color=red]; + 516 -> {521 518}; + 516 -> {517} [style=dotted]; 516 -> {521} [style=dashed]; - 517 -> {518}; + 517 -> {508} [color=red]; + 517 -> {518} [color=green]; 518 -> {519}; 519 -> {520}; 521 -> {522}; 522 -> {523}; 523 -> {524}; 524 -> {525}; - 525 -> {517} [color=green]; + 525 -> {517}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot index 55e712c2762..94aefedf769 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot @@ -130,17 +130,19 @@ digraph flowFromInplaceLambda2_kt { } 25 -> {26}; 26 -> {27}; - 27 -> {41}; - 27 -> {28} [color=red]; + 27 -> {41 29}; + 27 -> {28} [style=dotted]; 27 -> {41} [style=dashed]; - 28 -> {29}; + 28 -> {35} [color=red]; + 28 -> {29} [color=green]; 29 -> {30}; 30 -> {31}; 31 -> {32}; - 32 -> {48}; - 32 -> {33} [color=red]; + 32 -> {48 34}; + 32 -> {33} [style=dotted]; 32 -> {48} [style=dashed]; - 33 -> {34}; + 33 -> {35} [color=red]; + 33 -> {34} [color=green]; 34 -> {35}; 35 -> {36}; 36 -> {37}; @@ -153,16 +155,14 @@ digraph flowFromInplaceLambda2_kt { 44 -> {45}; 45 -> {46}; 46 -> {47}; - 47 -> {35} [color=red]; - 47 -> {28} [color=green]; + 47 -> {28}; 48 -> {49}; 49 -> {50}; 50 -> {51}; 51 -> {52}; 52 -> {53}; 53 -> {54}; - 54 -> {35} [color=red]; - 54 -> {33} [color=green]; + 54 -> {33}; subgraph cluster_14 { color=red @@ -215,18 +215,20 @@ digraph flowFromInplaceLambda2_kt { } 55 -> {56}; 56 -> {57}; - 57 -> {72}; - 57 -> {58} [color=red]; + 57 -> {72 59}; + 57 -> {58} [style=dotted]; 57 -> {72} [style=dashed]; - 58 -> {59}; + 58 -> {66} [color=red]; + 58 -> {59} [color=green]; 59 -> {60}; 60 -> {61}; 61 -> {62}; 62 -> {63}; - 63 -> {79}; - 63 -> {64} [color=red]; + 63 -> {79 65}; + 63 -> {64} [style=dotted]; 63 -> {79} [style=dashed]; - 64 -> {65}; + 64 -> {66} [color=red]; + 64 -> {65} [color=green]; 65 -> {66}; 66 -> {67}; 67 -> {68}; @@ -239,16 +241,14 @@ digraph flowFromInplaceLambda2_kt { 75 -> {76}; 76 -> {77}; 77 -> {78}; - 78 -> {66} [color=red]; - 78 -> {58} [color=green]; + 78 -> {58}; 79 -> {80}; 80 -> {81}; 81 -> {82}; 82 -> {83}; 83 -> {84}; 84 -> {85}; - 85 -> {66} [color=red]; - 85 -> {64} [color=green]; + 85 -> {64}; subgraph cluster_20 { color=red @@ -331,10 +331,11 @@ digraph flowFromInplaceLambda2_kt { } 86 -> {87}; 87 -> {88}; - 88 -> {118}; - 88 -> {89} [color=red]; + 88 -> {118 90}; + 88 -> {89} [style=dotted]; 88 -> {118} [style=dashed]; - 89 -> {90}; + 89 -> {112} [color=red]; + 89 -> {90} [color=green]; 90 -> {91}; 91 -> {92}; 92 -> {93}; @@ -354,10 +355,11 @@ digraph flowFromInplaceLambda2_kt { 106 -> {107}; 107 -> {108}; 108 -> {109}; - 109 -> {125}; - 109 -> {110} [color=red]; + 109 -> {125 111}; + 109 -> {110} [style=dotted]; 109 -> {125} [style=dashed]; - 110 -> {111}; + 110 -> {112} [color=red]; + 110 -> {111} [color=green]; 111 -> {112}; 112 -> {113}; 113 -> {114}; @@ -370,16 +372,14 @@ digraph flowFromInplaceLambda2_kt { 121 -> {122}; 122 -> {123}; 123 -> {124}; - 124 -> {112} [color=red]; - 124 -> {89} [color=green]; + 124 -> {89}; 125 -> {126}; 126 -> {127}; 127 -> {128}; 128 -> {129}; 129 -> {130}; 130 -> {131}; - 131 -> {112} [color=red]; - 131 -> {110} [color=green]; + 131 -> {110}; subgraph cluster_31 { color=red @@ -518,29 +518,32 @@ digraph flowFromInplaceLambda2_kt { 150 -> {151}; 151 -> {152}; 152 -> {153}; - 153 -> {187}; - 153 -> {154} [color=red]; + 153 -> {187 155}; + 153 -> {154} [style=dotted]; 153 -> {187} [style=dashed]; - 154 -> {155}; + 154 -> {171} [color=red]; + 154 -> {155} [color=green]; 155 -> {156}; 156 -> {157}; 157 -> {165}; 158 -> {159}; 159 -> {160}; - 160 -> {180}; - 160 -> {161} [color=red]; + 160 -> {180 162}; + 160 -> {161} [style=dotted]; 160 -> {180} [style=dashed]; - 161 -> {162}; + 161 -> {171} [color=red]; + 161 -> {162} [color=green]; 162 -> {163}; 163 -> {164}; 164 -> {165}; 165 -> {171 166}; 166 -> {167}; 167 -> {168}; - 168 -> {192}; - 168 -> {169} [color=red]; + 168 -> {192 170}; + 168 -> {169} [style=dotted]; 168 -> {192} [style=dashed]; - 169 -> {170}; + 169 -> {172} [color=red]; + 169 -> {170} [color=green]; 170 -> {172}; 171 -> {172} [color=red]; 172 -> {173}; @@ -556,14 +559,12 @@ digraph flowFromInplaceLambda2_kt { 183 -> {184}; 184 -> {185}; 185 -> {186}; - 186 -> {171} [color=red]; - 186 -> {161} [color=green]; + 186 -> {161}; 187 -> {188}; 188 -> {189}; 189 -> {190}; 190 -> {191}; - 191 -> {171} [color=red]; - 191 -> {154} [color=green]; + 191 -> {154}; 192 -> {193}; 193 -> {194}; 194 -> {195}; @@ -571,8 +572,7 @@ digraph flowFromInplaceLambda2_kt { 196 -> {197}; 197 -> {198}; 198 -> {199}; - 199 -> {172} [color=red]; - 199 -> {169} [color=green]; + 199 -> {169}; subgraph cluster_47 { color=red @@ -626,17 +626,19 @@ digraph flowFromInplaceLambda2_kt { 201 -> {202}; 202 -> {203 207}; 203 -> {204}; - 204 -> {218}; - 204 -> {205} [color=red]; + 204 -> {218 206}; + 204 -> {205} [style=dotted]; 204 -> {218} [style=dashed]; - 205 -> {206}; + 205 -> {212} [color=red]; + 205 -> {206} [color=green]; 206 -> {207}; 207 -> {212 208}; 208 -> {209}; - 209 -> {225}; - 209 -> {210} [color=red]; + 209 -> {225 211}; + 209 -> {210} [style=dotted]; 209 -> {225} [style=dashed]; - 210 -> {211}; + 210 -> {213} [color=red]; + 210 -> {211} [color=green]; 211 -> {213}; 212 -> {213} [color=red]; 213 -> {214}; @@ -649,14 +651,12 @@ digraph flowFromInplaceLambda2_kt { 221 -> {222}; 222 -> {223}; 223 -> {224}; - 224 -> {212} [color=red]; - 224 -> {205} [color=green]; + 224 -> {205}; 225 -> {226}; 226 -> {227}; 227 -> {228}; 228 -> {229}; - 229 -> {213} [color=red]; - 229 -> {210} [color=green]; + 229 -> {210}; subgraph cluster_53 { color=red @@ -762,29 +762,32 @@ digraph flowFromInplaceLambda2_kt { 237 -> {238}; 238 -> {239}; 239 -> {240}; - 240 -> {271}; - 240 -> {241} [color=red]; + 240 -> {271 242}; + 240 -> {241} [style=dotted]; 240 -> {271} [style=dashed]; - 241 -> {242}; + 241 -> {258} [color=red]; + 241 -> {242} [color=green]; 242 -> {243}; 243 -> {244}; 244 -> {252}; 245 -> {246}; 246 -> {247}; - 247 -> {264}; - 247 -> {248} [color=red]; + 247 -> {264 249}; + 247 -> {248} [style=dotted]; 247 -> {264} [style=dashed]; - 248 -> {249}; + 248 -> {258} [color=red]; + 248 -> {249} [color=green]; 249 -> {250}; 250 -> {251}; 251 -> {252}; 252 -> {258 253}; 253 -> {254}; 254 -> {255}; - 255 -> {278}; - 255 -> {256} [color=red]; + 255 -> {278 257}; + 255 -> {256} [style=dotted]; 255 -> {278} [style=dashed]; - 256 -> {257}; + 256 -> {259} [color=red]; + 256 -> {257} [color=green]; 257 -> {259}; 258 -> {259} [color=red]; 259 -> {260}; @@ -797,24 +800,21 @@ digraph flowFromInplaceLambda2_kt { 267 -> {268}; 268 -> {269}; 269 -> {270}; - 270 -> {258} [color=red]; - 270 -> {248} [color=green]; + 270 -> {248}; 271 -> {272}; 272 -> {273}; 273 -> {274}; 274 -> {275}; 275 -> {276}; 276 -> {277}; - 277 -> {258} [color=red]; - 277 -> {241} [color=green]; + 277 -> {241}; 278 -> {279}; 279 -> {280}; 280 -> {281}; 281 -> {282}; 282 -> {283}; 283 -> {284}; - 284 -> {259} [color=red]; - 284 -> {256} [color=green]; + 284 -> {256}; subgraph cluster_66 { color=red @@ -901,17 +901,19 @@ digraph flowFromInplaceLambda2_kt { 295 -> {312}; 296 -> {297}; 297 -> {298}; - 298 -> {315}; - 298 -> {299} [color=red]; + 298 -> {315 300}; + 298 -> {299} [style=dotted]; 298 -> {315} [style=dashed]; - 299 -> {300}; + 299 -> {306} [color=red]; + 299 -> {300} [color=green]; 300 -> {301}; 301 -> {302}; 302 -> {303}; - 303 -> {322}; - 303 -> {304} [color=red]; + 303 -> {322 305}; + 303 -> {304} [style=dotted]; 303 -> {322} [style=dashed]; - 304 -> {305}; + 304 -> {306} [color=red]; + 304 -> {305} [color=green]; 305 -> {306}; 306 -> {307}; 307 -> {308}; @@ -927,8 +929,7 @@ digraph flowFromInplaceLambda2_kt { 318 -> {319}; 319 -> {320}; 320 -> {321}; - 321 -> {306} [color=red]; - 321 -> {299} [color=green]; + 321 -> {299}; 322 -> {323}; 323 -> {324}; 324 -> {325}; @@ -936,7 +937,6 @@ digraph flowFromInplaceLambda2_kt { 326 -> {327}; 327 -> {328}; 328 -> {329}; - 329 -> {306} [color=red]; - 329 -> {304} [color=green]; + 329 -> {304}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda3.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda3.dot index ef78941b87a..8d9674908cf 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda3.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda3.dot @@ -110,7 +110,7 @@ digraph flowFromInplaceLambda3_kt { 24 -> {25}; 25 -> {26}; 26 -> {27}; - 27 -> {28 38}; + 27 -> {28 38 29}; 27 -> {38} [style=dashed]; 28 -> {29}; 28 -> {27} [color=green style=dashed]; @@ -171,7 +171,7 @@ digraph flowFromInplaceLambda3_kt { 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {53 60}; + 52 -> {53 60 54}; 52 -> {60} [style=dashed]; 53 -> {54}; 53 -> {52} [color=green style=dashed]; @@ -232,8 +232,8 @@ digraph flowFromInplaceLambda3_kt { 71 -> {72}; 72 -> {73}; 73 -> {74}; - 74 -> {85}; - 74 -> {75} [color=red]; + 74 -> {85 76}; + 74 -> {75} [style=dotted]; 74 -> {85} [style=dashed]; 75 -> {76}; 75 -> {74} [color=green style=dashed]; @@ -250,8 +250,7 @@ digraph flowFromInplaceLambda3_kt { 87 -> {88}; 88 -> {89}; 89 -> {90}; - 90 -> {76} [color=red]; - 90 -> {75} [color=green]; + 90 -> {75}; subgraph cluster_20 { color=red @@ -298,8 +297,8 @@ digraph flowFromInplaceLambda3_kt { 96 -> {97}; 97 -> {98}; 98 -> {99}; - 99 -> {110}; - 99 -> {100} [color=red]; + 99 -> {110 101}; + 99 -> {100} [style=dotted]; 99 -> {110} [style=dashed]; 100 -> {101}; 101 -> {102}; @@ -315,8 +314,7 @@ digraph flowFromInplaceLambda3_kt { 112 -> {113}; 113 -> {114}; 114 -> {115}; - 115 -> {101} [color=red]; - 115 -> {100} [color=green]; + 115 -> {100}; subgraph cluster_24 { color=red @@ -363,7 +361,7 @@ digraph flowFromInplaceLambda3_kt { 121 -> {122}; 122 -> {123}; 123 -> {124}; - 124 -> {125 135}; + 124 -> {125 135 126}; 124 -> {135} [style=dashed]; 125 -> {126}; 126 -> {127}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.dot index 03a916593cc..19a419ccd33 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.dot @@ -80,7 +80,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 45 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 27 [label="Postponed exit from lambda"]; 28 [label="Postponed enter to lambda"]; subgraph cluster_11 { color=blue @@ -97,6 +96,7 @@ digraph flowFromTwoInplaceLambdas_kt { 53 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 29 [label="Postponed exit from lambda"]; + 27 [label="Postponed exit from lambda"]; 30 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 31 [label="Access variable R|/p|"]; 32 [label="Smart cast: R|/p|"]; @@ -123,12 +123,12 @@ digraph flowFromTwoInplaceLambdas_kt { 23 -> {36}; 24 -> {25}; 25 -> {26}; - 26 -> {39}; - 26 -> {27} [color=red]; + 26 -> {28 39}; + 26 -> {27} [style=dotted]; 26 -> {39} [style=dashed]; - 27 -> {28}; - 28 -> {46}; - 28 -> {29} [color=red]; + 27 -> {30}; + 28 -> {46 30}; + 28 -> {29} [style=dotted]; 28 -> {46} [style=dashed]; 29 -> {30}; 30 -> {31}; @@ -145,8 +145,7 @@ digraph flowFromTwoInplaceLambdas_kt { 42 -> {43}; 43 -> {44}; 44 -> {45}; - 45 -> {30} [color=red]; - 45 -> {27} [color=green]; + 45 -> {27}; 46 -> {47}; 47 -> {48}; 48 -> {49}; @@ -154,8 +153,7 @@ digraph flowFromTwoInplaceLambdas_kt { 50 -> {51}; 51 -> {52}; 52 -> {53}; - 53 -> {30} [color=red]; - 53 -> {29} [color=green]; + 53 -> {29}; subgraph cluster_13 { color=red @@ -196,7 +194,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 94 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 68 [label="Postponed exit from lambda"]; 69 [label="Postponed enter to lambda"]; subgraph cluster_20 { color=blue @@ -212,6 +209,7 @@ digraph flowFromTwoInplaceLambdas_kt { 86 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 70 [label="Postponed exit from lambda"]; + 68 [label="Postponed exit from lambda"]; 71 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 72 [label="Access variable R|/p|"]; 73 [label="Smart cast: R|/p|"]; @@ -238,12 +236,12 @@ digraph flowFromTwoInplaceLambdas_kt { 64 -> {77}; 65 -> {66}; 66 -> {67}; - 67 -> {87}; - 67 -> {68} [color=red]; + 67 -> {69 87}; + 67 -> {68} [style=dotted]; 67 -> {87} [style=dashed]; - 68 -> {69}; - 69 -> {80}; - 69 -> {70} [color=red]; + 68 -> {71}; + 69 -> {80 71}; + 69 -> {70} [style=dotted]; 69 -> {80} [style=dashed]; 70 -> {71}; 71 -> {72}; @@ -260,8 +258,7 @@ digraph flowFromTwoInplaceLambdas_kt { 83 -> {84}; 84 -> {85}; 85 -> {86}; - 86 -> {71} [color=red]; - 86 -> {70} [color=green]; + 86 -> {70}; 87 -> {88}; 88 -> {89}; 89 -> {90}; @@ -269,8 +266,7 @@ digraph flowFromTwoInplaceLambdas_kt { 91 -> {92}; 92 -> {93}; 93 -> {94}; - 94 -> {71} [color=red]; - 94 -> {68} [color=green]; + 94 -> {68}; subgraph cluster_22 { color=red @@ -296,7 +292,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 122 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 102 [label="Postponed exit from lambda"]; 103 [label="Postponed enter to lambda"]; subgraph cluster_26 { color=blue @@ -312,6 +307,7 @@ digraph flowFromTwoInplaceLambdas_kt { 129 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 104 [label="Postponed exit from lambda"]; + 102 [label="Postponed exit from lambda"]; 105 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 106 [label="Access variable R|/p|"]; 107 [label="Smart cast: R|/p|"]; @@ -331,12 +327,12 @@ digraph flowFromTwoInplaceLambdas_kt { 98 -> {99}; 99 -> {100}; 100 -> {101}; - 101 -> {116}; - 101 -> {102} [color=red]; + 101 -> {103 116}; + 101 -> {102} [style=dotted]; 101 -> {116} [style=dashed]; - 102 -> {103}; - 103 -> {123}; - 103 -> {104} [color=red]; + 102 -> {105}; + 103 -> {123 105}; + 103 -> {104} [style=dotted]; 103 -> {123} [style=dashed]; 104 -> {105}; 105 -> {106}; @@ -355,16 +351,14 @@ digraph flowFromTwoInplaceLambdas_kt { 119 -> {120}; 120 -> {121}; 121 -> {122}; - 122 -> {105} [color=red]; - 122 -> {102} [color=green]; + 122 -> {102}; 123 -> {124}; 124 -> {125}; 125 -> {126}; 126 -> {127}; 127 -> {128}; 128 -> {129}; - 129 -> {105} [color=red]; - 129 -> {104} [color=green]; + 129 -> {104}; subgraph cluster_28 { color=red @@ -390,7 +384,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 157 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 137 [label="Postponed exit from lambda"]; 138 [label="Postponed enter to lambda"]; subgraph cluster_32 { color=blue @@ -406,6 +399,7 @@ digraph flowFromTwoInplaceLambdas_kt { 164 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 139 [label="Postponed exit from lambda"]; + 137 [label="Postponed exit from lambda"]; 140 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 141 [label="Access variable R|/p|"]; 142 [label="Smart cast: R|/p|"]; @@ -425,12 +419,12 @@ digraph flowFromTwoInplaceLambdas_kt { 133 -> {134}; 134 -> {135}; 135 -> {136}; - 136 -> {151}; - 136 -> {137} [color=red]; + 136 -> {138 151}; + 136 -> {137} [style=dotted]; 136 -> {151} [style=dashed]; - 137 -> {138}; - 138 -> {158}; - 138 -> {139} [color=red]; + 137 -> {140}; + 138 -> {158 140}; + 138 -> {139} [style=dotted]; 138 -> {158} [style=dashed]; 139 -> {140}; 140 -> {141}; @@ -449,16 +443,14 @@ digraph flowFromTwoInplaceLambdas_kt { 154 -> {155}; 155 -> {156}; 156 -> {157}; - 157 -> {140} [color=red]; - 157 -> {137} [color=green]; + 157 -> {137}; 158 -> {159}; 159 -> {160}; 160 -> {161}; 161 -> {162}; 162 -> {163}; 163 -> {164}; - 164 -> {140} [color=red]; - 164 -> {139} [color=green]; + 164 -> {139}; subgraph cluster_34 { color=red @@ -501,7 +493,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 197 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 176 [label="Postponed exit from lambda"]; 177 [label="Postponed enter to lambda"]; subgraph cluster_40 { color=blue @@ -520,6 +511,7 @@ digraph flowFromTwoInplaceLambdas_kt { 207 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 178 [label="Postponed exit from lambda"]; + 176 [label="Postponed exit from lambda"]; 179 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 180 [label="Access variable R|/x|"]; 181 [label="Smart cast: R|/x|"]; @@ -537,12 +529,12 @@ digraph flowFromTwoInplaceLambdas_kt { 172 -> {173}; 173 -> {174}; 174 -> {175}; - 175 -> {188}; - 175 -> {176} [color=red]; + 175 -> {177 188}; + 175 -> {176} [style=dotted]; 175 -> {188} [style=dashed]; - 176 -> {177}; - 177 -> {198}; - 177 -> {178} [color=red]; + 176 -> {179}; + 177 -> {198 179}; + 177 -> {178} [style=dotted]; 177 -> {198} [style=dashed]; 178 -> {179}; 179 -> {180}; @@ -562,8 +554,7 @@ digraph flowFromTwoInplaceLambdas_kt { 194 -> {195}; 195 -> {196}; 196 -> {197}; - 197 -> {179} [color=red]; - 197 -> {176} [color=green]; + 197 -> {176}; 198 -> {199}; 199 -> {200}; 200 -> {201}; @@ -573,8 +564,7 @@ digraph flowFromTwoInplaceLambdas_kt { 204 -> {205}; 205 -> {206}; 206 -> {207}; - 207 -> {179} [color=red]; - 207 -> {178} [color=green]; + 207 -> {178}; subgraph cluster_42 { color=red @@ -600,7 +590,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 235 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 215 [label="Postponed exit from lambda"]; 216 [label="Postponed enter to lambda"]; subgraph cluster_46 { color=blue @@ -616,6 +605,7 @@ digraph flowFromTwoInplaceLambdas_kt { 242 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 217 [label="Postponed exit from lambda"]; + 215 [label="Postponed exit from lambda"]; 218 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 219 [label="Access variable R|/p|"]; 220 [label="Smart cast: R|/p|"]; @@ -635,12 +625,12 @@ digraph flowFromTwoInplaceLambdas_kt { 211 -> {212}; 212 -> {213}; 213 -> {214}; - 214 -> {229}; - 214 -> {215} [color=red]; + 214 -> {216 229}; + 214 -> {215} [style=dotted]; 214 -> {229} [style=dashed]; - 215 -> {216}; - 216 -> {236}; - 216 -> {217} [color=red]; + 215 -> {218}; + 216 -> {236 218}; + 216 -> {217} [style=dotted]; 216 -> {236} [style=dashed]; 217 -> {218}; 218 -> {219}; @@ -659,16 +649,14 @@ digraph flowFromTwoInplaceLambdas_kt { 232 -> {233}; 233 -> {234}; 234 -> {235}; - 235 -> {218} [color=red]; - 235 -> {215} [color=green]; + 235 -> {215}; 236 -> {237}; 237 -> {238}; 238 -> {239}; 239 -> {240}; 240 -> {241}; 241 -> {242}; - 242 -> {218} [color=red]; - 242 -> {217} [color=green]; + 242 -> {217}; subgraph cluster_48 { color=red @@ -692,7 +680,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 262 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 247 [label="Postponed exit from lambda"]; 248 [label="Postponed enter to lambda"]; subgraph cluster_52 { color=blue @@ -707,6 +694,7 @@ digraph flowFromTwoInplaceLambdas_kt { 268 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 249 [label="Postponed exit from lambda"]; + 247 [label="Postponed exit from lambda"]; 250 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; 251 [label="Access variable R|/x|"]; 252 [label="Access variable R|kotlin/String.length|"]; @@ -717,12 +705,12 @@ digraph flowFromTwoInplaceLambdas_kt { 243 -> {244}; 244 -> {245}; 245 -> {246}; - 246 -> {255}; - 246 -> {247} [color=red]; + 246 -> {248 255}; + 246 -> {247} [style=dotted]; 246 -> {255} [style=dashed]; - 247 -> {248}; - 248 -> {263}; - 248 -> {249} [color=red]; + 247 -> {250}; + 248 -> {263 250}; + 248 -> {249} [style=dotted]; 248 -> {263} [style=dashed]; 249 -> {250}; 250 -> {251}; @@ -736,15 +724,13 @@ digraph flowFromTwoInplaceLambdas_kt { 259 -> {260}; 260 -> {261}; 261 -> {262}; - 262 -> {250} [color=red]; - 262 -> {247} [color=green]; + 262 -> {247}; 263 -> {264}; 264 -> {265}; 265 -> {266}; 266 -> {267}; 267 -> {268}; - 268 -> {250} [color=red]; - 268 -> {249} [color=green]; + 268 -> {249}; subgraph cluster_54 { color=red @@ -768,7 +754,6 @@ digraph flowFromTwoInplaceLambdas_kt { } 300 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 275 [label="Postponed exit from lambda"]; 276 [label="Postponed enter to lambda"]; subgraph cluster_58 { color=blue @@ -783,6 +768,7 @@ digraph flowFromTwoInplaceLambdas_kt { 306 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 277 [label="Postponed exit from lambda"]; + 275 [label="Postponed exit from lambda"]; 278 [label="Function call: R|/run2|(...)" style="filled" fillcolor=yellow]; subgraph cluster_60 { color=blue @@ -816,12 +802,12 @@ digraph flowFromTwoInplaceLambdas_kt { 271 -> {272}; 272 -> {273}; 273 -> {274}; - 274 -> {295}; - 274 -> {275} [color=red]; + 274 -> {276 295}; + 274 -> {275} [style=dotted]; 274 -> {295} [style=dashed]; - 275 -> {276}; - 276 -> {301}; - 276 -> {277} [color=red]; + 275 -> {278}; + 276 -> {301 278}; + 276 -> {277} [style=dotted]; 276 -> {301} [style=dashed]; 277 -> {278}; 278 -> {279}; @@ -845,15 +831,13 @@ digraph flowFromTwoInplaceLambdas_kt { 297 -> {298}; 298 -> {299}; 299 -> {300}; - 300 -> {278} [color=red]; - 300 -> {275} [color=green]; + 300 -> {275}; 301 -> {302}; 302 -> {303}; 303 -> {306}; 303 -> {304} [style=dotted]; 304 -> {305} [style=dotted]; 305 -> {306} [style=dotted]; - 306 -> {278} [color=red]; - 306 -> {277} [color=green]; + 306 -> {277}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.kt index d89dea029fc..853f8ec015d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.kt +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromTwoInplaceLambdas.kt @@ -75,7 +75,7 @@ fun test5(x: Any?, q: String?) { fun test6() { val x: String // not necessarily initialized in second lambda (may call in any order) - run2({ x = ""; x.length }, { x.length }) + run2({ x = ""; x.length }, { x.length }) x.length // initialized here } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/initBlockAndInPlaceLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/initBlockAndInPlaceLambda.dot index ff965c0f905..b7e828207ac 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/initBlockAndInPlaceLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/initBlockAndInPlaceLambda.dot @@ -62,8 +62,8 @@ digraph initBlockAndInPlaceLambda_kt { 9 -> {10}; 10 -> {11 15}; 11 -> {12}; - 12 -> {19}; - 12 -> {13} [color=red]; + 12 -> {19 14}; + 12 -> {13} [style=dotted]; 12 -> {19} [style=dashed]; 13 -> {14}; 14 -> {15}; @@ -77,8 +77,7 @@ digraph initBlockAndInPlaceLambda_kt { 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {14} [color=red]; - 25 -> {13} [color=green]; + 25 -> {13}; subgraph cluster_7 { color=red diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot index 88482cb8f02..d1bd97691cb 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot @@ -99,10 +99,11 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 21 -> {29}; 22 -> {23}; 23 -> {24}; - 24 -> {33}; - 24 -> {25} [color=red]; + 24 -> {33 26}; + 24 -> {25} [style=dotted]; 24 -> {33} [style=dashed]; - 25 -> {26}; + 25 -> {29} [color=red]; + 25 -> {26} [color=green]; 26 -> {27}; 27 -> {28}; 28 -> {29}; @@ -113,8 +114,7 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 34 -> {35}; 35 -> {36}; 36 -> {37}; - 37 -> {29} [color=red]; - 37 -> {25} [color=green]; + 37 -> {25}; subgraph cluster_11 { color=red @@ -173,10 +173,11 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 40 -> {41 48}; 41 -> {42}; 42 -> {43}; - 43 -> {58}; - 43 -> {44} [color=red]; + 43 -> {58 45}; + 43 -> {44} [style=dotted]; 43 -> {58} [style=dashed]; - 44 -> {45}; + 44 -> {54} [color=red]; + 44 -> {45} [color=green]; 45 -> {46}; 46 -> {47}; 47 -> {54 48}; @@ -194,8 +195,7 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 59 -> {60}; 60 -> {61}; 61 -> {62}; - 62 -> {54} [color=red]; - 62 -> {44} [color=green]; + 62 -> {44}; subgraph cluster_20 { color=red @@ -225,10 +225,11 @@ digraph inplaceLambdaInControlFlowExpressions_kt { } 63 -> {64}; 64 -> {65}; - 65 -> {72}; - 65 -> {66} [color=red]; + 65 -> {72 67}; + 65 -> {66} [style=dotted]; 65 -> {72} [style=dashed]; - 66 -> {67}; + 66 -> {68} [color=red]; + 66 -> {67} [color=green]; 67 -> {68}; 68 -> {69}; 69 -> {70}; @@ -237,7 +238,6 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 73 -> {74}; 74 -> {75}; 75 -> {76}; - 76 -> {68} [color=red]; - 76 -> {66} [color=green]; + 76 -> {66}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot index b94ca081f1d..c5c4f529a12 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot @@ -407,7 +407,7 @@ digraph jumps_kt { } 130 -> {131}; 131 -> {132}; - 132 -> {133 137}; + 132 -> {133 137 134}; 132 -> {137} [style=dashed]; 133 -> {134}; 133 -> {132} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot index 8ba6710aa54..9b61ae189c9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot @@ -26,34 +26,34 @@ digraph lambdaAsReturnOfLambda_kt { } 13 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 3 [label="Postponed exit from lambda"]; - 4 [label="Jump: ^@run lambda@fun (foo: R|kotlin/String|): R|kotlin/Unit| { + 3 [label="Jump: ^@run lambda@fun (foo: R|kotlin/String|): R|kotlin/Unit| { R|/bar|(R|/foo|) } "]; - 5 [label="Stub" style="filled" fillcolor=gray]; - 6 [label="Exit block" style="filled" fillcolor=gray]; + 4 [label="Stub" style="filled" fillcolor=gray]; + 5 [label="Exit block" style="filled" fillcolor=gray]; } - 7 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 6 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } + 7 [label="Postponed exit from lambda"]; 16 [label="Postponed exit from lambda"]; 17 [label="Function call: R|/run| kotlin/Unit|>(...)" style="filled" fillcolor=yellow]; 18 [label="Exit property" style="filled" fillcolor=red]; } 14 -> {15}; - 15 -> {16 0}; + 15 -> {16 0 17}; 15 -> {0} [style=dashed]; 16 -> {17}; 17 -> {18}; 0 -> {1}; 1 -> {2}; - 2 -> {3 8}; + 2 -> {7 3 8}; 2 -> {8} [style=dashed]; - 3 -> {4}; - 4 -> {7}; + 3 -> {6}; + 3 -> {4} [style=dotted]; 4 -> {5} [style=dotted]; 5 -> {6} [style=dotted]; - 6 -> {7} [style=dotted]; + 7 -> {17}; 8 -> {9}; 9 -> {10}; 10 -> {11}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot index 2f64d30f128..98d6781cc75 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot @@ -97,9 +97,10 @@ digraph lambdaReturningObject_kt { } 21 -> {22}; 22 -> {23}; - 23 -> {24 29}; + 23 -> {24 29 25}; 23 -> {29} [style=dashed]; - 24 -> {25}; + 24 -> {26} [color=red]; + 24 -> {25} [color=green]; 25 -> {26}; 26 -> {27}; 27 -> {28}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdas.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdas.dot index e7ec200ff8d..f93b73d60f7 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdas.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdas.dot @@ -75,7 +75,7 @@ digraph lambdas_kt { 12 -> {20}; 13 -> {14}; 14 -> {15}; - 15 -> {16 23}; + 15 -> {16 23 17}; 15 -> {23} [style=dashed]; 16 -> {17}; 16 -> {15} [color=green style=dashed]; @@ -219,7 +219,7 @@ digraph lambdas_kt { } 63 -> {64}; 64 -> {65}; - 65 -> {66 72}; + 65 -> {66 72 67}; 65 -> {72} [style=dashed]; 66 -> {67}; 66 -> {65} [color=green style=dashed]; @@ -270,7 +270,7 @@ digraph lambdas_kt { } 79 -> {80}; 80 -> {81}; - 81 -> {82 88}; + 81 -> {82 88 83}; 81 -> {88} [style=dashed]; 82 -> {83}; 82 -> {81} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot index 3fe9cc72510..487c69fb6b9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/localClassesWithImplicit.dot @@ -193,7 +193,7 @@ digraph localClassesWithImplicit_kt { } 36 -> {37}; 37 -> {38}; - 38 -> {39 45}; + 38 -> {39 45 40}; 38 -> {45} [style=dashed]; 39 -> {40}; 39 -> {38} [color=green style=dashed]; @@ -269,7 +269,7 @@ digraph localClassesWithImplicit_kt { } 73 -> {74}; 74 -> {75}; - 75 -> {76 82}; + 75 -> {76 82 77}; 75 -> {82} [style=dashed]; 76 -> {77}; 76 -> {75} [color=green style=dashed]; @@ -398,7 +398,7 @@ digraph localClassesWithImplicit_kt { } 102 -> {103}; 103 -> {104}; - 104 -> {105 111}; + 104 -> {105 111 106}; 104 -> {111} [style=dashed]; 105 -> {106}; 105 -> {104} [color=green style=dashed]; @@ -474,7 +474,7 @@ digraph localClassesWithImplicit_kt { } 139 -> {140}; 140 -> {141}; - 141 -> {142 148}; + 141 -> {142 148 143}; 141 -> {148} [style=dashed]; 142 -> {143}; 142 -> {141} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot index 0551097302d..775771a6baf 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot @@ -42,11 +42,11 @@ digraph postponedLambdaInConstructor_kt { } 22 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 15 [label="Postponed exit from lambda"]; - 16 [label="Exit block"]; + 15 [label="Exit block"]; } - 17 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 16 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } + 17 [label="Postponed exit from lambda"]; 8 [label="Postponed exit from lambda"]; 9 [label="Function call: R|/s|.R|kotlin/let| kotlin/String|>(...)" style="filled" fillcolor=yellow]; 10 [label="Delegated constructor call: super(...)" style="filled" fillcolor=yellow]; @@ -54,20 +54,21 @@ digraph postponedLambdaInConstructor_kt { } 5 -> {6}; 6 -> {7}; - 7 -> {12}; - 7 -> {8} [color=red]; + 7 -> {12 9}; + 7 -> {8} [style=dotted]; 7 -> {12} [style=dashed]; - 8 -> {9}; + 8 -> {10} [color=red]; + 8 -> {9} [color=green]; 9 -> {10}; 10 -> {11}; 12 -> {13}; 13 -> {14}; - 14 -> {15 18}; + 14 -> {17 15 18}; 14 -> {18} [style=dashed]; 15 -> {16}; - 16 -> {17}; + 16 -> {8}; 17 -> {10} [color=red]; - 17 -> {8} [color=green]; + 17 -> {9} [color=green]; 18 -> {19}; 19 -> {20}; 20 -> {21}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdas.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdas.dot index eee27324896..03fda8ba06c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdas.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdas.dot @@ -47,7 +47,7 @@ digraph postponedLambdas_kt { 5 -> {6}; 6 -> {7}; 7 -> {8}; - 8 -> {9 13}; + 8 -> {9 13 10}; 8 -> {13} [style=dashed]; 9 -> {10}; 9 -> {8} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot index 45e0d506ae2..defc4279f8d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot @@ -227,7 +227,7 @@ digraph propertiesAndInitBlocks_kt { 79 [label="Exit property" style="filled" fillcolor=red]; } 75 -> {76}; - 76 -> {77 24}; + 76 -> {77 24 78}; 76 -> {24} [style=dashed]; 77 -> {78}; 77 -> {76} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot index d63fbd590a5..0669c6f43ca 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot @@ -91,8 +91,8 @@ digraph returnValuesFromLambda_kt { } 12 -> {13}; 13 -> {14}; - 14 -> {20}; - 14 -> {15} [color=red]; + 14 -> {20 16}; + 14 -> {15} [style=dotted]; 14 -> {20} [style=dashed]; 15 -> {16}; 16 -> {17}; @@ -116,8 +116,7 @@ digraph returnValuesFromLambda_kt { 34 -> {35}; 35 -> {36}; 36 -> {37}; - 37 -> {16} [color=red]; - 37 -> {15} [color=green]; + 37 -> {15}; subgraph cluster_12 { color=red @@ -148,8 +147,8 @@ digraph returnValuesFromLambda_kt { } 38 -> {39}; 39 -> {40}; - 40 -> {46}; - 40 -> {41} [color=red]; + 40 -> {46 42}; + 40 -> {41} [style=dotted]; 40 -> {46} [style=dashed]; 41 -> {42}; 42 -> {43}; @@ -162,8 +161,7 @@ digraph returnValuesFromLambda_kt { 49 -> {50} [style=dotted]; 50 -> {51} [style=dotted]; 51 -> {52} [style=dotted]; - 52 -> {42} [color=red]; - 52 -> {41} [color=green]; + 52 -> {41}; subgraph cluster_16 { color=red @@ -195,7 +193,7 @@ digraph returnValuesFromLambda_kt { 53 -> {54}; 54 -> {55}; 55 -> {62}; - 55 -> {56} [color=red]; + 55 -> {56 57} [style=dotted]; 55 -> {62} [style=dashed]; 56 -> {57} [style=dotted]; 57 -> {58} [style=dotted]; @@ -209,6 +207,6 @@ digraph returnValuesFromLambda_kt { 64 -> {65} [style=dotted]; 65 -> {66} [style=dotted]; 66 -> {67} [style=dotted]; - 67 -> {56 57} [style=dotted]; + 67 -> {56} [style=dotted]; } diff --git a/compiler/fir/analysis-tests/testData/resolve/classCallInLambda.dot b/compiler/fir/analysis-tests/testData/resolve/classCallInLambda.dot index ebf405213dd..7752126fdd5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/classCallInLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/classCallInLambda.dot @@ -37,8 +37,8 @@ digraph classCallInLambda_kt { 0 -> {1}; 1 -> {2}; 2 -> {3}; - 3 -> {10}; - 3 -> {4} [color=red]; + 3 -> {10 5}; + 3 -> {4} [style=dotted]; 3 -> {10} [style=dashed]; 4 -> {5}; 5 -> {6}; @@ -51,7 +51,6 @@ digraph classCallInLambda_kt { 12 -> {13}; 13 -> {14}; 14 -> {15}; - 15 -> {5} [color=red]; - 15 -> {4} [color=green]; + 15 -> {4}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot index 2b4d7508688..6ffb5ee23ad 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot @@ -502,7 +502,7 @@ digraph returns_kt { 172 -> {173}; 173 -> {174}; 174 -> {175}; - 175 -> {176 180}; + 175 -> {176 180 177}; 175 -> {180} [style=dashed]; 176 -> {177}; 177 -> {178}; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.dot index abbc6be4d9b..0c14446d70b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.dot @@ -127,10 +127,11 @@ digraph incorrectSmartcastToNothing_kt { 32 -> {33}; 33 -> {34 38}; 34 -> {35}; - 35 -> {46}; - 35 -> {36} [color=red]; + 35 -> {46 37}; + 35 -> {36} [style=dotted]; 35 -> {46} [style=dashed]; - 36 -> {37}; + 36 -> {41} [color=red]; + 36 -> {37} [color=green]; 37 -> {38}; 38 -> {41 39}; 39 -> {40}; @@ -145,7 +146,6 @@ digraph incorrectSmartcastToNothing_kt { 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {41} [color=red]; - 52 -> {36} [color=green]; + 52 -> {36}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/inPlaceLambdas.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/inPlaceLambdas.dot index 553ccbb6c37..eb0e2a6df12 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/inPlaceLambdas.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/inPlaceLambdas.dot @@ -87,8 +87,8 @@ digraph inPlaceLambdas_kt { 15 -> {23}; 16 -> {17}; 17 -> {18}; - 18 -> {26}; - 18 -> {19} [color=red]; + 18 -> {26 20}; + 18 -> {19} [style=dotted]; 18 -> {26} [style=dashed]; 19 -> {20}; 20 -> {21}; @@ -102,8 +102,7 @@ digraph inPlaceLambdas_kt { 29 -> {30}; 30 -> {31}; 31 -> {32}; - 32 -> {20} [color=red]; - 32 -> {19} [color=green]; + 32 -> {19}; subgraph cluster_11 { color=red @@ -135,8 +134,8 @@ digraph inPlaceLambdas_kt { } 33 -> {34}; 34 -> {35}; - 35 -> {43}; - 35 -> {36} [color=red]; + 35 -> {43 37}; + 35 -> {36} [style=dotted]; 35 -> {43} [style=dashed]; 36 -> {37}; 37 -> {38}; @@ -149,8 +148,7 @@ digraph inPlaceLambdas_kt { 45 -> {46}; 46 -> {47}; 47 -> {48}; - 48 -> {37} [color=red]; - 48 -> {36} [color=green]; + 48 -> {36}; subgraph cluster_15 { color=red @@ -214,8 +212,8 @@ digraph inPlaceLambdas_kt { 56 -> {67}; 57 -> {58}; 58 -> {59}; - 59 -> {70}; - 59 -> {60} [color=red]; + 59 -> {70 61}; + 59 -> {60} [style=dotted]; 59 -> {70} [style=dashed]; 60 -> {61}; 61 -> {62}; @@ -235,7 +233,6 @@ digraph inPlaceLambdas_kt { 76 -> {77}; 77 -> {78}; 78 -> {79}; - 79 -> {61} [color=red]; - 79 -> {60} [color=green]; + 79 -> {60}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.dot index 9a3d1bd497b..708624de899 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.dot @@ -216,10 +216,11 @@ digraph lambdaInWhenBranch_kt { 45 -> {46}; 46 -> {47}; 47 -> {48}; - 48 -> {82}; - 48 -> {49} [color=red]; + 48 -> {82 50}; + 48 -> {49} [style=dotted]; 48 -> {82} [style=dashed]; - 49 -> {50}; + 49 -> {53} [color=red]; + 49 -> {50} [color=green]; 50 -> {51}; 51 -> {52}; 52 -> {53}; @@ -255,7 +256,6 @@ digraph lambdaInWhenBranch_kt { 83 -> {84}; 84 -> {85}; 85 -> {86}; - 86 -> {53} [color=red]; - 86 -> {49} [color=green]; + 86 -> {49}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/receivers/implicitReceivers.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/receivers/implicitReceivers.dot index 7d0f4147e01..ebf1a48d10e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/receivers/implicitReceivers.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/receivers/implicitReceivers.dot @@ -304,8 +304,8 @@ digraph implicitReceivers_kt { 82 -> {83}; 83 -> {84}; 84 -> {85}; - 85 -> {90}; - 85 -> {86} [color=red]; + 85 -> {90 87}; + 85 -> {86} [style=dotted]; 85 -> {90} [style=dashed]; 86 -> {87}; 87 -> {88}; @@ -313,19 +313,19 @@ digraph implicitReceivers_kt { 90 -> {91}; 91 -> {92}; 92 -> {93}; - 93 -> {98}; - 93 -> {94} [color=red]; + 93 -> {98 95}; + 93 -> {94} [style=dotted]; 93 -> {98} [style=dashed]; - 94 -> {95}; + 94 -> {87} [color=red]; + 94 -> {95} [color=green]; 95 -> {96}; 96 -> {97}; - 97 -> {87} [color=red]; - 97 -> {86} [color=green]; + 97 -> {86}; 98 -> {99}; 99 -> {100}; 100 -> {101}; - 101 -> {110}; - 101 -> {102} [color=red]; + 101 -> {110 103}; + 101 -> {102} [style=dotted]; 101 -> {110} [style=dashed]; 102 -> {103}; 103 -> {104}; @@ -334,7 +334,7 @@ digraph implicitReceivers_kt { 106 -> {107}; 107 -> {108}; 108 -> {109}; - 109 -> {94} [color=green]; + 109 -> {94}; 110 -> {111}; 111 -> {112}; 112 -> {113}; @@ -344,8 +344,7 @@ digraph implicitReceivers_kt { 116 -> {117}; 117 -> {118}; 118 -> {119}; - 119 -> {103} [color=red]; - 119 -> {102} [color=green]; + 119 -> {102}; subgraph cluster_32 { color=red diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot index 081933606b0..6296d3dbd9b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot @@ -187,7 +187,7 @@ digraph safeCalls_kt { 56 -> {57}; 57 -> {63 58}; 58 -> {59}; - 59 -> {60 69}; + 59 -> {60 69 61}; 59 -> {69} [style=dashed]; 60 -> {61}; 61 -> {64}; @@ -292,7 +292,7 @@ digraph safeCalls_kt { 95 -> {96 106}; 96 -> {97}; 97 -> {112}; - 97 -> {98} [color=red]; + 97 -> {98 99} [style=dotted]; 97 -> {112} [style=dashed]; 98 -> {99} [style=dotted]; 99 -> {100} [style=dotted]; @@ -314,6 +314,6 @@ digraph safeCalls_kt { 114 -> {115} [style=dotted]; 115 -> {116} [style=dotted]; 116 -> {117} [style=dotted]; - 117 -> {98 99} [style=dotted]; + 117 -> {98} [style=dotted]; } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot index 155414e7984..a51a0175ada 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot @@ -295,8 +295,8 @@ digraph smartcastToNothing_kt { 91 -> {92}; 92 -> {93 97}; 93 -> {94}; - 94 -> {100}; - 94 -> {95} [color=red]; + 94 -> {100 96}; + 94 -> {95} [style=dotted]; 94 -> {100} [style=dashed]; 95 -> {96}; 96 -> {97}; @@ -307,8 +307,7 @@ digraph smartcastToNothing_kt { 102 -> {103}; 103 -> {104}; 104 -> {105}; - 105 -> {96} [color=red]; - 105 -> {95} [color=green]; + 105 -> {95}; subgraph cluster_26 { color=red diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/complexPostponedCfg.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/complexPostponedCfg.dot index 5b02de8a1f6..74ef7d02d10 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/complexPostponedCfg.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/complexPostponedCfg.dot @@ -88,8 +88,8 @@ digraph complexPostponedCfg_kt { 6 -> {7}; 7 -> {8}; 8 -> {9}; - 9 -> {18}; - 9 -> {10} [color=red]; + 9 -> {18 11}; + 9 -> {10} [style=dotted]; 9 -> {18} [style=dashed]; 10 -> {11}; 11 -> {12}; @@ -101,14 +101,14 @@ digraph complexPostponedCfg_kt { 16 -> {17} [style=dotted]; 18 -> {19}; 19 -> {20}; - 20 -> {25}; - 20 -> {21} [color=red]; + 20 -> {22 25}; + 20 -> {21} [style=dotted]; 20 -> {25} [style=dashed]; - 21 -> {22}; + 21 -> {11} [color=red]; + 21 -> {22} [color=green]; 22 -> {23}; 23 -> {24}; - 24 -> {11} [color=red]; - 24 -> {10} [color=green]; + 24 -> {10}; 25 -> {26}; 26 -> {27}; 27 -> {28}; @@ -116,14 +116,13 @@ digraph complexPostponedCfg_kt { 29 -> {30}; 30 -> {31}; 31 -> {32}; - 32 -> {37}; - 32 -> {33} [color=red]; + 32 -> {37 34}; + 32 -> {33} [style=dotted]; 32 -> {37} [style=dashed]; 33 -> {34}; 34 -> {35}; 35 -> {36}; - 36 -> {11} [color=red]; - 36 -> {21} [color=green]; + 36 -> {21}; 37 -> {38}; 38 -> {39}; 39 -> {40}; @@ -132,7 +131,6 @@ digraph complexPostponedCfg_kt { 42 -> {43}; 43 -> {44}; 44 -> {45}; - 45 -> {34} [color=red]; - 45 -> {33} [color=green]; + 45 -> {33}; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot index 74308a9a30a..de6f2b3271b 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot @@ -34,8 +34,8 @@ digraph callsInPlace_kt { 0 -> {1}; 1 -> {2}; 2 -> {3}; - 3 -> {10}; - 3 -> {4} [color=red]; + 3 -> {10 5}; + 3 -> {4} [style=dotted]; 3 -> {10} [style=dashed]; 4 -> {5}; 5 -> {6}; @@ -47,8 +47,7 @@ digraph callsInPlace_kt { 12 -> {13}; 13 -> {14}; 14 -> {15}; - 15 -> {5} [color=red]; - 15 -> {4} [color=green]; + 15 -> {4}; subgraph cluster_4 { color=red @@ -78,7 +77,7 @@ digraph callsInPlace_kt { 16 -> {17}; 17 -> {18}; 18 -> {19}; - 19 -> {20 24}; + 19 -> {20 24 21}; 19 -> {24} [style=dashed]; 20 -> {21}; 20 -> {19} [color=green style=dashed]; @@ -108,8 +107,8 @@ digraph callsInPlace_kt { } 41 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 32 [label="Postponed exit from lambda"]; 33 [label="Const: Int(10)"]; + 32 [label="Postponed exit from lambda"]; 34 [label="Function call: R|kotlin/repeat|(...)" style="filled" fillcolor=yellow]; 35 [label="Exit block"]; } @@ -117,9 +116,9 @@ digraph callsInPlace_kt { } 29 -> {30}; 30 -> {31}; - 31 -> {32 37}; + 31 -> {32 33 37}; 31 -> {37} [style=dashed]; - 32 -> {33}; + 32 -> {34}; 32 -> {31} [color=green style=dashed]; 33 -> {34}; 34 -> {35}; @@ -162,8 +161,8 @@ digraph callsInPlace_kt { 42 -> {43}; 43 -> {44}; 44 -> {45}; - 45 -> {50}; - 45 -> {46} [color=red]; + 45 -> {50 47}; + 45 -> {46} [style=dotted]; 45 -> {50} [style=dashed]; 46 -> {47}; 47 -> {48}; @@ -176,8 +175,7 @@ digraph callsInPlace_kt { 55 -> {56}; 56 -> {57}; 57 -> {58}; - 58 -> {47} [color=red]; - 58 -> {46} [color=green]; + 58 -> {46}; subgraph cluster_16 { color=red @@ -211,8 +209,8 @@ digraph callsInPlace_kt { 59 -> {60}; 60 -> {61}; 61 -> {62}; - 62 -> {67}; - 62 -> {63} [color=red]; + 62 -> {67 64}; + 62 -> {63} [style=dotted]; 62 -> {67} [style=dashed]; 63 -> {64}; 64 -> {65}; @@ -225,8 +223,7 @@ digraph callsInPlace_kt { 72 -> {73}; 73 -> {74}; 74 -> {75}; - 75 -> {64} [color=red]; - 75 -> {63} [color=green]; + 75 -> {63}; subgraph cluster_20 { color=red @@ -264,7 +261,6 @@ digraph callsInPlace_kt { } 100 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 85 [label="Postponed exit from lambda"]; 86 [label="Postponed enter to lambda"]; subgraph cluster_26 { color=blue @@ -278,6 +274,7 @@ digraph callsInPlace_kt { 95 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 87 [label="Postponed exit from lambda"]; + 85 [label="Postponed exit from lambda"]; 88 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 89 [label="Exit block"]; } @@ -285,11 +282,11 @@ digraph callsInPlace_kt { } 82 -> {83}; 83 -> {84}; - 84 -> {85 96}; + 84 -> {85 86 96}; 84 -> {96} [style=dashed]; - 85 -> {86}; + 85 -> {88}; 85 -> {84} [color=green style=dashed]; - 86 -> {87 91}; + 86 -> {87 91 88}; 86 -> {91} [style=dashed]; 87 -> {88}; 87 -> {86} [color=green style=dashed]; @@ -324,7 +321,6 @@ digraph callsInPlace_kt { } 114 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } - 104 [label="Postponed exit from lambda"]; 105 [label="Postponed enter to lambda"]; subgraph cluster_32 { color=blue @@ -338,6 +334,7 @@ digraph callsInPlace_kt { 119 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; } 106 [label="Postponed exit from lambda"]; + 104 [label="Postponed exit from lambda"]; 107 [label="Function call: R|/myRun|(...)" style="filled" fillcolor=yellow]; 108 [label="Exit block"]; } @@ -345,11 +342,11 @@ digraph callsInPlace_kt { } 101 -> {102}; 102 -> {103}; - 103 -> {104 110}; + 103 -> {104 105 110}; 103 -> {110} [style=dashed]; - 104 -> {105}; + 104 -> {107}; 104 -> {103} [color=green style=dashed]; - 105 -> {106 115}; + 105 -> {106 115 107}; 105 -> {115} [style=dashed]; 106 -> {107}; 106 -> {105} [color=green style=dashed]; @@ -408,7 +405,7 @@ digraph callsInPlace_kt { } 125 -> {126}; 126 -> {127}; - 127 -> {128 132}; + 127 -> {128 132 129}; 127 -> {132} [style=dashed]; 128 -> {129}; 129 -> {130}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atLeastOnce.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atLeastOnce.dot index d9ec5020938..73af71eea5c 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atLeastOnce.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atLeastOnce.dot @@ -66,8 +66,8 @@ digraph atLeastOnce_kt { 10 -> {11}; 11 -> {12}; 12 -> {13}; - 13 -> {20}; - 13 -> {14} [color=red]; + 13 -> {20 15}; + 13 -> {14} [style=dotted]; 13 -> {20} [style=dashed]; 14 -> {15}; 14 -> {13} [color=green style=dashed]; @@ -80,8 +80,7 @@ digraph atLeastOnce_kt { 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {15} [color=red]; - 25 -> {14} [color=green]; + 25 -> {14}; subgraph cluster_8 { color=red @@ -114,8 +113,8 @@ digraph atLeastOnce_kt { 26 -> {27}; 27 -> {28}; 28 -> {29}; - 29 -> {36}; - 29 -> {30} [color=red]; + 29 -> {36 31}; + 29 -> {30} [style=dotted]; 29 -> {36} [style=dashed]; 30 -> {31}; 30 -> {29} [color=green style=dashed]; @@ -128,7 +127,6 @@ digraph atLeastOnce_kt { 38 -> {39}; 39 -> {40}; 40 -> {41}; - 41 -> {31} [color=red]; - 41 -> {30} [color=green]; + 41 -> {30}; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atMostOnce.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atMostOnce.dot index 5d1188db3d5..80da72f5bb2 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atMostOnce.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/atMostOnce.dot @@ -66,7 +66,7 @@ digraph atMostOnce_kt { 10 -> {11}; 11 -> {12}; 12 -> {13}; - 13 -> {14 20}; + 13 -> {14 20 15}; 13 -> {20} [style=dashed]; 14 -> {15}; 15 -> {16}; @@ -111,7 +111,7 @@ digraph atMostOnce_kt { 26 -> {27}; 27 -> {28}; 28 -> {29}; - 29 -> {30 36}; + 29 -> {30 36 31}; 29 -> {36} [style=dashed]; 30 -> {31}; 31 -> {32}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/exactlyOnce.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/exactlyOnce.dot index 38776f759b4..914719beb02 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/exactlyOnce.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/exactlyOnce.dot @@ -66,8 +66,8 @@ digraph exactlyOnce_kt { 10 -> {11}; 11 -> {12}; 12 -> {13}; - 13 -> {20}; - 13 -> {14} [color=red]; + 13 -> {20 15}; + 13 -> {14} [style=dotted]; 13 -> {20} [style=dashed]; 14 -> {15}; 15 -> {16}; @@ -79,8 +79,7 @@ digraph exactlyOnce_kt { 22 -> {23}; 23 -> {24}; 24 -> {25}; - 25 -> {15} [color=red]; - 25 -> {14} [color=green]; + 25 -> {14}; subgraph cluster_8 { color=red @@ -113,8 +112,8 @@ digraph exactlyOnce_kt { 26 -> {27}; 27 -> {28}; 28 -> {29}; - 29 -> {36}; - 29 -> {30} [color=red]; + 29 -> {36 31}; + 29 -> {30} [style=dotted]; 29 -> {36} [style=dashed]; 30 -> {31}; 31 -> {32}; @@ -126,7 +125,6 @@ digraph exactlyOnce_kt { 38 -> {39}; 39 -> {40}; 40 -> {41}; - 41 -> {31} [color=red]; - 41 -> {30} [color=green]; + 41 -> {30}; } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/inPlaceLambda.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/inPlaceLambda.dot index bdb8ede85c5..0791b29eebf 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/inPlaceLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/inPlaceLambda.dot @@ -76,7 +76,7 @@ digraph inPlaceLambda_kt { 15 -> {16}; 16 -> {17}; 17 -> {18}; - 18 -> {19 23}; + 18 -> {19 23 20}; 18 -> {23} [style=dashed]; 19 -> {20}; 20 -> {21}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/unknown.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/unknown.dot index 6a61fcc894e..c9640539e94 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/unknown.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromSource/good/callsInPlace/unknown.dot @@ -66,7 +66,7 @@ digraph unknown_kt { 10 -> {11}; 11 -> {12}; 12 -> {13}; - 13 -> {14 20}; + 13 -> {14 20 15}; 13 -> {20} [style=dashed]; 14 -> {15}; 14 -> {13} [color=green style=dashed]; @@ -112,7 +112,7 @@ digraph unknown_kt { 26 -> {27}; 27 -> {28}; 28 -> {29}; - 29 -> {30 36}; + 29 -> {30 36 31}; 29 -> {36} [style=dashed]; 30 -> {31}; 30 -> {29} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot index 4bd82969b04..6d706056e96 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot @@ -229,9 +229,10 @@ digraph delegateWithAnonymousObject_kt { 78 [label="Exit property" style="filled" fillcolor=red]; } 71 -> {72}; - 72 -> {73}; + 72 -> {73 74}; 72 -> {26} [style=dashed]; - 73 -> {74}; + 73 -> {77} [color=red]; + 73 -> {74} [color=green]; 74 -> {75}; 75 -> {76}; 76 -> {77}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot index 0bd920692ae..2309a07a934 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot @@ -40,7 +40,7 @@ digraph plusAssignWithLambdaInRhs_kt { 4 -> {5} [style=dotted]; 5 -> {6} [style=dotted]; 6 -> {7} [style=dotted]; - 7 -> {8 12} [style=dotted]; + 7 -> {8 12 9} [style=dotted]; 7 -> {12} [style=dashed]; 8 -> {9} [style=dotted]; 8 -> {7} [color=green style=dotted]; @@ -135,7 +135,7 @@ digraph plusAssignWithLambdaInRhs_kt { 27 -> {28}; 28 -> {29}; 29 -> {30}; - 30 -> {31 37}; + 30 -> {31 37 32}; 30 -> {37} [style=dashed]; 31 -> {32}; 32 -> {33}; @@ -146,7 +146,7 @@ digraph plusAssignWithLambdaInRhs_kt { 37 -> {38}; 38 -> {39}; 39 -> {40}; - 40 -> {41 45}; + 40 -> {41 45 42}; 40 -> {45} [style=dashed]; 41 -> {42}; 41 -> {40} [color=green style=dashed]; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot index 1d489576feb..a2bd41a32d6 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot @@ -105,7 +105,7 @@ finally { 14 -> {15}; 15 -> {16}; 16 -> {17}; - 17 -> {18 31}; + 17 -> {18 31 19}; 17 -> {31} [style=dashed]; 18 -> {19}; 18 -> {17} [color=green style=dashed]; @@ -195,7 +195,7 @@ finally { 39 -> {40}; 40 -> {41}; 41 -> {42}; - 42 -> {43 56}; + 42 -> {43 56 44}; 42 -> {56} [style=dashed]; 43 -> {44}; 44 -> {45}; diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/LocalPropertyAndCapturedWriteCollector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/LocalPropertyAndCapturedWriteCollector.kt index ebf0e39df5d..d7d955b6f76 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/LocalPropertyAndCapturedWriteCollector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/util/LocalPropertyAndCapturedWriteCollector.kt @@ -40,7 +40,7 @@ class LocalPropertyAndCapturedWriteCollector private constructor() : ControlFlow } override fun visitPostponedLambdaEnterNode(node: PostponedLambdaEnterNode) { - lambdaOrLocalFunctionStack.add(node.fir) + lambdaOrLocalFunctionStack.add(node.fir.anonymousFunction) } override fun visitLocalFunctionDeclarationNode(node: LocalFunctionDeclarationNode, data: Nothing?) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index ade4fd057c8..dcf61365ad5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -222,22 +222,15 @@ abstract class FirDataFlowAnalyzer( exitCapturingStatement(anonymousFunction) } functionExitNode.mergeIncomingFlow() - if (postponedLambdaExitNode != null) { - // Data flow changed, need to recompute. TODO: this violates the "flow computed only once" principle. - postponedLambdaExitNode.mergeIncomingFlow() - } else { - // The current node should be `postponedLambdaExitNode` but we don't get a reference to it. - resetReceivers() - } + postponedLambdaExitNode?.mergeIncomingFlow() + resetReceivers() // roll back to state before function return FirControlFlowGraphReferenceImpl(graph) } fun visitPostponedAnonymousFunction(anonymousFunctionExpression: FirAnonymousFunctionExpression) { val anonymousFunction = anonymousFunctionExpression.anonymousFunction getOrCreateLocalVariableAssignmentAnalyzer(anonymousFunction)?.visitPostponedAnonymousFunction(anonymousFunction) - val (enterNode, exitNode) = graphBuilder.visitPostponedAnonymousFunction(anonymousFunctionExpression) - enterNode.mergeIncomingFlow() - exitNode.mergeIncomingFlow() + graphBuilder.visitPostponedAnonymousFunction(anonymousFunctionExpression).mergeIncomingFlow() } fun exitAnonymousFunctionExpression(anonymousFunctionExpression: FirAnonymousFunctionExpression) { @@ -626,11 +619,9 @@ abstract class FirDataFlowAnalyzer( } fun exitWhenExpression(whenExpression: FirWhenExpression, callCompleted: Boolean) { - val (whenExitNode, syntheticElseNode, mergePostponedLambdaExitsNode) = - graphBuilder.exitWhenExpression(whenExpression, callCompleted) + val (whenExitNode, syntheticElseNode) = graphBuilder.exitWhenExpression(whenExpression, callCompleted) syntheticElseNode?.mergeWhenBranchEntryFlow() whenExitNode.mergeIncomingFlow() - mergePostponedLambdaExitsNode?.mergeIncomingFlow() } fun exitWhenSubjectExpression(expression: FirWhenSubjectExpression) { @@ -771,9 +762,7 @@ abstract class FirDataFlowAnalyzer( } fun exitTryExpression(callCompleted: Boolean) { - val (tryExpressionExitNode, mergePostponedLambdaExitsNode) = graphBuilder.exitTryExpression(callCompleted) - tryExpressionExitNode.mergeIncomingFlow() - mergePostponedLambdaExitsNode?.mergeIncomingFlow() + graphBuilder.exitTryExpression(callCompleted).mergeIncomingFlow() } // ----------------------------------- Resolvable call ----------------------------------- @@ -799,7 +788,7 @@ abstract class FirDataFlowAnalyzer( } fun exitSafeCall(safeCall: FirSafeCallExpression) { - val (node, mergePostponedLambdaExitsNode) = graphBuilder.exitSafeCall() + val node = graphBuilder.exitSafeCall() node.mergeIncomingFlow { flow -> // If there is only 1 previous node, then this is LHS of `a?.b ?: c`; then the null-case // edge from `a` goes directly to `c` and this node's flow already assumes `b` executed. @@ -813,7 +802,6 @@ abstract class FirDataFlowAnalyzer( // (that requires a second level of implications: receiver != null => condition => effect). flow.addAllConditionally(expressionVariable notEq null, node.lastPreviousNode.flow) } - mergePostponedLambdaExitsNode?.mergeIncomingFlow() } fun exitResolvedQualifierNode(resolvedQualifier: FirResolvedQualifier) { @@ -1172,7 +1160,7 @@ abstract class FirDataFlowAnalyzer( } fun exitElvis(elvisExpression: FirElvisExpression, isLhsNotNull: Boolean, callCompleted: Boolean) { - val (node, mergePostponedLambdaExitsNode) = graphBuilder.exitElvis(isLhsNotNull, callCompleted) + val node = graphBuilder.exitElvis(isLhsNotNull, callCompleted) node.mergeIncomingFlow { flow -> // If LHS is never null, then the edge from RHS is dead and this node's flow already contains // all statements from LHS unconditionally. @@ -1183,7 +1171,6 @@ abstract class FirDataFlowAnalyzer( val elvisVariable = variableStorage.createSynthetic(elvisExpression) flow.addAllConditionally(elvisVariable eq !rhs, node.firstPreviousNode.flow) } - mergePostponedLambdaExitsNode?.mergeIncomingFlow() } // Callable reference @@ -1223,7 +1210,10 @@ abstract class FirDataFlowAnalyzer( private fun CFGNode<*>.buildIncomingFlow(): MutableFlow { val previousFlows = previousNodes.mapNotNull { val incomingEdgeKind = incomingEdges.getValue(it).kind - it.takeIf { incomingEdgeKind.usedInDfa || (isDead && incomingEdgeKind.usedInDeadDfa) }?.flow + if (if (isDead) !incomingEdgeKind.usedInDeadDfa else !incomingEdgeKind.usedInDfa) return@mapNotNull null + // `MergePostponedLambdaExitsNode` nodes form a parallel data flow graph. We never compute + // data flow for any of them until reaching a completed call. + if (it is MergePostponedLambdaExitsNode) it.mergeIncomingFlow() else it.flow } val result = logicSystem.joinFlow(previousFlows, union = this is UnionNodeMarker) if (graphBuilder.lastNodeOrNull == this) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 6a2aebfc1fa..959c0730680 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -63,13 +63,12 @@ class ControlFlowGraphBuilder { private val postponedAnonymousFunctionNodes = mutableMapOf, Pair>() - private val dataFlowSourcesForNextCompletedCall: Stack>> = stackOf() + private val postponedLambdaExits: Stack, EdgeKind>>> = stackOf() private val loopConditionEnterNodes: NodeStorage = NodeStorage() private val loopExitNodes: NodeStorage = NodeStorage() private val whenExitNodes: NodeStorage = NodeStorage() - private val whenBranchIndices: Stack> = stackOf() private val binaryLogicExpressionExitNodes: Stack> = stackOf() @@ -199,8 +198,6 @@ class ControlFlowGraphBuilder { } // ----------------------------------- Anonymous function ----------------------------------- - // TODO: this is ALL WRONG. - // // There are two cases we need to distinguish. // // 1. Function calls can have contracts that specify lambdas as "called in place". @@ -227,28 +224,28 @@ class ControlFlowGraphBuilder { // |<--------------\ | // \-----> [UNKNOWN] -----/ // \----------^ - // This is already problematic, since all these lambdas should share ONE entry node - // to which control can return after AT_LEAST_ONCE and UNKNOWN lambdas. To make - // matters worse, if the call is not complete, then the lambdas inside it *and* - // other lambdas in whatever expression this is a part of can be resolved in any order, - // so the data flow cannot look like this - until some call is finally completed, there - // will be holes in the graph where some lambdas' subgraphs should be. Instead, we - // should be collecting the lambdas as they are being resolved, filling gaps in the - // control flow graph, and then redirecting the outgoing data flow edges into the next - // completed call node. Unfortunately, I'm not sure how this fits into the subgraph - // design. Also, touching the `PostponedLambda{Enter,Exit}Node`s in any way seem to - // break random stuff that probably looks at `node.fir` with zero regard as to what - // the node even means. - fun visitPostponedAnonymousFunction(anonymousFunctionExpression: FirAnonymousFunctionExpression): Pair { - val anonymousFunction = anonymousFunctionExpression.anonymousFunction - val enterNode = createPostponedLambdaEnterNode(anonymousFunction) + // To implement this, we create dummy enter+exit nodes, then as the call is resolved + // plop in the lambdas in between them and add looping/skipping edges depending + // on how many times the lambda is called (only known after we select a candidate + // for the call). Then, when the call is exited, we add edges from the dummy exit + // nodes instead of directly from lambdas. + // + // If the call is not complete, then it is not guaranteed that lambdas will be resolved + // before we have to create the function call node. In that case we can still add + // control flow edges from the dummy nodes, but not data flow edges as the data flow + // for them may not have been computed yet. Instead, these edges are redirected + // into the outer call. The outermost call *has* to be completed, so at some point + // all data will be unified in a single call node. + fun visitPostponedAnonymousFunction(anonymousFunctionExpression: FirAnonymousFunctionExpression): PostponedLambdaEnterNode { + // TODO: should only have 1 enter node for all lambdas in a single call. + val enterNode = createPostponedLambdaEnterNode(anonymousFunctionExpression) val exitNode = createPostponedLambdaExitNode(anonymousFunctionExpression) - val symbol = anonymousFunction.symbol + val symbol = anonymousFunctionExpression.anonymousFunction.symbol postponedAnonymousFunctionNodes[symbol] = enterNode to exitNode addNewSimpleNode(enterNode) - addNewSimpleNode(exitNode, preferredKind = EdgeKind.DfgForward) - require(dataFlowSourcesForNextCompletedCall.isNotEmpty) - return enterNode to exitNode + addEdge(enterNode, exitNode) + postponedLambdaExits.top().add(exitNode to EdgeKind.Forward) + return enterNode } fun enterAnonymousFunction(anonymousFunction: FirAnonymousFunction): Pair { @@ -282,37 +279,20 @@ class ControlFlowGraphBuilder { val graph = popGraph().also { graph -> assert(graph.declaration == anonymousFunction) assert(graph.exitNode == exitNode) - // TODO: disregarding the edges is probably not correct, though this should never find any nodes anyway - dataFlowSourcesForNextCompletedCall.topOrNull()?.removeAll { it.owner == graph } } val (postponedEnterNode, postponedExitNode) = postponedAnonymousFunctionNodes.remove(symbol) ?: return Triple(exitNode, null, graph).also { currentGraph.addSubGraph(graph) } val invocationKind = anonymousFunction.invocationKind - var changedExitDataFlow = false // Lambdas not called in-place behave as if called never, but with extra invalidation of all smart casts // for all variables that they reassign. That second part is handled by `FirDataFlowAnalyzer`. - if (invocationKind?.isDefinitelyVisited() != true) { - // Data flow from enter -> exit already exists, only need to also mark that edge as control flow. - CFGNode.addJustKindEdge(postponedEnterNode, postponedExitNode, EdgeKind.CfgForward, propagateDeadness = true) - } if (invocationKind?.canBeVisited() == true) { - val currentCallsPostponedLambdas = dataFlowSourcesForNextCompletedCall.top() - // Since the skipping edge goes to `postponedExitNode` rather than `exitNode`, if - // we try to merge data flow for not-definitely-called lambdas from `exitNode` into the next call - // we won't get a correct result. TODO: that seems hacky and points to the edges being wrong. + addEdge(exitNode, postponedExitNode, propagateDeadness = invocationKind.isDefinitelyVisited()) if (invocationKind.isDefinitelyVisited()) { - // When a call has lambda arguments that the function says it will call in place, control goes through - // all other arguments, then through the lambdas in parallel, then out of the function call. This parallel - // (in terms of ordering, not multi-threaded or w/e) execution is represented with the call being a union node. - // TODO: currently this is only done for data flow; control flow incorrectly pretends lambdas - // are called in the order they are provided to the call, which is wrong. This needs to be fixed. Somehow. - addEdge(exitNode, postponedExitNode, preferredKind = EdgeKind.CfgForward, propagateDeadness = true) - currentCallsPostponedLambdas.add(postponedExitNode) - } else { - addEdge(exitNode, postponedExitNode, propagateDeadness = invocationKind.isDefinitelyVisited()) - changedExitDataFlow = true + // We had to create this edge so that if the lambda is postponed for so long that we exit the subgraph + // before visiting it, `orderNodes` can still find an ordering. Now we can kill it. + CFGNode.addJustKindEdge(postponedEnterNode, postponedExitNode, EdgeKind.DeadForward, propagateDeadness = false) } if (invocationKind.canBeRevisited()) { addBackEdge(postponedExitNode, postponedEnterNode) @@ -322,7 +302,7 @@ class ControlFlowGraphBuilder { postponedEnterNode.addSubGraph(graph) // May not be the current graph: `nearestCompletedCall(run { run { generic() } }, 1)` postponedEnterNode.owner.addSubGraph(graph) - return Triple(exitNode, postponedExitNode.takeIf { changedExitDataFlow }, graph) + return Triple(exitNode, postponedExitNode, graph) } fun exitAnonymousFunctionExpression(anonymousFunctionExpression: FirAnonymousFunctionExpression): AnonymousFunctionExpressionExitNode { @@ -332,28 +312,28 @@ class ControlFlowGraphBuilder { } private fun splitDataFlowForPostponedLambdas() { - dataFlowSourcesForNextCompletedCall.push(mutableListOf()) - } - - private fun MutableList>.addPostponedLambdaDataFlowEdgesTo(node: CFGNode<*>) { - for (exitNode in this) { - // To avoid storing nodes from subgraphs in the list, we have PostponedLambdaExitNode instead of the real - // exit node of the lambda subgraph. The latter is the previous node of the former. Everything else is - // already a join node in this graph. - val functionExitOrMerge = if (exitNode is PostponedLambdaExitNode) exitNode.lastPreviousNode else exitNode - addEdge(functionExitOrMerge, node, preferredKind = EdgeKind.DfgForward, propagateDeadness = false) - } + postponedLambdaExits.push(mutableListOf()) } private fun unifyDataFlowFromPostponedLambdas(node: T, callCompleted: Boolean) where T : CFGNode<*>, T : UnionNodeMarker { - val currentLevelExits = dataFlowSourcesForNextCompletedCall.pop() + val currentLevelExits = postponedLambdaExits.pop() if (currentLevelExits.isEmpty()) return - val nextLevelExits = dataFlowSourcesForNextCompletedCall.topOrNull().takeIf { !callCompleted } + + val nextLevelExits = postponedLambdaExits.topOrNull().takeIf { !callCompleted } if (nextLevelExits != null) { // Call is incomplete, don't pass data flow from lambdas inside it to lambdas in the outer call. - nextLevelExits.addAll(currentLevelExits) + for ((exit, kind) in currentLevelExits) { + if (kind.usedInCfa) { + addEdge(exit, node, preferredKind = EdgeKind.CfgForward) + } + nextLevelExits.add(exit to EdgeKind.DfgForward) + } } else { - currentLevelExits.addPostponedLambdaDataFlowEdgesTo(node) + for ((exit, kind) in currentLevelExits) { + // Since `node` is a union node, it is dead iff any input is dead. For once, `propagateDeadness` + // semantics are correct without an `updateDeadStatus`. + addEdge(exit, node, preferredKind = kind, propagateDeadness = kind.usedInCfa) + } } } @@ -368,7 +348,7 @@ class ControlFlowGraphBuilder { // \-> y -> ?? -> run#2 -/ // // Ideally, we want to pretend that the lambdas are not called-in-place until we get - // to `f`, at which point the lambdas are guaranteed to be resolved and we should be + // to `f`, at which point the lambdas are guaranteed to be resolved, and we should be // able to reconstruct the entire data flow. The problem is that the call/when/etc. // exit nodes on the way from the lambda to the function call exit node can have // statements attached to them, so unless we want to re-do all the work, it's too late @@ -376,24 +356,31 @@ class ControlFlowGraphBuilder { // they may reassign variables and so the data we've gathered about them should be // invalidated. So what we do here is merge the data from the lambdas with the data // obtained without them: this can only erase statements that are not provably correct. - private fun mergeDataFlowFromPostponedLambdas(node: CFGNode<*>, callCompleted: Boolean): MergePostponedLambdaExitsNode? { - val currentLevelExits = dataFlowSourcesForNextCompletedCall.pop() - if (currentLevelExits.isEmpty()) return null + // + // TODO: an alternative is to delay computing incoming flow for "branch result exit" nodes + // until the entire "when" is resolved; then either unify each branch's lambdas into its + // exit node, or create N union nodes (1/branch) and point them into the merge node. + private fun mergeDataFlowFromPostponedLambdas(node: CFGNode<*>, callCompleted: Boolean) { + val currentLevelExits = postponedLambdaExits.pop() + if (currentLevelExits.isEmpty()) return - val nextLevelExits = dataFlowSourcesForNextCompletedCall.topOrNull().takeIf { !callCompleted } - return if (nextLevelExits != null) { - // Call is incomplete, don't pass data flow from lambdas inside it to lambdas in the outer call. - // TODO: this is wrong, we don't necessarily have all the lambdas yet... Also, - // the lambdas in the list can come from different branches, and this should be - // more like merge(node, union(lambdas from branch 1), ..., union(from branch N)). - createMergePostponedLambdaExitsNode(node.fir).also { - addEdge(node, it) - currentLevelExits.addPostponedLambdaDataFlowEdgesTo(it) - nextLevelExits.add(it) - } + val nextLevelExits = postponedLambdaExits.topOrNull().takeIf { !callCompleted } + if (nextLevelExits != null) { + node.updateDeadStatus() + nextLevelExits += createMergePostponedLambdaExitsNode(node.fir).also { + addEdge(node, it) // copy liveness (deadness?) from `node` + for ((exit, kind) in currentLevelExits) { + if (kind.usedInCfa) { + addEdge(exit, node, preferredKind = EdgeKind.CfgForward, propagateDeadness = false) + } + addEdge(exit, it, preferredKind = EdgeKind.DfgForward, propagateDeadness = false) + } + } to EdgeKind.DfgForward } else { - currentLevelExits.addPostponedLambdaDataFlowEdgesTo(node) - null + for ((exit, kind) in currentLevelExits) { + // `node` is a merge node for many inputs anyhow so someone will call `updateDeadStatus` on it. + addEdge(exit, node, preferredKind = kind, propagateDeadness = false) + } } } @@ -709,7 +696,6 @@ class ControlFlowGraphBuilder { val node = createWhenEnterNode(whenExpression) addNewSimpleNode(node) whenExitNodes.push(createWhenExitNode(whenExpression)) - whenBranchIndices.push(whenExpression.branches.mapIndexed { index, branch -> branch to index }.toMap()) notCompletedFunctionCalls.push(mutableListOf()) levelCounter++ splitDataFlowForPostponedLambdas() @@ -721,7 +707,6 @@ class ControlFlowGraphBuilder { } fun enterWhenBranchCondition(whenBranch: FirWhenBranch): WhenBranchConditionEnterNode { - levelCounter += whenBranchIndices.top().getValue(whenBranch) return createWhenBranchConditionEnterNode(whenBranch).also { addNewSimpleNode(it) }.also { levelCounter++ } } @@ -743,14 +728,15 @@ class ControlFlowGraphBuilder { popAndAddEdge(node) val whenExitNode = whenExitNodes.top() addEdge(node, whenExitNode, propagateDeadness = false) - levelCounter -= whenBranchIndices.top().getValue(whenBranch) + levelCounter++ return node } fun exitWhenExpression( whenExpression: FirWhenExpression, callCompleted: Boolean - ): Triple { + ): Pair { + levelCounter -= whenExpression.branches.size val whenExitNode = whenExitNodes.pop() // exit from last condition node still on stack // we should remove it @@ -762,11 +748,11 @@ class ControlFlowGraphBuilder { addEdge(this, whenExitNode) } } else null + mergeDataFlowFromPostponedLambdas(whenExitNode, callCompleted) whenExitNode.updateDeadStatus() lastNodes.push(whenExitNode) levelCounter-- - whenBranchIndices.pop() - return Triple(whenExitNode, syntheticElseBranchNode, mergeDataFlowFromPostponedLambdas(whenExitNode, callCompleted)) + return whenExitNode to syntheticElseBranchNode } // ----------------------------------- While Loop ----------------------------------- @@ -1015,7 +1001,7 @@ class ControlFlowGraphBuilder { } } - fun exitTryExpression(callCompleted: Boolean): Pair { + fun exitTryExpression(callCompleted: Boolean): TryExpressionExitNode { levelCounter-- catchNodeStorages.pop() val catchExitNodes = catchExitNodeStorages.pop() @@ -1024,6 +1010,7 @@ class ControlFlowGraphBuilder { notCompletedFunctionCalls.pop().forEach(::completeFunctionCall) val node = tryExitNodes.pop() + mergeDataFlowFromPostponedLambdas(node, callCompleted) node.updateDeadStatus() lastNodes.push(node) @@ -1038,7 +1025,7 @@ class ControlFlowGraphBuilder { lastNodes.push(stub) } - return node to mergeDataFlowFromPostponedLambdas(node, callCompleted) + return node } //this is a workaround to make function call dead when call is completed _after_ building its node in the graph @@ -1245,18 +1232,18 @@ class ControlFlowGraphBuilder { return enterNode } - fun exitSafeCall(): Pair { + fun exitSafeCall(): ExitSafeCallNode { // There will be two paths towards this exit safe call node: // one from the node prior to the enclosing safe call, and // the other from the selector part in the enclosing safe call. // Note that *neither* points to the safe call directly. // So, when it comes to the real exit of the enclosing block/function, // the safe call bound to this exit safe call node should be retrieved. - return exitSafeCallNodes.pop().let { + return exitSafeCallNodes.pop().also { addNewSimpleNode(it) - it.updateDeadStatus() // Safe calls only have one user-specified branch, so if any lambdas were postponed, they still are. - it to mergeDataFlowFromPostponedLambdas(it, callCompleted = false) + mergeDataFlowFromPostponedLambdas(it, callCompleted = false) + it.updateDeadStatus() } } @@ -1291,11 +1278,12 @@ class ControlFlowGraphBuilder { return Triple(lhsExitNode, lhsIsNotNullNode, rhsEnterNode) } - fun exitElvis(lhsIsNotNull: Boolean, callCompleted: Boolean): Pair { + fun exitElvis(lhsIsNotNull: Boolean, callCompleted: Boolean): ElvisExitNode { val exitNode = exitElvisExpressionNodes.pop() addNewSimpleNode(exitNode, isDead = lhsIsNotNull) + mergeDataFlowFromPostponedLambdas(exitNode, callCompleted) exitNode.updateDeadStatus() - return exitNode to mergeDataFlowFromPostponedLambdas(exitNode, callCompleted) + return exitNode } // ----------------------------------- Contract description ----------------------------------- @@ -1318,7 +1306,7 @@ class ControlFlowGraphBuilder { // ------------------------------------------------------------------------------------------------------------------------- fun reset() { - dataFlowSourcesForNextCompletedCall.reset() + postponedLambdaExits.reset() lastNodes.reset() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt index 59391d2cbea..7641a71b1b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt @@ -223,7 +223,7 @@ fun ControlFlowGraphBuilder.createEnterSafeCallNode(fir: FirSafeCallExpression): fun ControlFlowGraphBuilder.createPostponedLambdaExitNode(fir: FirAnonymousFunctionExpression): PostponedLambdaExitNode = PostponedLambdaExitNode(currentGraph, fir, levelCounter, createId()) -fun ControlFlowGraphBuilder.createPostponedLambdaEnterNode(fir: FirAnonymousFunction): PostponedLambdaEnterNode = +fun ControlFlowGraphBuilder.createPostponedLambdaEnterNode(fir: FirAnonymousFunctionExpression): PostponedLambdaEnterNode = PostponedLambdaEnterNode(currentGraph, fir, levelCounter, createId()) fun ControlFlowGraphBuilder.createAnonymousFunctionExpressionExitNode(fir: FirAnonymousFunctionExpression): AnonymousFunctionExpressionExitNode = diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt index 11537defb71..a0353299b4f 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt @@ -129,7 +129,10 @@ sealed class CFGNode(val owner: ControlFlowGraph, val level: open var flow: PersistentFlow get() = _flow ?: throw IllegalStateException("flow for $this not initialized - traversing nodes in wrong order?") @CfgInternals - set(value) { _flow = value } // TODO: forbid reassignment + set(value) { + assert(_flow == null) { "reassigning flow for $this" } + _flow = value + } @CfgInternals fun updateDeadStatus() { @@ -240,7 +243,7 @@ class ExitDefaultArgumentsNode(owner: ControlFlowGraph, override val fir: FirVal // ----------------------------------- Anonymous function ----------------------------------- -class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunction, level: Int, id: Int) : CFGNodeWithSubgraphs(owner, level, id) { +class PostponedLambdaEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousFunctionExpression, level: Int, id: Int) : CFGNodeWithSubgraphs(owner, level, id) { override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { return visitor.visitPostponedLambdaEnterNode(this, data) } diff --git a/compiler/testData/codegen/box/smartCasts/kt44814.dot b/compiler/testData/codegen/box/smartCasts/kt44814.dot index c25f8136e26..49cf1df1a2f 100644 --- a/compiler/testData/codegen/box/smartCasts/kt44814.dot +++ b/compiler/testData/codegen/box/smartCasts/kt44814.dot @@ -712,7 +712,7 @@ digraph kt44814_kt { 188 -> {189}; 189 -> {190}; 190 -> {191}; - 191 -> {192 238}; + 191 -> {192 238 193}; 191 -> {238} [style=dashed]; 192 -> {193}; 192 -> {191} [color=green style=dashed]; @@ -738,10 +738,11 @@ digraph kt44814_kt { 211 -> {212}; 212 -> {217 213}; 213 -> {214}; - 214 -> {232}; - 214 -> {215} [color=red]; + 214 -> {232 216}; + 214 -> {215} [style=dotted]; 214 -> {232} [style=dashed]; - 215 -> {216}; + 215 -> {221} [color=red]; + 215 -> {216} [color=green]; 216 -> {218}; 217 -> {218}; 218 -> {221 219}; @@ -763,8 +764,7 @@ digraph kt44814_kt { 234 -> {235}; 235 -> {236}; 236 -> {237}; - 237 -> {221} [color=red]; - 237 -> {215} [color=green]; + 237 -> {215}; 238 -> {239}; 239 -> {240}; 240 -> {241 243};