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 4323fd68c01..e8ac2eeb5fa 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.isReleaseCoroutines import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm @@ -948,7 +947,7 @@ private fun allSuspensionPointsAreTailCalls( safelyReachableReturns[endIndex + 1]?.all { returnIndex -> sourceFrames[returnIndex].top().sure { "There must be some value on stack to return" - }.insns.all { sourceInsn -> + }.insns.any { 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 new file mode 100644 index 00000000000..21f777c0cae --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// COMMON_COROUTINES_TEST + +import COROUTINES_PACKAGE.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 new file mode 100644 index 00000000000..38dde421230 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.txt @@ -0,0 +1,6 @@ +@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.experimental.Continuation): java.lang.Object + private synthetic final static method f_2(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object +} diff --git a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit_1_3.txt b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit_1_3.txt new file mode 100644 index 00000000000..7fb7923b1ca --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit_1_3.txt @@ -0,0 +1,6 @@ +@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 14b31f88cf4..28c1cea829c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -498,6 +498,16 @@ 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_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("tailCallIfReturnUnit.kt") + public void testTailCallIfReturnUnit_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tailcall/tailCallIfReturnUnit.kt", "kotlin.coroutines"); + } + @TestMetadata("tailCallIntrinsics.kt") public void testTailCallIntrinsics_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.kt", "kotlin.coroutines.experimental");