diff --git a/compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt b/compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt index 94399889ec4..6ebc6152f76 100644 --- a/compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt +++ b/compiler/testData/codegen/box/coroutines/controlFlow/finallyCatch.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS // IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt b/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt new file mode 100644 index 00000000000..493c35c2577 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt @@ -0,0 +1,43 @@ +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +// Note: This test for issue KT-28207 about infinite loop after throwing exception from finally block + +suspend fun throwHere(): Nothing = throw RuntimeException("Do not catch me") + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "" + + var count = 0 + try { + builder { + try { + throwHere() + count = 1 + } finally { + if (count == 0) { + count = 2 + result = "O" + throw Exception("K") + } else if (count == 2) { + result = "FAIL: execution gets into infinite loop" + } else { + result = "FAIL: exception has not been thrown" + } + } + } + } catch (x: Exception) { + result += x.message + } + + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt b/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt new file mode 100644 index 00000000000..ff27422583a --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt @@ -0,0 +1,52 @@ +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +// Note: This test for issue KT-28207 about infinite loop after throwing exception from finally block + +var resume: () -> Unit = {} + +suspend fun suspendHere(): String = suspendCoroutineUninterceptedOrReturn { cont -> + resume = { + cont.resumeWithException(RuntimeException("Do not catch me")) + } + COROUTINE_SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "" + + var count = 0 + try { + builder { + try { + suspendHere() + count = 1 + } finally { + if (count == 0) { + count = 2 + result = "O" + throw Exception("K") + } else if (count == 2) { + result = "FAIL: execution gets into infinite loop" + } else { + result = "FAIL: exception has not been thrown" + } + } + } + resume() + } catch (x: Exception) { + result += x.message + } + + + return result +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 43fbc63565d..6382392ece1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -7623,6 +7623,26 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt", "kotlin.coroutines"); } + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("simple.kt") public void testSimple_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/simple.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 f02f0a1b02a..2e3959f0453 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7623,6 +7623,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt", "kotlin.coroutines"); } + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("simple.kt") public void testSimple_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/simple.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 725fbc275cf..af8d266a4bd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -7623,6 +7623,26 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt", "kotlin.coroutines"); } + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("simple.kt") public void testSimple_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/simple.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 f7d34b2a4f0..2f1534c0f84 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 @@ -295,6 +295,7 @@ class CoroutineBodyTransformer(private val context: CoroutineTransformationConte // Handle finally node if (finallyNode != null) { currentBlock = finallyBlock + currentStatements += exceptionState(oldCatchBlock, x) finallyNode.statements.forEach { it.accept(this) } generateFinallyExit() hasFinallyBlocks = true 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 957eab89383..c53bbfe5e06 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 @@ -6373,6 +6373,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt", "kotlin.coroutines"); } + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("simple.kt") public void testSimple_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/simple.kt", "kotlin.coroutines"); 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 db1bc3b73be..057c14c666e 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 @@ -7223,6 +7223,26 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/inlineSuspendFunction.kt", "kotlin.coroutines"); } + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinallyWithSuspension.kt") + public void testRethrowInFinallyWithSuspension_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinallyWithSuspension.kt", "kotlin.coroutines"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("rethrowInFinally.kt") + public void testRethrowInFinally_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/rethrowInFinally.kt", "kotlin.coroutines"); + } + @TestMetadata("simple.kt") public void testSimple_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/stackUnwinding/simple.kt", "kotlin.coroutines.experimental");