From 6d9f02cfc6efb613864de2df25ae0dcf33f96ef6 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Tue, 30 Mar 2021 13:29:25 +0200 Subject: [PATCH] [JVM_IR] Fix range of locals in connection with finally blocks. For code such as: ``` try { var y = "y" for (i in 0 until 1) { return y } } finally { println("finally") } ``` The local variables `y` and `i` ended up covering the finally block as well in the debugger. This change splits the range of the locals so that they do not cover the finally block. This change does not change the inliner to do similar transformations, so the range of locals is still wrong win finally blocks when inlined into an inline function. Added a failing test to that effect. --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../backend/jvm/codegen/ExpressionCodegen.kt | 46 +++++++++++++++-- .../nonLocalReturnInTryFinally.kt | 14 ++++++ .../debug/localVariables/tryFinally.kt | 28 +++++++++++ .../debug/localVariables/tryFinally2.kt | 35 +++++++++++++ .../debug/localVariables/tryFinally3.kt | 38 ++++++++++++++ .../debug/localVariables/tryFinally4.kt | 49 +++++++++++++++++++ .../debug/localVariables/tryFinally5.kt | 48 ++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../IrLocalVariableTestGenerated.java | 30 ++++++++++++ .../LocalVariableTestGenerated.java | 30 ++++++++++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 ++ .../IrJsCodegenBoxTestGenerated.java | 5 ++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++ 16 files changed, 351 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt create mode 100644 compiler/testData/debug/localVariables/tryFinally.kt create mode 100644 compiler/testData/debug/localVariables/tryFinally2.kt create mode 100644 compiler/testData/debug/localVariables/tryFinally3.kt create mode 100644 compiler/testData/debug/localVariables/tryFinally4.kt create mode 100644 compiler/testData/debug/localVariables/tryFinally5.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index c015b111e89..71786b1f76b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -8659,6 +8659,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @Test + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @Test @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 397f0b499c2..722472a11aa 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -70,7 +70,9 @@ import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import java.util.* -sealed class ExpressionInfo +sealed class ExpressionInfo { + var blockInfo: BlockInfo? = null +} class LoopInfo(val loop: IrLoop, val continueLabel: Label, val breakLabel: Label) : ExpressionInfo() @@ -89,11 +91,12 @@ class BlockInfo(val parent: BlockInfo? = null) { fun hasFinallyBlocks(): Boolean = infos.firstIsInstanceOrNull() != null internal inline fun withBlock(info: T, f: (T) -> R): R { + info.blockInfo = this infos.add(info) try { return f(info) } finally { - infos.pop() + infos.pop().blockInfo = null } } @@ -110,7 +113,11 @@ class BlockInfo(val parent: BlockInfo? = null) { } } -class VariableInfo(val declaration: IrVariable, val index: Int, val type: Type, val startLabel: Label) +class Gap(val start: Label, val end: Label) + +class VariableInfo(val declaration: IrVariable, val index: Int, val type: Type, val startLabel: Label) { + val gaps = mutableListOf() +} class ExpressionCodegen( val irFunction: IrFunction, @@ -384,7 +391,12 @@ class ExpressionCodegen( private fun writeLocalVariablesInTable(info: BlockInfo, endLabel: Label) { info.variables.forEach { if (it.declaration.isVisibleInLVT) { - mv.visitLocalVariable(it.declaration.name.asString(), it.type.descriptor, null, it.startLabel, endLabel, it.index) + var start = it.startLabel + for (gap in it.gaps) { + mv.visitLocalVariable(it.declaration.name.asString(), it.type.descriptor, null, start, gap.start, it.index) + start = gap.end + } + mv.visitLocalVariable(it.declaration.name.asString(), it.type.descriptor, null, start, endLabel, it.index) } } @@ -393,6 +405,23 @@ class ExpressionCodegen( } } + private fun addLocalVariableGapsForFinallyBlocks( + info: BlockInfo, + tryWithFinallyInfo: TryWithFinallyInfo, + gapStart: Label, + restartLabel: Label + ) { + var current: BlockInfo? = info + while (current != null && current != tryWithFinallyInfo.blockInfo) { + for (variable in current.variables) { + if (variable.declaration.isVisibleInLVT) { + variable.gaps.add(Gap(gapStart, restartLabel)) + } + } + current = current.parent + } + } + private fun visitStatementContainer(container: IrStatementContainer, data: BlockInfo) = container.statements.fold(unitValue) { prev, exp -> prev.discard() @@ -1210,6 +1239,7 @@ class ExpressionCodegen( nestedTryWithoutFinally: MutableList = arrayListOf() ) { val gapStart = markNewLinkedLabel() + finallyDepth++ if (isFinallyMarkerRequired()) { generateFinallyMarker(mv, finallyDepth, true) @@ -1223,7 +1253,13 @@ class ExpressionCodegen( tryWithFinallyInfo.onExit.markLineNumber(startOffset = false) mv.goTo(tryCatchBlockEnd) } - val gapEnd = afterJumpLabel ?: markNewLabel() + + // Split the local variables for the blocks on the way to the finally. Variables introduced in these blocks do not + // cover the finally block code. + val endOfFinallyCode = markNewLinkedLabel() + addLocalVariableGapsForFinallyBlocks(data, tryWithFinallyInfo, gapStart, endOfFinallyCode) + + val gapEnd = afterJumpLabel ?: endOfFinallyCode tryWithFinallyInfo.gaps.add(gapStart to gapEnd) if (state.languageVersionSettings.supportsFeature(LanguageFeature.ProperFinally)) { for (it in nestedTryWithoutFinally) { diff --git a/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt new file mode 100644 index 00000000000..d20b60c4bef --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt @@ -0,0 +1,14 @@ +inline fun g(block: () -> Unit): Unit = block() + +fun box(): String { + try { + for (c in emptyArray()) { + g { + for (d in emptyArray()) { + return "Fail" + } + } + } + } finally {} + return "OK" +} diff --git a/compiler/testData/debug/localVariables/tryFinally.kt b/compiler/testData/debug/localVariables/tryFinally.kt new file mode 100644 index 00000000000..dd2acfb46f5 --- /dev/null +++ b/compiler/testData/debug/localVariables/tryFinally.kt @@ -0,0 +1,28 @@ +// FILE: test.kt +fun box() { + var result = "" + for (x in listOf("A", "B")) { + try { + val y = "y" + result += y + break + } + finally { + val z = "z" + result += z + } + } +} + +// The old backend has the local y covering the finally block as well. +// IGNORE_BACKEND: JVM + +// LOCAL VARIABLES +// test.kt:3 box: +// test.kt:4 box: result:java.lang.String="":java.lang.String +// test.kt:5 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:6 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:7 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:11 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:12 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, z:java.lang.String="z":java.lang.String +// test.kt:15 box: result:java.lang.String="yz":java.lang.String diff --git a/compiler/testData/debug/localVariables/tryFinally2.kt b/compiler/testData/debug/localVariables/tryFinally2.kt new file mode 100644 index 00000000000..ba4b1701c39 --- /dev/null +++ b/compiler/testData/debug/localVariables/tryFinally2.kt @@ -0,0 +1,35 @@ +// FILE: test.kt +fun box() { + var result = "" + for (x in listOf("A", "B")) { + try { + val y = "y" + result += y + continue + } + finally { + val z = "z" + result += z + } + } +} + +// The old backend has the local y covering the finally block as well. +// IGNORE_BACKEND: JVM + +// LOCAL VARIABLES +// test.kt:3 box: +// test.kt:4 box: result:java.lang.String="":java.lang.String +// test.kt:5 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:6 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:7 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:11 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:12 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, z:java.lang.String="z":java.lang.String +// test.kt:4 box: result:java.lang.String="yz":java.lang.String +// test.kt:5 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String +// test.kt:6 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String +// test.kt:7 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:11 box: result:java.lang.String="yzy":java.lang.String, x:java.lang.String="B":java.lang.String +// test.kt:12 box: result:java.lang.String="yzy":java.lang.String, x:java.lang.String="B":java.lang.String, z:java.lang.String="z":java.lang.String +// test.kt:4 box: result:java.lang.String="yzyz":java.lang.String +// test.kt:15 box: result:java.lang.String="yzyz":java.lang.String diff --git a/compiler/testData/debug/localVariables/tryFinally3.kt b/compiler/testData/debug/localVariables/tryFinally3.kt new file mode 100644 index 00000000000..810bdca09bd --- /dev/null +++ b/compiler/testData/debug/localVariables/tryFinally3.kt @@ -0,0 +1,38 @@ +// FILE: test.kt + +fun compute(): String { + var result = "" + for (x in listOf("A", "B")) { + try { + val y = "y" + result += y + return result + } + finally { + val z = "z" + result += z + } + } + return result +} + +fun box() { + compute() +} + +// The old backend has the local y covering the finally block as well. +// IGNORE_BACKEND: JVM + +// LOCAL VARIABLES +// test.kt:20 box: +// test.kt:4 compute: +// test.kt:5 compute: result:java.lang.String="":java.lang.String +// test.kt:6 compute: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:7 compute: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:8 compute: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:9 compute: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:12 compute: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String +// test.kt:13 compute: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, z:java.lang.String="z":java.lang.String +// test.kt:9 compute: result:java.lang.String="yz":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String +// test.kt:20 box: +// test.kt:21 box: diff --git a/compiler/testData/debug/localVariables/tryFinally4.kt b/compiler/testData/debug/localVariables/tryFinally4.kt new file mode 100644 index 00000000000..250b105c5c9 --- /dev/null +++ b/compiler/testData/debug/localVariables/tryFinally4.kt @@ -0,0 +1,49 @@ +// FILE: test.kt + +fun compute(): String { + var result = "" + try { + val a = "a" + try { + val b = "b" + for (i in 0 until 1) { + val e = "e" + result += b + return result + } + } finally { + val c = "c" + result += c + } + } finally { + val d = "d" + result += d + } + return result +} + +fun box() { + compute() +} + +// The old backend gets the local variables for finally blocks wrong. +// IGNORE_BACKEND: JVM + +// LOCAL VARIABLES +// test.kt:26 box: +// test.kt:4 compute: +// test.kt:5 compute: result:java.lang.String="":java.lang.String +// test.kt:6 compute: result:java.lang.String="":java.lang.String +// test.kt:7 compute: result:java.lang.String="":java.lang.String, a:java.lang.String="a":java.lang.String +// test.kt:8 compute: result:java.lang.String="":java.lang.String, a:java.lang.String="a":java.lang.String +// test.kt:9 compute: result:java.lang.String="":java.lang.String, a:java.lang.String="a":java.lang.String, b:java.lang.String="b":java.lang.String +// test.kt:10 compute: result:java.lang.String="":java.lang.String, a:java.lang.String="a":java.lang.String, b:java.lang.String="b":java.lang.String, i:int=0:int +// test.kt:11 compute: result:java.lang.String="":java.lang.String, a:java.lang.String="a":java.lang.String, b:java.lang.String="b":java.lang.String, i:int=0:int, e:java.lang.String="e":java.lang.String +// test.kt:12 compute: result:java.lang.String="b":java.lang.String, a:java.lang.String="a":java.lang.String, b:java.lang.String="b":java.lang.String, i:int=0:int, e:java.lang.String="e":java.lang.String +// test.kt:15 compute: result:java.lang.String="b":java.lang.String, a:java.lang.String="a":java.lang.String +// test.kt:16 compute: result:java.lang.String="b":java.lang.String, a:java.lang.String="a":java.lang.String, c:java.lang.String="c":java.lang.String +// test.kt:19 compute: result:java.lang.String="bc":java.lang.String +// test.kt:20 compute: result:java.lang.String="bc":java.lang.String, d:java.lang.String="d":java.lang.String +// test.kt:12 compute: result:java.lang.String="bcd":java.lang.String, a:java.lang.String="a":java.lang.String, b:java.lang.String="b":java.lang.String, i:int=0:int, e:java.lang.String="e":java.lang.String +// test.kt:26 box: +// test.kt:27 box: diff --git a/compiler/testData/debug/localVariables/tryFinally5.kt b/compiler/testData/debug/localVariables/tryFinally5.kt new file mode 100644 index 00000000000..5bd7503652a --- /dev/null +++ b/compiler/testData/debug/localVariables/tryFinally5.kt @@ -0,0 +1,48 @@ +// FILE: test.kt + +inline fun g(block: () -> Unit) { + block() +} + +var x: String? = null + +fun compute(): String { + try { + for (a in listOf("a")) { + g { + for (b in listOf("b")) { + return b + } + } + } + } finally { + x = "OK" + } + return "FAIL" +} + +fun box() { + val result = compute() + val localX = x +} + +// JVM_IR backend correctly gets rid of the `a` local in the finally, but the inliner +// does not get rid of `b` or the inlining locals. + +// JVM backend does not get rid of `a` and also the inliner does not get rid of `b` +// or the inlining locals. + +// IGNORE_BACKEND: JVM_IR, JVM + +// LOCAL VARIABLES +// test.kt:25 box: +// test.kt:10 compute: +// test.kt:11 compute: +// test.kt:12 compute: a:java.lang.String="a":java.lang.String +// test.kt:4 compute: a:java.lang.String="a":java.lang.String, $i$f$g:int=0:int +// test.kt:13 compute: a:java.lang.String="a":java.lang.String, $i$f$g:int=0:int, $i$a$-g-TestKt$compute$1:int=0:int +// test.kt:14 compute: a:java.lang.String="a":java.lang.String, $i$f$g:int=0:int, $i$a$-g-TestKt$compute$1:int=0:int, b:java.lang.String="b":java.lang.String +// test.kt:19 compute: +// test.kt:25 box: +// test.kt:26 box: result:java.lang.String="b":java.lang.String +// test.kt:27 box: result:java.lang.String="b":java.lang.String, localX:java.lang.String="OK":java.lang.String diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index e5bc5a08f64..48ebf86b4c3 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -8659,6 +8659,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @Test + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @Test @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index b9bd230dddc..40afe43d525 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -8659,6 +8659,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @Test + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @Test @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index f1d132bf87a..ff4348b847a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6725,6 +6725,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java index 127b565293f..7b981161b68 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java @@ -86,6 +86,36 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); } + @Test + @TestMetadata("tryFinally.kt") + public void testTryFinally() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally.kt"); + } + + @Test + @TestMetadata("tryFinally2.kt") + public void testTryFinally2() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally2.kt"); + } + + @Test + @TestMetadata("tryFinally3.kt") + public void testTryFinally3() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally3.kt"); + } + + @Test + @TestMetadata("tryFinally4.kt") + public void testTryFinally4() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally4.kt"); + } + + @Test + @TestMetadata("tryFinally5.kt") + public void testTryFinally5() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally5.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java index dc9082c975d..0c84a8ea521 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java @@ -86,6 +86,36 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); } + @Test + @TestMetadata("tryFinally.kt") + public void testTryFinally() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally.kt"); + } + + @Test + @TestMetadata("tryFinally2.kt") + public void testTryFinally2() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally2.kt"); + } + + @Test + @TestMetadata("tryFinally3.kt") + public void testTryFinally3() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally3.kt"); + } + + @Test + @TestMetadata("tryFinally4.kt") + public void testTryFinally4() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally4.kt"); + } + + @Test + @TestMetadata("tryFinally5.kt") + public void testTryFinally5() throws Exception { + runTest("compiler/testData/debug/localVariables/tryFinally5.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 8a52d637923..406a373a4c0 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -6014,6 +6014,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 0bae74acc17..840c9d8163f 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -5425,6 +5425,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 355caba3f6c..29d76ea991d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5425,6 +5425,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt"); } + @TestMetadata("nonLocalReturnInTryFinally.kt") + public void testNonLocalReturnInTryFinally() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/nonLocalReturnInTryFinally.kt"); + } + @TestMetadata("splitTry.kt") public void testSplitTry() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/splitTry.kt");