diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index a8113bb25a9..a14743f62bb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransf import org.jetbrains.kotlin.codegen.optimization.boxing.isPrimitiveUnboxing import org.jetbrains.kotlin.codegen.optimization.common.* import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer +import org.jetbrains.kotlin.codegen.optimization.fixStack.top import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.isReleaseCoroutines @@ -951,7 +952,13 @@ private fun allSuspensionPointsAreTailCalls( } if (insideTryBlock) return@all false - safelyReachableReturns[endIndex + 1] != null + safelyReachableReturns[endIndex + 1]?.all { returnIndex -> + sourceFrames[returnIndex].top().sure { + "There must be some value on stack to return" + }.insns.all { sourceInsn -> + sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex + } + } ?: false } } diff --git a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt deleted file mode 100644 index 91c8cacdf76..00000000000 --- a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt +++ /dev/null @@ -1,16 +0,0 @@ -// WITH_RUNTIME - -import kotlin.coroutines.intrinsics.* - -fun check() = true - -suspend fun f(i: Int): Unit { - return f_2() -} - -private inline suspend fun f_2(): Unit { - if (check()) return - return suspendCoroutineUninterceptedOrReturn { - COROUTINE_SUSPENDED - } -} diff --git a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.txt b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.txt deleted file mode 100644 index 7fb7923b1ca..00000000000 --- a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.txt +++ /dev/null @@ -1,6 +0,0 @@ -@kotlin.Metadata -public final class TailCallIfReturnUnitKt { - public final static method check(): boolean - public final static @org.jetbrains.annotations.Nullable method f(p0: int, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object - private synthetic final static method f_2(p0: kotlin.coroutines.Continuation): java.lang.Object -} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index eceff59c950..14b31f88cf4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -498,11 +498,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/tailcall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } - @TestMetadata("tailCallIfReturnUnit.kt") - public void testTailCallIfReturnUnit() throws Exception { - runTest("compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt"); - } - @TestMetadata("tailCallIntrinsics.kt") public void testTailCallIntrinsics_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.kt", "kotlin.coroutines.experimental");