From 755c54553afea107b0cd356dfc5ac57ad16f64bc Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 13 Jun 2022 12:15:03 +0200 Subject: [PATCH] FIR CFG: add more KT-44512 related tests --- ...nosisCompilerFirTestdataTestGenerated.java | 6 + ...TouchedTilContractsPhaseTestGenerated.java | 5 + .../resolve/cfg/flowFromInplaceLambda2.dot | 938 ++++++++++++++++++ .../cfg/flowFromInplaceLambda2.fir.txt | 138 +++ .../resolve/cfg/flowFromInplaceLambda2.kt | 78 ++ .../runners/FirDiagnosticTestGenerated.java | 6 + ...DiagnosticsWithLightTreeTestGenerated.java | 6 + 7 files changed, 1177 insertions(+) create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index d0fcfe6cdca..1f4c71760ac 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -1077,6 +1077,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.kt"); } + @Test + @TestMetadata("flowFromInplaceLambda2.kt") + public void testFlowFromInplaceLambda2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt"); + } + @Test @TestMetadata("initBlock.kt") public void testInitBlock() throws Exception { diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 6857f9d352a..9eed385de66 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -928,6 +928,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.kt"); } + @TestMetadata("flowFromInplaceLambda2.kt") + public void testFlowFromInplaceLambda2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt"); + } + @TestMetadata("initBlock.kt") public void testInitBlock() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/initBlock.kt"); diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot new file mode 100644 index 00000000000..1f1c8378ef6 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.dot @@ -0,0 +1,938 @@ +digraph flowFromInplaceLambda2_kt { + graph [nodesep=3] + node [shape=box penwidth=2] + edge [penwidth=2] + + subgraph cluster_0 { + color=red + 0 [label="Enter function foo" style="filled" fillcolor=red]; + subgraph cluster_1 { + color=blue + 1 [label="Enter block"]; + 2 [label="Exit block"]; + } + 3 [label="Exit function foo" style="filled" fillcolor=red]; + } + 0 -> {1}; + 1 -> {2}; + 2 -> {3}; + + subgraph cluster_2 { + color=red + 4 [label="Enter function id" style="filled" fillcolor=red]; + subgraph cluster_3 { + color=blue + 5 [label="Enter block"]; + 6 [label="Access variable R|/x|"]; + 7 [label="Jump: ^id R|/x|"]; + 8 [label="Stub" style="filled" fillcolor=gray]; + 9 [label="Exit block" style="filled" fillcolor=gray]; + } + 10 [label="Exit function id" style="filled" fillcolor=red]; + } + 4 -> {5}; + 5 -> {6}; + 6 -> {7}; + 7 -> {10}; + 7 -> {8} [style=dotted]; + 8 -> {9} [style=dotted]; + 9 -> {10} [style=dotted]; + + subgraph cluster_4 { + color=red + 11 [label="Enter function n" style="filled" fillcolor=red]; + subgraph cluster_5 { + color=blue + 12 [label="Enter block"]; + 13 [label="Const: Null(null)"]; + 14 [label="Jump: ^n Null(null)"]; + 15 [label="Stub" style="filled" fillcolor=gray]; + 16 [label="Exit block" style="filled" fillcolor=gray]; + } + 17 [label="Exit function n" style="filled" fillcolor=red]; + } + 11 -> {12}; + 12 -> {13}; + 13 -> {14}; + 14 -> {17}; + 14 -> {15} [style=dotted]; + 15 -> {16} [style=dotted]; + 16 -> {17} [style=dotted]; + + subgraph cluster_6 { + color=red + 18 [label="Enter function someCompletedCall" style="filled" fillcolor=red]; + subgraph cluster_7 { + color=blue + 19 [label="Enter block"]; + 20 [label="Access variable R|/arg|"]; + 21 [label="Jump: ^someCompletedCall R|/arg|"]; + 22 [label="Stub" style="filled" fillcolor=gray]; + 23 [label="Exit block" style="filled" fillcolor=gray]; + } + 24 [label="Exit function someCompletedCall" style="filled" fillcolor=red]; + } + 18 -> {19}; + 19 -> {20}; + 20 -> {21}; + 21 -> {24}; + 21 -> {22} [style=dotted]; + 22 -> {23} [style=dotted]; + 23 -> {24} [style=dotted]; + + subgraph cluster_8 { + color=red + 25 [label="Enter function test1" style="filled" fillcolor=red]; + subgraph cluster_9 { + color=blue + 26 [label="Enter block"]; + 27 [label="Postponed enter to lambda"]; + subgraph cluster_10 { + color=blue + 41 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_11 { + color=blue + 42 [label="Enter block"]; + 43 [label="Access variable R|/x|"]; + 44 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 45 [label="Function call: R|/n|()"]; + 46 [label="Exit block"]; + } + 47 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 28 [label="Postponed exit from lambda"]; + 29 [label="Function call: R|kotlin/run|(...)"]; + 30 [label="Function call: R|/id|(...)"]; + 31 [label="Const: Int(1)"]; + 32 [label="Postponed enter to lambda"]; + subgraph cluster_12 { + color=blue + 48 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_13 { + color=blue + 49 [label="Enter block"]; + 50 [label="Access variable R|/x|"]; + 51 [label="Access variable #"]; + 52 [label="Const: Int(123)"]; + 53 [label="Exit block"]; + } + 54 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 33 [label="Postponed exit from lambda"]; + 34 [label="Function call: R|kotlin/run|(...)"]; + 35 [label="Call arguments union" style="filled" fillcolor=yellow]; + 36 [label="Function call: R|/foo|(...)"]; + 37 [label="Access variable R|/x|"]; + 38 [label="Access variable R|kotlin/String.length|"]; + 39 [label="Exit block"]; + } + 40 [label="Exit function test1" style="filled" fillcolor=red]; + } + 25 -> {26}; + 26 -> {27}; + 27 -> {41}; + 27 -> {28} [color=red]; + 27 -> {41} [style=dashed]; + 28 -> {29}; + 29 -> {30}; + 30 -> {31}; + 31 -> {32}; + 32 -> {48}; + 32 -> {33} [color=red]; + 32 -> {48} [style=dashed]; + 33 -> {34}; + 34 -> {35}; + 35 -> {36}; + 36 -> {37}; + 37 -> {38}; + 38 -> {39}; + 39 -> {40}; + 41 -> {42}; + 42 -> {43}; + 43 -> {44}; + 44 -> {45}; + 45 -> {46}; + 46 -> {47}; + 47 -> {35} [color=red]; + 47 -> {28} [color=green]; + 48 -> {49}; + 49 -> {50}; + 50 -> {51}; + 51 -> {52}; + 52 -> {53}; + 53 -> {54}; + 54 -> {35} [color=red]; + 54 -> {33} [color=green]; + + subgraph cluster_14 { + color=red + 55 [label="Enter function test2" style="filled" fillcolor=red]; + subgraph cluster_15 { + color=blue + 56 [label="Enter block"]; + 57 [label="Postponed enter to lambda"]; + subgraph cluster_16 { + color=blue + 73 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_17 { + color=blue + 74 [label="Enter block"]; + 75 [label="Access variable R|/x|"]; + 76 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 77 [label="Function call: R|/n|()"]; + 78 [label="Exit block"]; + } + 79 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 58 [label="Postponed exit from lambda"]; + 59 [label="Function call: R|kotlin/run|(...)"]; + 60 [label="Function call: R|/id|(...)"]; + 61 [label="Const: Int(1)"]; + 62 [label="Call arguments union" style="filled" fillcolor=yellow]; + 63 [label="Function call: R|/someCompletedCall|(...)"]; + 64 [label="Postponed enter to lambda"]; + subgraph cluster_18 { + color=blue + 80 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_19 { + color=blue + 81 [label="Enter block"]; + 82 [label="Access variable R|/x|"]; + 83 [label="Access variable R|kotlin/String.length|"]; + 84 [label="Const: Int(123)"]; + 85 [label="Exit block"]; + } + 86 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 65 [label="Postponed exit from lambda"]; + 66 [label="Function call: R|kotlin/run|(...)"]; + 67 [label="Call arguments union" style="filled" fillcolor=yellow]; + 68 [label="Function call: R|/foo|(...)"]; + 69 [label="Access variable R|/x|"]; + 70 [label="Access variable R|kotlin/String.length|"]; + 71 [label="Exit block"]; + } + 72 [label="Exit function test2" style="filled" fillcolor=red]; + } + 55 -> {56}; + 56 -> {57}; + 57 -> {73}; + 57 -> {58} [color=red]; + 57 -> {73} [style=dashed]; + 58 -> {59}; + 59 -> {60}; + 60 -> {61}; + 61 -> {62}; + 62 -> {63}; + 63 -> {64}; + 64 -> {80}; + 64 -> {65} [color=red]; + 64 -> {80} [style=dashed]; + 65 -> {66}; + 66 -> {67}; + 67 -> {68}; + 68 -> {69}; + 69 -> {70}; + 70 -> {71}; + 71 -> {72}; + 73 -> {74}; + 74 -> {75}; + 75 -> {76}; + 76 -> {77}; + 77 -> {78}; + 78 -> {79}; + 79 -> {62} [color=red]; + 79 -> {58} [color=green]; + 80 -> {81}; + 81 -> {82}; + 82 -> {83}; + 83 -> {84}; + 84 -> {85}; + 85 -> {86}; + 86 -> {67} [color=red]; + 86 -> {65} [color=green]; + + subgraph cluster_20 { + color=red + 87 [label="Enter function test3" style="filled" fillcolor=red]; + subgraph cluster_21 { + color=blue + 88 [label="Enter block"]; + 89 [label="Postponed enter to lambda"]; + subgraph cluster_22 { + color=blue + 119 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_23 { + color=blue + 120 [label="Enter block"]; + 121 [label="Access variable R|/x|"]; + 122 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 123 [label="Function call: R|/n|()"]; + 124 [label="Exit block"]; + } + 125 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 90 [label="Postponed exit from lambda"]; + 91 [label="Function call: R|kotlin/run|(...)"]; + 92 [label="Function call: R|/id|(...)"]; + subgraph cluster_24 { + color=blue + 93 [label="Enter when"]; + subgraph cluster_25 { + color=blue + 94 [label="Enter when branch condition "]; + 95 [label="Const: Boolean(true)"]; + 96 [label="Exit when branch condition"]; + } + subgraph cluster_26 { + color=blue + 97 [label="Enter when branch condition else"]; + 98 [label="Exit when branch condition"]; + } + 99 [label="Enter when branch result"]; + subgraph cluster_27 { + color=blue + 100 [label="Enter block"]; + 101 [label="Const: Int(2)"]; + 102 [label="Exit block"]; + } + 103 [label="Exit when branch result"]; + 104 [label="Enter when branch result"]; + subgraph cluster_28 { + color=blue + 105 [label="Enter block"]; + 106 [label="Const: Int(1)"]; + 107 [label="Exit block"]; + } + 108 [label="Exit when branch result"]; + 109 [label="Exit when"]; + } + 110 [label="Postponed enter to lambda"]; + subgraph cluster_29 { + color=blue + 126 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_30 { + color=blue + 127 [label="Enter block"]; + 128 [label="Access variable R|/x|"]; + 129 [label="Access variable #"]; + 130 [label="Const: Int(123)"]; + 131 [label="Exit block"]; + } + 132 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 111 [label="Postponed exit from lambda"]; + 112 [label="Function call: R|kotlin/run|(...)"]; + 113 [label="Call arguments union" style="filled" fillcolor=yellow]; + 114 [label="Function call: R|/foo|(...)"]; + 115 [label="Access variable R|/x|"]; + 116 [label="Access variable #"]; + 117 [label="Exit block"]; + } + 118 [label="Exit function test3" style="filled" fillcolor=red]; + } + 87 -> {88}; + 88 -> {89}; + 89 -> {119}; + 89 -> {90} [color=red]; + 89 -> {119} [style=dashed]; + 90 -> {91}; + 91 -> {92}; + 92 -> {93}; + 93 -> {94}; + 94 -> {95}; + 95 -> {96}; + 96 -> {104 97}; + 97 -> {98}; + 98 -> {99}; + 99 -> {100}; + 100 -> {101}; + 101 -> {102}; + 102 -> {103}; + 103 -> {109}; + 104 -> {105}; + 105 -> {106}; + 106 -> {107}; + 107 -> {108}; + 108 -> {109}; + 109 -> {110}; + 110 -> {126}; + 110 -> {111} [color=red]; + 110 -> {126} [style=dashed]; + 111 -> {112}; + 112 -> {113}; + 113 -> {114}; + 114 -> {115}; + 115 -> {116}; + 116 -> {117}; + 117 -> {118}; + 119 -> {120}; + 120 -> {121}; + 121 -> {122}; + 122 -> {123}; + 123 -> {124}; + 124 -> {125}; + 125 -> {90} [color=green]; + 126 -> {127}; + 127 -> {128}; + 128 -> {129}; + 129 -> {130}; + 130 -> {131}; + 131 -> {132}; + 132 -> {113} [color=red]; + 132 -> {111} [color=green]; + + subgraph cluster_31 { + color=red + 133 [label="Enter function test4" style="filled" fillcolor=red]; + subgraph cluster_32 { + color=blue + 134 [label="Enter block"]; + 135 [label="Access variable R|/x|"]; + 136 [label="Variable declaration: lvar p: R|kotlin/String?|"]; + subgraph cluster_33 { + color=blue + 137 [label="Enter when"]; + subgraph cluster_34 { + color=blue + 138 [label="Enter when branch condition "]; + 139 [label="Access variable R|/p|"]; + 140 [label="Const: Null(null)"]; + 141 [label="Equality operator !="]; + 142 [label="Exit when branch condition"]; + } + 143 [label="Synthetic else branch"]; + 144 [label="Enter when branch result"]; + subgraph cluster_35 { + color=blue + 145 [label="Enter block"]; + subgraph cluster_36 { + color=blue + 146 [label="Enter when"]; + subgraph cluster_37 { + color=blue + 147 [label="Enter when branch condition "]; + 148 [label="Const: Boolean(true)"]; + 149 [label="Exit when branch condition"]; + } + subgraph cluster_38 { + color=blue + 150 [label="Enter when branch condition else"]; + 151 [label="Exit when branch condition"]; + } + 152 [label="Enter when branch result"]; + subgraph cluster_39 { + color=blue + 153 [label="Enter block"]; + 154 [label="Postponed enter to lambda"]; + subgraph cluster_40 { + color=blue + 188 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_41 { + color=blue + 189 [label="Enter block"]; + 190 [label="Function call: R|/n|()"]; + 191 [label="Exit block"]; + } + 192 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 155 [label="Postponed exit from lambda"]; + 156 [label="Function call: R|kotlin/run|(...)"]; + 157 [label="Exit block"]; + } + 158 [label="Exit when branch result"]; + 159 [label="Enter when branch result"]; + subgraph cluster_42 { + color=blue + 160 [label="Enter block"]; + 161 [label="Postponed enter to lambda"]; + subgraph cluster_43 { + color=blue + 181 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_44 { + color=blue + 182 [label="Enter block"]; + 183 [label="Const: Null(null)"]; + 184 [label="Assignment: R|/p|"]; + 185 [label="Function call: R|/n|()"]; + 186 [label="Exit block"]; + } + 187 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 162 [label="Postponed exit from lambda"]; + 163 [label="Function call: R|kotlin/run|(...)"]; + 164 [label="Exit block"]; + } + 165 [label="Exit when branch result"]; + 166 [label="Exit when"]; + } + 167 [label="Function call: R|/id|(...)"]; + 168 [label="Const: Int(1)"]; + 169 [label="Postponed enter to lambda"]; + subgraph cluster_45 { + color=blue + 193 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_46 { + color=blue + 194 [label="Enter block"]; + 195 [label="Access variable R|/p|"]; + 196 [label="Access variable R|kotlin/String.length|"]; + 197 [label="Const: Int(123)"]; + 198 [label="Exit block"]; + } + 199 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 170 [label="Postponed exit from lambda"]; + 171 [label="Function call: R|kotlin/run|(...)"]; + 172 [label="Call arguments union" style="filled" fillcolor=yellow]; + 173 [label="Function call: R|/foo|(...)"]; + 174 [label="Access variable R|/p|"]; + 175 [label="Access variable R|kotlin/String.length|"]; + 176 [label="Exit block"]; + } + 177 [label="Exit when branch result"]; + 178 [label="Exit when"]; + } + 179 [label="Exit block"]; + } + 180 [label="Exit function test4" style="filled" fillcolor=red]; + } + 133 -> {134}; + 134 -> {135}; + 135 -> {136}; + 136 -> {137}; + 137 -> {138}; + 138 -> {139}; + 139 -> {140}; + 140 -> {141}; + 141 -> {142}; + 142 -> {144 143}; + 143 -> {178}; + 144 -> {145}; + 145 -> {146}; + 146 -> {147}; + 147 -> {148}; + 148 -> {149}; + 149 -> {159 150}; + 150 -> {151}; + 151 -> {152}; + 152 -> {153}; + 153 -> {154}; + 154 -> {188}; + 154 -> {155} [color=red]; + 154 -> {188} [style=dashed]; + 155 -> {156}; + 156 -> {157}; + 157 -> {158}; + 158 -> {166}; + 159 -> {160}; + 160 -> {161}; + 161 -> {181}; + 161 -> {162} [color=red]; + 161 -> {181} [style=dashed]; + 162 -> {163}; + 163 -> {164}; + 164 -> {165}; + 165 -> {166}; + 166 -> {167}; + 167 -> {168}; + 168 -> {169}; + 169 -> {193}; + 169 -> {170} [color=red]; + 169 -> {193} [style=dashed]; + 170 -> {171}; + 171 -> {172}; + 172 -> {173}; + 173 -> {174}; + 174 -> {175}; + 175 -> {176}; + 176 -> {177}; + 177 -> {178}; + 178 -> {179}; + 179 -> {180}; + 181 -> {182}; + 182 -> {183}; + 183 -> {184}; + 184 -> {185}; + 185 -> {186}; + 186 -> {187}; + 187 -> {162} [color=green]; + 188 -> {189}; + 189 -> {190}; + 190 -> {191}; + 191 -> {192}; + 192 -> {155} [color=green]; + 193 -> {194}; + 194 -> {195}; + 195 -> {196}; + 196 -> {197}; + 197 -> {198}; + 198 -> {199}; + 199 -> {172} [color=red]; + 199 -> {170} [color=green]; + + subgraph cluster_47 { + color=red + 200 [label="Enter function test5" style="filled" fillcolor=red]; + subgraph cluster_48 { + color=blue + 201 [label="Enter block"]; + 202 [label="Access variable R|/y|"]; + 203 [label="Enter safe call"]; + 204 [label="Postponed enter to lambda"]; + subgraph cluster_49 { + color=blue + 218 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_50 { + color=blue + 219 [label="Enter block"]; + 220 [label="Access variable R|/x|"]; + 221 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 222 [label="Function call: R|/n|()"]; + 223 [label="Exit block"]; + } + 224 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 205 [label="Postponed exit from lambda"]; + 206 [label="Function call: $subj$.R|kotlin/let|(...)"]; + 207 [label="Exit safe call"]; + 208 [label="Const: Int(1)"]; + 209 [label="Postponed enter to lambda"]; + subgraph cluster_51 { + color=blue + 225 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_52 { + color=blue + 226 [label="Enter block"]; + 227 [label="Const: String()"]; + 228 [label="Exit block"]; + } + 229 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 210 [label="Postponed exit from lambda"]; + 211 [label="Function call: R|kotlin/run|(...)"]; + 212 [label="Call arguments union" style="filled" fillcolor=yellow]; + 213 [label="Function call: R|/foo|(...)"]; + 214 [label="Access variable R|/x|"]; + 215 [label="Access variable R|kotlin/String.length|"]; + 216 [label="Exit block"]; + } + 217 [label="Exit function test5" style="filled" fillcolor=red]; + } + 200 -> {201}; + 201 -> {202}; + 202 -> {203 207}; + 203 -> {204}; + 204 -> {218}; + 204 -> {205} [color=red]; + 204 -> {218} [style=dashed]; + 205 -> {206}; + 206 -> {207}; + 207 -> {208}; + 208 -> {209}; + 209 -> {225}; + 209 -> {210} [color=red]; + 209 -> {225} [style=dashed]; + 210 -> {211}; + 211 -> {212}; + 212 -> {213}; + 213 -> {214}; + 214 -> {215}; + 215 -> {216}; + 216 -> {217}; + 218 -> {219}; + 219 -> {220}; + 220 -> {221}; + 221 -> {222}; + 222 -> {223}; + 223 -> {224}; + 224 -> {212} [color=red]; + 224 -> {205} [color=green]; + 225 -> {226}; + 226 -> {227}; + 227 -> {228}; + 228 -> {229}; + 229 -> {212} [color=red]; + 229 -> {210} [color=green]; + + subgraph cluster_53 { + color=red + 230 [label="Enter function test6" style="filled" fillcolor=red]; + subgraph cluster_54 { + color=blue + 231 [label="Enter block"]; + subgraph cluster_55 { + color=blue + 232 [label="Enter when"]; + subgraph cluster_56 { + color=blue + 233 [label="Enter when branch condition "]; + 234 [label="Const: Boolean(true)"]; + 235 [label="Exit when branch condition"]; + } + subgraph cluster_57 { + color=blue + 236 [label="Enter when branch condition else"]; + 237 [label="Exit when branch condition"]; + } + 238 [label="Enter when branch result"]; + subgraph cluster_58 { + color=blue + 239 [label="Enter block"]; + 240 [label="Postponed enter to lambda"]; + subgraph cluster_59 { + color=blue + 271 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_60 { + color=blue + 272 [label="Enter block"]; + 273 [label="Access variable R|/x|"]; + 274 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 275 [label="Function call: R|/n|()"]; + 276 [label="Exit block"]; + } + 277 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 241 [label="Postponed exit from lambda"]; + 242 [label="Function call: R|kotlin/run|(...)"]; + 243 [label="Exit block"]; + } + 244 [label="Exit when branch result"]; + 245 [label="Enter when branch result"]; + subgraph cluster_61 { + color=blue + 246 [label="Enter block"]; + 247 [label="Postponed enter to lambda"]; + subgraph cluster_62 { + color=blue + 264 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_63 { + color=blue + 265 [label="Enter block"]; + 266 [label="Access variable R|/x|"]; + 267 [label="Type operator: (R|/x| as R|kotlin/String|)"]; + 268 [label="Function call: R|/n|()"]; + 269 [label="Exit block"]; + } + 270 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 248 [label="Postponed exit from lambda"]; + 249 [label="Function call: R|kotlin/run|(...)"]; + 250 [label="Exit block"]; + } + 251 [label="Exit when branch result"]; + 252 [label="Exit when"]; + } + 253 [label="Function call: R|/id|(...)"]; + 254 [label="Const: Int(1)"]; + 255 [label="Postponed enter to lambda"]; + subgraph cluster_64 { + color=blue + 278 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_65 { + color=blue + 279 [label="Enter block"]; + 280 [label="Access variable R|/x|"]; + 281 [label="Access variable #"]; + 282 [label="Const: Int(123)"]; + 283 [label="Exit block"]; + } + 284 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 256 [label="Postponed exit from lambda"]; + 257 [label="Function call: R|kotlin/run|(...)"]; + 258 [label="Call arguments union" style="filled" fillcolor=yellow]; + 259 [label="Function call: R|/foo|(...)"]; + 260 [label="Access variable R|/x|"]; + 261 [label="Access variable #"]; + 262 [label="Exit block"]; + } + 263 [label="Exit function test6" style="filled" fillcolor=red]; + } + 230 -> {231}; + 231 -> {232}; + 232 -> {233}; + 233 -> {234}; + 234 -> {235}; + 235 -> {245 236}; + 236 -> {237}; + 237 -> {238}; + 238 -> {239}; + 239 -> {240}; + 240 -> {271}; + 240 -> {241} [color=red]; + 240 -> {271} [style=dashed]; + 241 -> {242}; + 242 -> {243}; + 243 -> {244}; + 244 -> {252}; + 245 -> {246}; + 246 -> {247}; + 247 -> {264}; + 247 -> {248} [color=red]; + 247 -> {264} [style=dashed]; + 248 -> {249}; + 249 -> {250}; + 250 -> {251}; + 251 -> {252}; + 252 -> {253}; + 253 -> {254}; + 254 -> {255}; + 255 -> {278}; + 255 -> {256} [color=red]; + 255 -> {278} [style=dashed]; + 256 -> {257}; + 257 -> {258}; + 258 -> {259}; + 259 -> {260}; + 260 -> {261}; + 261 -> {262}; + 262 -> {263}; + 264 -> {265}; + 265 -> {266}; + 266 -> {267}; + 267 -> {268}; + 268 -> {269}; + 269 -> {270}; + 270 -> {248} [color=green]; + 271 -> {272}; + 272 -> {273}; + 273 -> {274}; + 274 -> {275}; + 275 -> {276}; + 276 -> {277}; + 277 -> {241} [color=green]; + 278 -> {279}; + 279 -> {280}; + 280 -> {281}; + 281 -> {282}; + 282 -> {283}; + 283 -> {284}; + 284 -> {258} [color=red]; + 284 -> {256} [color=green]; + + subgraph cluster_66 { + color=red + 285 [label="Enter function test7" style="filled" fillcolor=red]; + subgraph cluster_67 { + color=blue + 286 [label="Enter block"]; + 287 [label="Access variable R|/x|"]; + 288 [label="Variable declaration: lvar p: R|kotlin/String?|"]; + subgraph cluster_68 { + color=blue + 289 [label="Enter when"]; + subgraph cluster_69 { + color=blue + 290 [label="Enter when branch condition "]; + 291 [label="Access variable R|/p|"]; + 292 [label="Const: Null(null)"]; + 293 [label="Equality operator !="]; + 294 [label="Exit when branch condition"]; + } + 295 [label="Synthetic else branch"]; + 296 [label="Enter when branch result"]; + subgraph cluster_70 { + color=blue + 297 [label="Enter block"]; + 298 [label="Postponed enter to lambda"]; + subgraph cluster_71 { + color=blue + 316 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_72 { + color=blue + 317 [label="Enter block"]; + 318 [label="Const: Null(null)"]; + 319 [label="Assignment: R|/p|"]; + 320 [label="Function call: R|/n|()"]; + 321 [label="Exit block"]; + } + 322 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 299 [label="Postponed exit from lambda"]; + 300 [label="Function call: R|kotlin/run|(...)"]; + 301 [label="Function call: R|/id|(...)"]; + 302 [label="Const: Int(1)"]; + 303 [label="Postponed enter to lambda"]; + subgraph cluster_73 { + color=blue + 323 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + subgraph cluster_74 { + color=blue + 324 [label="Enter block"]; + 325 [label="Access variable R|/p|"]; + 326 [label="Access variable R|kotlin/String.length|"]; + 327 [label="Const: Int(123)"]; + 328 [label="Exit block"]; + } + 329 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + } + 304 [label="Postponed exit from lambda"]; + 305 [label="Function call: R|kotlin/run|(...)"]; + 306 [label="Call arguments union" style="filled" fillcolor=yellow]; + 307 [label="Function call: R|/foo|(...)"]; + 308 [label="Access variable R|/p|"]; + 309 [label="Stub" style="filled" fillcolor=gray]; + 310 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray]; + 311 [label="Exit block" style="filled" fillcolor=gray]; + } + 312 [label="Exit when branch result" style="filled" fillcolor=gray]; + 313 [label="Exit when"]; + } + 314 [label="Exit block"]; + } + 315 [label="Exit function test7" style="filled" fillcolor=red]; + } + 285 -> {286}; + 286 -> {287}; + 287 -> {288}; + 288 -> {289}; + 289 -> {290}; + 290 -> {291}; + 291 -> {292}; + 292 -> {293}; + 293 -> {294}; + 294 -> {296 295}; + 295 -> {313}; + 296 -> {297}; + 297 -> {298}; + 298 -> {316}; + 298 -> {299} [color=red]; + 298 -> {316} [style=dashed]; + 299 -> {300}; + 300 -> {301}; + 301 -> {302}; + 302 -> {303}; + 303 -> {323}; + 303 -> {304} [color=red]; + 303 -> {323} [style=dashed]; + 304 -> {305}; + 305 -> {306}; + 306 -> {307}; + 307 -> {308}; + 308 -> {315} [label=onUncaughtException]; + 308 -> {309} [style=dotted]; + 309 -> {310} [style=dotted]; + 310 -> {311} [style=dotted]; + 311 -> {312} [style=dotted]; + 312 -> {313} [style=dotted]; + 313 -> {314}; + 314 -> {315}; + 316 -> {317}; + 317 -> {318}; + 318 -> {319}; + 319 -> {320}; + 320 -> {321}; + 321 -> {322}; + 322 -> {306} [color=red]; + 322 -> {299} [color=green]; + 323 -> {324}; + 324 -> {325}; + 325 -> {326}; + 326 -> {327}; + 327 -> {328}; + 328 -> {329}; + 329 -> {306} [color=red]; + 329 -> {304} [color=green]; + +} diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.fir.txt new file mode 100644 index 00000000000..defc6d88aa3 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.fir.txt @@ -0,0 +1,138 @@ +FILE: flowFromInplaceLambda2.kt + public final fun foo(x: R|T?|, i: R|kotlin/Int|, y: R|T|): R|kotlin/Unit| { + } + public final fun id(x: R|T|): R|T| { + ^id R|/x| + } + public final fun n(): R|T?| { + ^n Null(null) + } + public final fun someCompletedCall(arg: R|kotlin/Int|): R|kotlin/Int| { + ^someCompletedCall R|/arg| + } + public final fun test1(x: R|kotlin/String?|): R|kotlin/Unit| { + R|/foo|(R|/id|(R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + )), Int(1), R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/x|.# + ^ Int(123) + } + )) + R|/x|.R|kotlin/String.length| + } + public final fun test2(x: R|kotlin/String?|): R|kotlin/Unit| { + R|/foo|(R|/id|(R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + )), R|/someCompletedCall|(Int(1)), R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/x|.R|kotlin/String.length| + ^ Int(123) + } + )) + R|/x|.R|kotlin/String.length| + } + public final fun test3(x: R|kotlin/String?|): R|kotlin/Unit| { + R|/foo|(R|/id|(R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + )), when () { + Boolean(true) -> { + Int(1) + } + else -> { + Int(2) + } + } + , R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/x|.# + ^ Int(123) + } + )) + R|/x|.# + } + public final fun test4(x: R|kotlin/String?|): R|kotlin/Unit| { + lvar p: R|kotlin/String?| = R|/x| + when () { + !=(R|/p|, Null(null)) -> { + R|/foo|(R|/id|(when () { + Boolean(true) -> { + R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + R|/p| = Null(null) + ^ R|/n|() + } + ) + } + else -> { + R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + ^ R|/n|() + } + ) + } + } + ), Int(1), R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/p|.R|kotlin/String.length| + ^ Int(123) + } + )) + R|/p|.R|kotlin/String.length| + } + } + + } + public final fun test5(x: R|kotlin/String?|, y: R|kotlin/String?|): R|kotlin/Unit| { + R|/foo|(R|/y|?.{ $subj$.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + ) }, Int(1), R|kotlin/run|( = run@fun (): R|kotlin/String| { + ^ String() + } + )) + R|/x|.R|kotlin/String.length| + } + public final fun test6(x: R|kotlin/String?|): R|kotlin/Unit| { + R|/foo|(R|/id|(when () { + Boolean(true) -> { + R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + ) + } + else -> { + R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + (R|/x| as R|kotlin/String|) + ^ R|/n|() + } + ) + } + } + ), Int(1), R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/x|.# + ^ Int(123) + } + )) + R|/x|.# + } + public final fun test7(x: R|kotlin/String?|): R|kotlin/Unit| { + lvar p: R|kotlin/String?| = R|/x| + when () { + !=(R|/p|, Null(null)) -> { + R|/foo|(R|/id|(R|kotlin/run|( = run@fun (): R|kotlin/Nothing?| { + R|/p| = Null(null) + ^ R|/n|() + } + )), Int(1), R|kotlin/run|( = run@fun (): R|kotlin/Int| { + R|/p|.R|kotlin/String.length| + ^ Int(123) + } + )) + R|/p|.R|kotlin/String.length| + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt new file mode 100644 index 00000000000..b7fb98dd00b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt @@ -0,0 +1,78 @@ +// !DUMP_CFG + +fun foo(x: T?, i: Int, y: T) {} + +fun id(x: T): T = x + +fun n(): T? = null + +fun someCompletedCall(arg: Int) = arg + +fun test1(x: String?) { + foo( + id(run { x as String; n() }), + 1, + run { x.length; 123 } // Bad (resolution order undefined) + ) + x.length // OK (x as String unconditional) +} + +fun test2(x: String?) { + foo( + id(run { x as String; n() }), + someCompletedCall(1), + run { x.length; 123 } // Bad (resolution order undefined) + ) + x.length // OK (x as String unconditional) +} + +fun test3(x: String?) { + foo( + id(run { x as String; n() }), + if (true) 1 else 2, + run { x.length; 123 } // Bad (resolution order undefined) + ) + x.length // OK (x as String unconditional) +} + +fun test4(x: String?) { + var p = x + if (p != null) { + foo( + id(if (true) run { p = null; n() } else run { n() }), + 1, + run { p.length; 123 } // Bad (p = null possible) + ) + p.length // Bad (p = null possible) + } +} + +fun test5(x: String?, y: String?) { + foo( + y?.let { x as String; n() }, + 1, + run { "" } + ) + x.length // Bad (x as String conditional) +} + +fun test6(x: String?) { + foo( + id(if (true) run { x as String; n() } else run { x as String; n() }), + 1, + run { x.length; 123 } // Bad (resolution order undefined) + ) + x.length // OK (x as String in both branches) +} + +fun test7(x: String?) { + var p = x + if (p != null) { + foo( + id(run { p = null; n() }), + 1, + run { p.length; 123 } // Bad (p = null) + ) + p.length // Bad (p = null) + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 5e5dd2ae73b..c673d0d18cd 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -1077,6 +1077,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.kt"); } + @Test + @TestMetadata("flowFromInplaceLambda2.kt") + public void testFlowFromInplaceLambda2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt"); + } + @Test @TestMetadata("initBlock.kt") public void testInitBlock() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index f0e03168775..69a273f10df 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1077,6 +1077,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.kt"); } + @Test + @TestMetadata("flowFromInplaceLambda2.kt") + public void testFlowFromInplaceLambda2() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda2.kt"); + } + @Test @TestMetadata("initBlock.kt") public void testInitBlock() throws Exception {