diff --git a/compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt b/compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt index 5efe6b15a6c..6281fc3f783 100644 --- a/compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt +++ b/compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt @@ -7,6 +7,8 @@ import helpers.* import COROUTINES_PACKAGE.* import COROUTINES_PACKAGE.intrinsics.* + + class Controller { var result = "" @@ -15,9 +17,18 @@ class Controller { c.resume(value) COROUTINE_SUSPENDED } + + var count = 0 + fun expect(i: Int) { + if (++count != i) throw Exception("EXPECTED $i") + } + + fun log(value: T) { + result += "log($value);" + } } -fun builder(c: suspend Controller.() -> String): String { +fun builder(c: suspend Controller.() -> Int): String { val controller = Controller() c.startCoroutine(controller, handleResultContinuation { controller.result += "return($it);" @@ -25,45 +36,22 @@ fun builder(c: suspend Controller.() -> String): String { return controller.result } -fun builderUnit(c: suspend Controller.() -> Unit): String { - val controller = Controller() - c.startCoroutine(controller, handleResultContinuation { - controller.result += "return;" - }) - return controller.result -} - -fun id(value: T) = value - fun box(): String { - var value = builder { + val res = builder { + expect(1) + log(1) try { - if (id(23) == 23) { - return@builder suspendAndLog("OK") - } + expect(2) + suspendAndLog(2) + } finally { + expect(3) + log(3) + return@builder 4 } - finally { - result += "finally;" - } - result += "afterFinally;" - "shouldNotReach" + log("FAIL") + -1 } - if (value != "suspend(OK);finally;return(OK);") return "fail1: $value" - - value = builderUnit { - try { - if (id(23) == 23) { - suspendAndLog("OK") - return@builderUnit - } - } - finally { - result += "finally;" - } - result += "afterFinally;" - "shouldNotReach" - } - if (value != "suspend(OK);finally;return;") return "fail2: $value" + if (res != "log(1);suspend(2);log(3);return(4);") return "FAIL: $res" return "OK" -} +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt b/compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt new file mode 100644 index 00000000000..5efe6b15a6c --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt @@ -0,0 +1,69 @@ +// IGNORE_BACKEND: JS_IR +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +class Controller { + var result = "" + + suspend fun suspendAndLog(value: T): T = suspendCoroutineUninterceptedOrReturn { c -> + result += "suspend($value);" + c.resume(value) + COROUTINE_SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> String): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.result += "return($it);" + }) + return controller.result +} + +fun builderUnit(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.result += "return;" + }) + return controller.result +} + +fun id(value: T) = value + +fun box(): String { + var value = builder { + try { + if (id(23) == 23) { + return@builder suspendAndLog("OK") + } + } + finally { + result += "finally;" + } + result += "afterFinally;" + "shouldNotReach" + } + if (value != "suspend(OK);finally;return(OK);") return "fail1: $value" + + value = builderUnit { + try { + if (id(23) == 23) { + suspendAndLog("OK") + return@builderUnit + } + } + finally { + result += "finally;" + } + result += "afterFinally;" + "shouldNotReach" + } + if (value != "suspend(OK);finally;return;") return "fail2: $value" + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 2d1e3a27355..95accd92397 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6170,6 +6170,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt", "kotlin.coroutines"); } + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("switchLikeWhen.kt") public void testSwitchLikeWhen_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/switchLikeWhen.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 653dfaa7129..b0cc6aa7ec5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -6170,6 +6170,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt", "kotlin.coroutines"); } + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("switchLikeWhen.kt") public void testSwitchLikeWhen_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/switchLikeWhen.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d96e95126fd..25248443e85 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6170,6 +6170,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt", "kotlin.coroutines"); } + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("switchLikeWhen.kt") public void testSwitchLikeWhen_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/switchLikeWhen.kt", "kotlin.coroutines.experimental"); diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt index a758109636b..f7d34b2a4f0 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt @@ -290,6 +290,8 @@ class CoroutineBodyTransformer(private val context: CoroutineTransformationConte } } + tryStack.removeAt(tryStack.lastIndex) + // Handle finally node if (finallyNode != null) { currentBlock = finallyBlock @@ -298,8 +300,6 @@ class CoroutineBodyTransformer(private val context: CoroutineTransformationConte hasFinallyBlocks = true } - tryStack.removeAt(tryStack.lastIndex) - currentBlock = successor } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index fec1a77b1ce..3c1f962dded 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -5430,6 +5430,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt", "kotlin.coroutines.experimental"); } + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines.experimental"); + } + @TestMetadata("switchLikeWhen.kt") public void testSwitchLikeWhen_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/switchLikeWhen.kt", "kotlin.coroutines.experimental"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index fca26870f53..fa3361b9a46 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5895,6 +5895,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnFromFinally.kt", "kotlin.coroutines"); } + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("returnWithFinally.kt") + public void testReturnWithFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/returnWithFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("switchLikeWhen.kt") public void testSwitchLikeWhen_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/controlFlow/switchLikeWhen.kt", "kotlin.coroutines.experimental");