diff --git a/compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.dot b/compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.dot index 09068e61e8e..174023a2a1d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.dot @@ -101,7 +101,6 @@ digraph initializationInTry_kt { 26 -> {27}; 27 -> {28}; 28 -> {29}; - 28 -> {33} [label="onUncaughtException"]; 29 -> {30}; 30 -> {31}; 31 -> {32}; @@ -168,7 +167,6 @@ digraph initializationInTry_kt { 48 -> {49}; 49 -> {50}; 50 -> {51}; - 50 -> {55} [label="onUncaughtException"]; 51 -> {52}; 52 -> {53}; 53 -> {54}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/complex.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/complex.dot index bde0f3e54ac..5947d6ab254 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/complex.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/complex.dot @@ -148,7 +148,6 @@ digraph complex_kt { 25 -> {26}; 26 -> {27 36}; 27 -> {28}; - 27 -> {52} [label="onUncaughtException"]; 28 -> {29}; 29 -> {30}; 30 -> {31}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot index 08c1c4f4c0a..1d356071a7e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot @@ -195,12 +195,11 @@ digraph flowFromInplaceLambda_kt { 97 [label="Stub" style="filled" fillcolor=gray]; 98 [label="Exit block" style="filled" fillcolor=gray]; } - 99 [label="Exit function materialize" style="filled" fillcolor=red]; + 99 [label="Exit function materialize" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 91 -> {92}; 92 -> {93}; 93 -> {94}; - 94 -> {99} [label="onUncaughtException"]; 94 -> {95} [style=dotted]; 95 -> {96} [style=dotted]; 96 -> {97 99} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/initBlock.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/initBlock.dot index 32f3fb34df2..a6579819a18 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/initBlock.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/initBlock.dot @@ -66,26 +66,25 @@ digraph initBlock_kt { 23 [label="Variable declaration: lval y: R|kotlin/Int|" style="filled" fillcolor=gray]; 24 [label="Exit block" style="filled" fillcolor=gray]; } - 25 [label="Exit init block" style="filled" fillcolor=red]; + 25 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 15 -> {16}; 16 -> {17}; 17 -> {18}; 18 -> {19}; 19 -> {20}; - 20 -> {25} [label="onUncaughtException"]; 20 -> {21} [style=dotted]; 21 -> {22} [style=dotted]; 22 -> {23} [style=dotted]; 23 -> {24} [style=dotted]; 24 -> {25} [style=dotted]; - 25 -> {28} [color=green]; + 25 -> {28} [style=dotted]; subgraph cluster_7 { color=red 26 [label="Enter class Bar" style="filled" fillcolor=red]; 27 [label="Part of class initialization"]; - 28 [label="Exit class Bar" style="filled" fillcolor=red]; + 28 [label="Exit class Bar" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 26 -> {27} [color=green]; 27 -> {15} [color=green]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot index 6240ab4fd5c..ace5d8ff83c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/inplaceLambdaInControlFlowExpressions.dot @@ -16,12 +16,11 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 6 [label="Stub" style="filled" fillcolor=gray]; 7 [label="Exit block" style="filled" fillcolor=gray]; } - 8 [label="Exit function materialize" style="filled" fillcolor=red]; + 8 [label="Exit function materialize" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; - 3 -> {8} [label="onUncaughtException"]; 3 -> {4} [style=dotted]; 4 -> {5} [style=dotted]; 5 -> {6 8} [style=dotted]; @@ -182,7 +181,6 @@ digraph inplaceLambdaInControlFlowExpressions_kt { 46 -> {47}; 47 -> {48 54}; 48 -> {49}; - 48 -> {57} [label="onUncaughtException"]; 49 -> {50}; 50 -> {51}; 51 -> {52}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot index 2b7597f1808..8dcece1862c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/jumps.dot @@ -75,7 +75,6 @@ digraph jumps_kt { 16 -> {17}; 17 -> {18}; 18 -> {19}; - 19 -> {31} [label="onUncaughtException"]; 19 -> {20} [style=dotted]; 20 -> {21} [style=dotted]; 21 -> {22} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot index f00d2e3426b..a7cf10c846d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot @@ -59,11 +59,10 @@ digraph lambdaReturningObject_kt { 18 [label="Stub" style="filled" fillcolor=gray]; 19 [label="Exit block" style="filled" fillcolor=gray]; } - 20 [label="Exit function MyOut" style="filled" fillcolor=red]; + 20 [label="Exit function MyOut" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 13 -> {14}; 14 -> {15}; - 15 -> {20} [label="onUncaughtException"]; 15 -> {16} [style=dotted]; 16 -> {17} [style=dotted]; 17 -> {18 20} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInReturn.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInReturn.dot index 79428336b78..92fb48fda64 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInReturn.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInReturn.dot @@ -329,7 +329,6 @@ digraph postponedLambdaInReturn_kt { 101 -> {102} [style=dotted]; 102 -> {103 108} [style=dotted]; 103 -> {104}; - 103 -> {84} [label="onUncaughtException"]; 104 -> {105}; 105 -> {106}; 106 -> {107}; @@ -339,7 +338,6 @@ digraph postponedLambdaInReturn_kt { 110 -> {88} [color=green style=dashed]; 111 -> {112} [style=dotted]; 112 -> {113} [style=dotted]; - 113 -> {84} [style=dotted label="onUncaughtException"]; 113 -> {114} [style=dotted]; 114 -> {115} [style=dotted]; 115 -> {116} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot index 89050f04f9b..060c441d79a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.dot @@ -91,7 +91,7 @@ digraph propertiesAndInitBlocks_kt { 43 [label="Stub" style="filled" fillcolor=gray]; 44 [label="Exit block" style="filled" fillcolor=gray]; } - 45 [label="Exit function foo" style="filled" fillcolor=red]; + 45 [label="Exit function foo" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 35 -> {36}; 36 -> {37}; @@ -100,7 +100,6 @@ digraph propertiesAndInitBlocks_kt { 39 -> {40}; 40 -> {41}; 41 -> {42}; - 42 -> {45} [label="onUncaughtException"]; 42 -> {43} [style=dotted]; 43 -> {44} [style=dotted]; 44 -> {45} [style=dotted]; @@ -126,17 +125,16 @@ digraph propertiesAndInitBlocks_kt { 54 [label="Const: Int(1)" style="filled" fillcolor=gray]; 55 [label="Exit block" style="filled" fillcolor=gray]; } - 56 [label="Exit init block" style="filled" fillcolor=red]; + 56 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 49 -> {50}; 50 -> {51}; 51 -> {52}; - 52 -> {56} [label="onUncaughtException"]; 52 -> {53} [style=dotted]; 53 -> {54} [style=dotted]; 54 -> {55} [style=dotted]; 55 -> {56} [style=dotted]; - 56 -> {34} [color=green]; + 56 -> {34} [style=dotted]; subgraph cluster_13 { color=red @@ -153,7 +151,7 @@ digraph propertiesAndInitBlocks_kt { color=blue 62 [label="Enter class GetterLocalClass" style="filled" fillcolor=red]; 63 [label="Part of class initialization"]; - 64 [label="Exit class GetterLocalClass" style="filled" fillcolor=red]; + 64 [label="Exit class GetterLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 57 -> {58}; 58 -> {59}; @@ -187,16 +185,15 @@ digraph propertiesAndInitBlocks_kt { 72 [label="Stub" style="filled" fillcolor=gray]; 73 [label="Exit block" style="filled" fillcolor=gray]; } - 74 [label="Exit init block" style="filled" fillcolor=red]; + 74 [label="Exit init block" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 68 -> {69}; 69 -> {70}; 70 -> {71}; - 71 -> {74} [label="onUncaughtException"]; 71 -> {72} [style=dotted]; 72 -> {73} [style=dotted]; 73 -> {74} [style=dotted]; - 74 -> {64} [color=green]; + 74 -> {64} [style=dotted]; subgraph cluster_19 { color=red @@ -220,7 +217,7 @@ digraph propertiesAndInitBlocks_kt { color=blue 32 [label="Enter class InitializerLocalClass" style="filled" fillcolor=red]; 33 [label="Part of class initialization"]; - 34 [label="Exit class InitializerLocalClass" style="filled" fillcolor=red]; + 34 [label="Exit class InitializerLocalClass" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 77 [label="Postponed exit from lambda"]; 78 [label="Function call: R|/run|(...)" style="filled" fillcolor=yellow]; @@ -239,7 +236,6 @@ digraph propertiesAndInitBlocks_kt { 26 -> {32 46} [color=green]; 26 -> {32 46} [style=dashed]; 27 -> {28}; - 28 -> {79} [label="onUncaughtException"]; 28 -> {29} [style=dotted]; 29 -> {30} [style=dotted]; 30 -> {31} [style=dotted]; @@ -313,7 +309,6 @@ digraph propertiesAndInitBlocks_kt { 95 -> {96}; 96 -> {97}; 97 -> {98}; - 97 -> {99} [label="onUncaughtException"]; 98 -> {99}; } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot index 445cd57b132..ebe882e5ae5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/returnValuesFromLambda.dot @@ -196,7 +196,6 @@ digraph returnValuesFromLambda_kt { 55 -> {56 57} [style=dotted]; 55 -> {62} [style=dashed]; 56 -> {57} [style=dotted]; - 57 -> {61} [style=dotted label="onUncaughtException"]; 57 -> {58} [style=dotted]; 58 -> {59} [style=dotted]; 59 -> {60} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/tryCatch.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/tryCatch.dot index a89841a6536..ddc705247b4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/tryCatch.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/tryCatch.dot @@ -66,7 +66,6 @@ digraph tryCatch_kt { 7 -> {8}; 8 -> {9 16 23}; 9 -> {10}; - 9 -> {25} [label="onUncaughtException"]; 10 -> {11}; 11 -> {12}; 12 -> {13}; @@ -74,7 +73,6 @@ digraph tryCatch_kt { 14 -> {15}; 15 -> {23}; 16 -> {17}; - 16 -> {25} [label="onUncaughtException"]; 17 -> {18}; 18 -> {19}; 19 -> {20}; @@ -132,7 +130,6 @@ digraph tryCatch_kt { 32 -> {33}; 33 -> {34 40}; 34 -> {35}; - 34 -> {43} [label="onUncaughtException"]; 35 -> {36}; 36 -> {37}; 37 -> {38}; @@ -307,7 +304,6 @@ digraph tryCatch_kt { 82 -> {83}; 83 -> {84 91 103}; 84 -> {85}; - 84 -> {99} [label="onUncaughtException"]; 85 -> {86}; 86 -> {87}; 87 -> {47} [color=green style=dashed]; @@ -316,7 +312,6 @@ digraph tryCatch_kt { 89 -> {90} [style=dotted]; 90 -> {103} [style=dotted]; 91 -> {92}; - 91 -> {99} [label="onUncaughtException"]; 92 -> {93}; 93 -> {94}; 94 -> {95}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/variableInitializedInTryBlock.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/variableInitializedInTryBlock.dot index fed57d116cb..7e6c7291fcb 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/variableInitializedInTryBlock.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/variableInitializedInTryBlock.dot @@ -83,7 +83,7 @@ digraph variableInitializedInTryBlock_kt { 23 -> {24}; 24 -> {25}; 25 -> {26}; - 25 -> {30} [label="onUncaughtException"]; + 25 -> {30} [label="return@/test"]; 26 -> {27}; 27 -> {28}; 28 -> {29}; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/jumpFromRhsOfOperator.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/jumpFromRhsOfOperator.dot index a69eeffce0d..b04bac13a22 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/jumpFromRhsOfOperator.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/jumpFromRhsOfOperator.dot @@ -52,7 +52,6 @@ digraph jumpFromRhsOfOperator_kt { 10 -> {11 15}; 11 -> {12}; 12 -> {13}; - 13 -> {20} [label="onUncaughtException"]; 13 -> {14} [style=dotted]; 14 -> {15} [style=dotted]; 15 -> {16}; @@ -96,7 +95,6 @@ digraph jumpFromRhsOfOperator_kt { 27 -> {28 32}; 28 -> {29}; 29 -> {30}; - 30 -> {37} [label="onUncaughtException"]; 30 -> {31} [style=dotted]; 31 -> {32} [style=dotted]; 32 -> {33}; @@ -163,7 +161,6 @@ digraph jumpFromRhsOfOperator_kt { 46 -> {47 51}; 47 -> {48}; 48 -> {49}; - 49 -> {66} [label="onUncaughtException"]; 49 -> {50} [style=dotted]; 50 -> {51} [style=dotted]; 51 -> {52}; @@ -240,7 +237,6 @@ digraph jumpFromRhsOfOperator_kt { 75 -> {76 80}; 76 -> {77}; 77 -> {78}; - 78 -> {95} [label="onUncaughtException"]; 78 -> {79} [style=dotted]; 79 -> {80} [style=dotted]; 80 -> {81}; @@ -294,7 +290,6 @@ digraph jumpFromRhsOfOperator_kt { 102 -> {103 107}; 103 -> {104}; 104 -> {105}; - 105 -> {112} [label="onUncaughtException"]; 105 -> {106} [style=dotted]; 106 -> {107} [style=dotted]; 107 -> {108}; @@ -338,7 +333,6 @@ digraph jumpFromRhsOfOperator_kt { 119 -> {120 124}; 120 -> {121}; 121 -> {122}; - 122 -> {129} [label="onUncaughtException"]; 122 -> {123} [style=dotted]; 123 -> {124} [style=dotted]; 124 -> {125}; @@ -405,7 +399,6 @@ digraph jumpFromRhsOfOperator_kt { 138 -> {139 143}; 139 -> {140}; 140 -> {141}; - 141 -> {158} [label="onUncaughtException"]; 141 -> {142} [style=dotted]; 142 -> {143} [style=dotted]; 143 -> {144}; @@ -482,7 +475,6 @@ digraph jumpFromRhsOfOperator_kt { 167 -> {168 172}; 168 -> {169}; 169 -> {170}; - 170 -> {187} [label="onUncaughtException"]; 170 -> {171} [style=dotted]; 171 -> {172} [style=dotted]; 172 -> {173}; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.dot index dfd124611c9..acbacb096f4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.dot @@ -871,7 +871,6 @@ digraph boundSmartcastsInBranches_kt { 309 -> {310}; 310 -> {311}; 311 -> {312}; - 312 -> {341} [label="onUncaughtException"]; 312 -> {313} [style=dotted]; 313 -> {314} [style=dotted]; 314 -> {315} [style=dotted]; @@ -1207,7 +1206,6 @@ digraph boundSmartcastsInBranches_kt { 446 -> {447}; 447 -> {448}; 448 -> {449}; - 449 -> {479} [label="onUncaughtException"]; 449 -> {450} [style=dotted]; 450 -> {451} [style=dotted]; 451 -> {452} [style=dotted]; 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 4d782b7b190..84af1a7e810 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot @@ -295,7 +295,6 @@ digraph safeCalls_kt { 97 -> {98 99} [style=dotted]; 97 -> {112} [style=dashed]; 98 -> {99} [style=dotted]; - 99 -> {111} [style=dotted label="onUncaughtException"]; 99 -> {100} [style=dotted]; 100 -> {101 106} [style=dotted]; 101 -> {102} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartCastInInit.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartCastInInit.dot index 5668ced4494..5d34587a3a3 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartCastInInit.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartCastInInit.dot @@ -36,11 +36,10 @@ digraph smartCastInInit_kt { 11 [label="Stub" style="filled" fillcolor=gray]; 12 [label="Exit block" style="filled" fillcolor=gray]; } - 13 [label="Exit function s" style="filled" fillcolor=red]; + 13 [label="Exit function s" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 6 -> {7}; 7 -> {8}; - 8 -> {13} [label="onUncaughtException"]; 8 -> {9} [style=dotted]; 9 -> {10} [style=dotted]; 10 -> {11 13} [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 407309caa15..f175de45f4c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.dot @@ -16,12 +16,11 @@ digraph smartcastToNothing_kt { 6 [label="Stub" style="filled" fillcolor=gray]; 7 [label="Exit block" style="filled" fillcolor=gray]; } - 8 [label="Exit function getNothing" style="filled" fillcolor=red]; + 8 [label="Exit function getNothing" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; - 3 -> {8} [label="onUncaughtException"]; 3 -> {4} [style=dotted]; 4 -> {5} [style=dotted]; 5 -> {6 8} [style=dotted]; @@ -104,12 +103,11 @@ digraph smartcastToNothing_kt { 36 [label="Stub" style="filled" fillcolor=gray]; 37 [label="Exit block" style="filled" fillcolor=gray]; } - 38 [label="Exit function myListOf" style="filled" fillcolor=red]; + 38 [label="Exit function myListOf" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 30 -> {31}; 31 -> {32}; 32 -> {33}; - 33 -> {38} [label="onUncaughtException"]; 33 -> {34} [style=dotted]; 34 -> {35} [style=dotted]; 35 -> {36 38} [style=dotted]; @@ -266,17 +264,14 @@ digraph smartcastToNothing_kt { 65 -> {66}; 66 -> {67}; 67 -> {68}; - 68 -> {93} [label="onUncaughtException"]; 68 -> {69} [style=dotted]; 69 -> {70} [style=dotted]; 70 -> {71} [style=dotted]; - 71 -> {93} [style=dotted label="onUncaughtException"]; 71 -> {72} [style=dotted]; 72 -> {73} [style=dotted]; 73 -> {74} [style=dotted]; 74 -> {75} [style=dotted]; 75 -> {76} [style=dotted]; - 76 -> {93} [style=dotted label="onUncaughtException"]; 76 -> {77} [style=dotted]; 77 -> {78} [style=dotted]; 78 -> {79} [style=dotted]; @@ -398,7 +393,6 @@ digraph smartcastToNothing_kt { 131 -> {132}; 132 -> {133}; 133 -> {134}; - 134 -> {142} [label="onUncaughtException"]; 134 -> {135} [style=dotted]; 135 -> {136} [style=dotted]; 136 -> {137} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot index 1f9b47a02ad..63ee8e62f44 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot @@ -32,12 +32,11 @@ digraph delegateWithAnonymousObject_kt { 11 [label="Stub" style="filled" fillcolor=gray]; 12 [label="Exit block" style="filled" fillcolor=gray]; } - 13 [label="Exit function delegate" style="filled" fillcolor=red]; + 13 [label="Exit function delegate" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 5 -> {6}; 6 -> {7}; 7 -> {8}; - 8 -> {13} [label="onUncaughtException"]; 8 -> {9} [style=dotted]; 9 -> {10} [style=dotted]; 10 -> {11 13} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot index 2f09c19786e..e84d6a209dc 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/plusAssignWithLambdaInRhs.dot @@ -30,12 +30,11 @@ digraph plusAssignWithLambdaInRhs_kt { 9 [label="Function call: R|/list|.R|kotlin/collections/plusAssign| kotlin/String|>(...)" style="filled" fillcolor=gray]; 10 [label="Exit block" style="filled" fillcolor=gray]; } - 11 [label="Exit function test" style="filled" fillcolor=red]; + 11 [label="Exit function test" style="filled" fillcolor=red style="filled" fillcolor=gray]; } 0 -> {1}; 1 -> {2}; 2 -> {3}; - 3 -> {11} [label="onUncaughtException"]; 3 -> {4} [style=dotted]; 4 -> {5} [style=dotted]; 5 -> {6} [style=dotted]; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot index 235dd2c4d1f..133862d1af8 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot @@ -116,7 +116,6 @@ finally { 23 -> {24}; 24 -> {25}; 25 -> {26}; - 25 -> {30} [label="onUncaughtException"]; 26 -> {27}; 27 -> {30}; 27 -> {28} [style=dotted]; @@ -205,7 +204,6 @@ finally { 48 -> {49}; 49 -> {50}; 50 -> {51}; - 50 -> {55} [label="onUncaughtException"]; 51 -> {52}; 52 -> {55}; 52 -> {53} [style=dotted]; 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 c2c987c96a7..ed0617a0e7d 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 @@ -938,6 +938,9 @@ class ControlFlowGraphBuilder { finallyEnterNodes.push(createFinallyBlockEnterNode(tryExpression)) } + // These edges should really be from `enterTryMainBlockNode`, but there is no practical difference + // so w/e. In fact, `enterTryExpressionNode` is just 100% redundant. + // TODO: this is more or less `addExceptionEdgesFrom(enterTryExpressionNode)`. Hmm. for (catchEnterNode in catchNodes.top()) { addEdge(enterTryExpressionNode, catchEnterNode) } @@ -959,11 +962,14 @@ class ControlFlowGraphBuilder { // try { a } catch (e) { b } [finally { c }] // \-----------------^ val nextNode = if (node.fir.finallyBlock != null) finallyEnterNodes.top() else exitTryExpressionNode + // Liveness of `exitTryExpressionNode` will be computed at the end since there are `catch`es. + // And the `finally` node is never dead unless the entire try-finally is dead. addEdge(node, nextNode, propagateDeadness = false) for (catchEnterNode in catchNodes.pop().asReversed()) { catchBlocksInProgress.push(catchEnterNode) // At least merge the data flow from enter + exit...but this doesn't really help, - // see the comment for `addExceptionEdgesFrom`. + // see the comment for `addExceptionEdgesFrom`. Better than nothing, though. + // Like `finally`, `catch` nodes are only dead if the entire try-catch is dead. addEdge(node, catchEnterNode, propagateDeadness = false) } return node @@ -975,9 +981,6 @@ class ControlFlowGraphBuilder { if (tryExitNodes.top().fir.finallyBlock != null) { // TODO: not sure this does anything? addEdge(catchEnterNode, finallyEnterNodes.top(), propagateDeadness = false, label = UncaughtExceptionPath) - } else { - // TODO: this DEFINITELY does nothing, and is in fact incorrect if there are outer try-finally. - addEdge(catchEnterNode, exitTargetsForTry.top(), propagateDeadness = false, label = UncaughtExceptionPath) } lastNodes.push(catchEnterNode) levelCounter++ @@ -1013,27 +1016,40 @@ class ControlFlowGraphBuilder { edge.kind.isDead || edge.label != NormalPath } addEdge(exitNode, tryExitNode, isDead = allNormalInputsAreDead) - val nextExitLevel = addUncaughtExceptionEdgeFrom(exitNode) + // TODO: there should also be edges to outer catch blocks? Control flow can go like this: + // try { try { throw E2() } catch (e: E1) { } finally { } } catch (e: E2) { } + // \-----------------------------^ \-----------------^ + // Wait, that's just `addExceptionEdgesFrom(exitNode)` again! + val nextExitLevel = exitTargetsForTry.top().level + val nextFinally = finallyEnterNodes.topOrNull()?.takeIf { it.level > nextExitLevel } + if (nextFinally != null) { + addEdge(exitNode, nextFinally, label = UncaughtExceptionPath, propagateDeadness = false) + } + + val nextFinallyOrExitLevel = nextFinally?.level ?: nextExitLevel // /-----------v // f@ { try { return@f } finally { b }; c } // \-----^ - exitNode.addReturnEdges(exitTargetsForReturn, nextExitLevel) + exitNode.addReturnEdges(exitTargetsForReturn, nextFinallyOrExitLevel) // /-----------v // f@ while (x) { try { continue@f } finally { b }; c } // ^------------------------------------/ - exitNode.addReturnEdges(loopConditionEnterNodes, nextExitLevel) + exitNode.addReturnEdges(loopConditionEnterNodes, nextFinallyOrExitLevel) // /-----------v // f@ while (x) { try { break@f } finally { b }; c } // \-----^ - exitNode.addReturnEdges(loopExitNodes, nextExitLevel) + exitNode.addReturnEdges(loopExitNodes, nextFinallyOrExitLevel) return exitNode } private fun > CFGNode<*>.addReturnEdges(nodes: Stack, minLevel: Int) { for (node in nodes.all()) { when { - node.level <= minLevel -> break + node.level < minLevel -> break + // TODO: this check is imprecise and can add redundant edges: + // x@{ try { return@x } finally {}; try {} finally { /* return@x target is in nonDirectJumps */ } node !in nonDirectJumps -> continue + // TODO: if the input to finally with that label is dead, then so should be the exit probably node.returnPathIsBackwards -> addBackEdge(this, node, label = node.returnPathLabel) else -> addEdge(this, node, propagateDeadness = false, label = node.returnPathLabel) } @@ -1050,25 +1066,17 @@ class ControlFlowGraphBuilder { return node } - private fun addUncaughtExceptionEdgeFrom(node: CFGNode<*>): Int { - val nextExit = exitTargetsForTry.top() - val nextFinally = finallyEnterNodes.topOrNull() - // TODO: this edge is probably redundant if chose `nextExit` - val nextNode = if (nextFinally != null && nextFinally.level > nextExit.level) nextFinally else nextExit - addEdge(node, nextNode, propagateDeadness = false, label = UncaughtExceptionPath) - return nextNode.level - } - - // TODO: these edges are true for literally any node in the graph. Their existence for *some* nodes - // might lead to a false sense of security, but things are broken. This should be some sort of implicit knowledge - // instead of requiring a ton of edges? + // TODO: these edges are true for literally any node in the graph. Their existence for *some* nodes might lead + // to a false sense of security, but things are broken. This should be some sort of implicit knowledge instead + // of requiring a ton of edges? (Some nodes never throw, but calls are never safe, and most useful stuff is calls.) + // var x: Any? // x = "" // try { // x = null - // f() // throws + // listOf(1, 2, 3).single() // x = "" // } catch (e: Throwable) { x.length } // oops - // Just look at `enterTryExpression` - the edges it adds are literally `addExceptionEdgesFrom(tryExpressionEnterNode)`. + // R8 devs say they tried the "implicit knowledge" way but failed and decided to add all the edges - bad sign... private fun addExceptionEdgesFrom(node: CFGNode<*>) { val nextCatch = catchNodes.topOrNull() if (nextCatch != null) { @@ -1076,7 +1084,10 @@ class ControlFlowGraphBuilder { addEdge(node, catchEnterNode, propagateDeadness = false) } } - addUncaughtExceptionEdgeFrom(node) + val nextFinally = finallyEnterNodes.topOrNull() + if (nextFinally != null && nextFinally.level > exitTargetsForTry.top().level) { + addEdge(node, nextFinally, propagateDeadness = false, label = UncaughtExceptionPath) + } } //this is a workaround to make function call dead when call is completed _after_ building its node in the graph diff --git a/compiler/testData/diagnostics/tests/initializedAfterRethrow.fir.kt b/compiler/testData/diagnostics/tests/initializedAfterRethrow.fir.kt new file mode 100644 index 00000000000..1bfc432da32 --- /dev/null +++ b/compiler/testData/diagnostics/tests/initializedAfterRethrow.fir.kt @@ -0,0 +1,223 @@ + +fun foo(): Int = 42 + +object ThrowInTryWithCatch { + private val p: String + + init { + try { + throw Exception() + } catch (e: Exception) { + } + p = "OK" + } +} + +object ThrowInTryWithCatchAndFinally { + private val p: String + + init { + try { + throw Exception() + } catch (e: Exception) { + } finally { + } + p = "OK" + } +} + +object ThrowInFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + } finally { + throw Exception() + } + p = "OK" + } +} + +object RethrowInCatch { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + throw e + } + p = "OK" + } +} + +object RethrowInCatchWithFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + throw e + } finally { + } + p = "OK" + } +} + +object InnerTryWithCatch { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + throw e + } catch (ee: Exception) { + } + } + p = "OK" + } +} + +object InnerTryWithFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + throw e + } finally { + } + } + p = "OK" + } +} + + +object InnerTryWithCatchAndFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + throw e + } catch (ee: Exception) { + } finally { + } + } + p = "OK" + } +} + +object InnerCatch { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } catch (ee: Exception) { + throw ee + } + } + p = "OK" + } +} + +object InnerCatchWithFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } catch (ee: Exception) { + throw ee + } finally { + } + } + p = "OK" + } +} + +object InnerCatchOuterRethrow { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } catch (ee: Exception) { + throw e + } + } + p = "OK" + } +} + +object InnerCatchOuterRethrowWithFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } catch (ee: Exception) { + throw e + } finally { + } + } + p = "OK" + } +} + +object InnerFinally { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } finally { + throw e + } + } + p = "OK" + } +} + +object InnerFinallyWithCatch { + private val p: String + + init { + try { + foo() + } catch (e: Exception) { + try { + foo() + } catch (ee: Exception) { + } finally { + throw e + } + } + p = "OK" + } +} diff --git a/compiler/testData/diagnostics/tests/initializedAfterRethrow.kt b/compiler/testData/diagnostics/tests/initializedAfterRethrow.kt index 72dacac94a3..f4897417874 100644 --- a/compiler/testData/diagnostics/tests/initializedAfterRethrow.kt +++ b/compiler/testData/diagnostics/tests/initializedAfterRethrow.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL fun foo(): Int = 42