From ae70a60a0ae6f2cab93a2e4262773a9db5089c6c Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 9 Nov 2016 12:00:33 +0300 Subject: [PATCH] Validate label value of coroutine in case of no suspension points #KT-14718 Fixed --- .../CoroutineTransformationClassBuilder.kt | 2 -- .../codegen/box/coroutines/illegalState.kt | 22 +++++++++++++++- .../box/coroutines/noSuspensionPoints.kt | 26 +++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt index 1c997917d4b..449feb07110 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt @@ -74,8 +74,6 @@ class CoroutineTransformerMethodVisitor( // Add global exception handler processHandleExceptionCall(methodNode) - if (suspensionPoints.isEmpty()) return - // Spill stack to variables before suspension points, try/catch blocks FixStackWithLabelNormalizationMethodTransformer().transform(classBuilder.thisName, methodNode) diff --git a/compiler/testData/codegen/box/coroutines/illegalState.kt b/compiler/testData/codegen/box/coroutines/illegalState.kt index a9520474d5f..74e22cf5c80 100644 --- a/compiler/testData/codegen/box/coroutines/illegalState.kt +++ b/compiler/testData/codegen/box/coroutines/illegalState.kt @@ -35,7 +35,27 @@ fun box(): String { return "fail 3" } catch (e: java.lang.IllegalStateException) { if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 4: ${e.message!!}" - return "OK" + } + + var result = "OK" + + try { + builder1 { + result = "fail 5" + } + return "fail 6" + } catch (e: java.lang.IllegalStateException) { + if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 7: ${e.message!!}" + } + + try { + builder2 { + result = "fail 8" + } + return "fail 9" + } catch (e: java.lang.IllegalStateException) { + if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 10: ${e.message!!}" + return result } return "fail" diff --git a/compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt b/compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt new file mode 100644 index 00000000000..03da19b5897 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt @@ -0,0 +1,26 @@ +class Controller { + var res = 0 + operator fun handleResult(x: Int, y: Continuation) { + res = x + } +} + +fun builder(coroutine c: Controller.() -> Continuation): Int { + val controller = Controller() + c(controller).resume(Unit) + + return controller.res +} + +fun box(): String { + var result = "" + + val handledResult = builder { + result = "OK" + 56 + } + + if (handledResult != 56) return "fail 1: $handledResult" + + return result +} 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 f56ae17c566..c2fa6b1e97b 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 @@ -4573,6 +4573,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("noSuspensionPoints.kt") + public void testNoSuspensionPoints() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt"); + doTest(fileName); + } + @TestMetadata("nonLocalReturnFromInlineLambda.kt") public void testNonLocalReturnFromInlineLambda() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/nonLocalReturnFromInlineLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a06b31b3eb2..4a0fbf848f0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -4573,6 +4573,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("noSuspensionPoints.kt") + public void testNoSuspensionPoints() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt"); + doTest(fileName); + } + @TestMetadata("nonLocalReturnFromInlineLambda.kt") public void testNonLocalReturnFromInlineLambda() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/nonLocalReturnFromInlineLambda.kt");