From cebe67d90cdd2173f452701bbf7066c1e4cc08b9 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 31 Aug 2016 16:15:36 +0300 Subject: [PATCH] Fix default value generation after suspension point Replace coercion from VOID with call 'pushDefaultValueOnStack' It's necessary because coercion of VOID to java/lang/Object ends with Unit instance on stack that makes variables spilling algorithm thinking that variable is Unit #KT-13409 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 2 +- .../box/coroutines/falseUnitCoercion.kt | 24 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 881ae8afe40..45a9f375801 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2875,7 +2875,7 @@ public class ExpressionCodegen extends KtVisitor impleme callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this); if (isSuspensionPoint) { - StackValue.coerce(Type.VOID_TYPE, getSuspensionReturnTypeByResolvedCall(resolvedCall), v); + AsmUtil.pushDefaultValueOnStack(getSuspensionReturnTypeByResolvedCall(resolvedCall), v); v.invokestatic( CoroutineCodegenUtilKt.COROUTINE_MARKER_OWNER, CoroutineCodegenUtilKt.AFTER_SUSPENSION_POINT_MARKER_NAME, "()V", false); diff --git a/compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt b/compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt new file mode 100644 index 00000000000..c827d4dea5b --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt @@ -0,0 +1,24 @@ +class Controller { + suspend fun suspendHere(v: T, x: Continuation) { + x.resume(v) + } +} + +fun builder(coroutine c: Controller.() -> Continuation) { + c(Controller()).resume(Unit) +} + +var result: Any = "" + +fun foo(v: T) { + builder { + val r = suspendHere(v) + suspendHere("") + result = r + } +} + +fun box(): String { + foo("OK") + return result as String +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a30f71e71e7..0bdecbc7dcc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -4348,6 +4348,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("falseUnitCoercion.kt") + public void testFalseUnitCoercion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt"); + doTest(fileName); + } + @TestMetadata("generate.kt") public void testGenerate() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/generate.kt");