Skip to content

Commit

Permalink
Fix incorrect code generation for Nothing-returning suspend calls
Browse files Browse the repository at this point in the history
 #KT-30642 Fixed
  • Loading branch information
SvyatoslavScherbina authored Mar 27, 2019
1 parent b22fa98 commit b870ce9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2148,7 +2148,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
private fun call(function: IrFunction, llvmFunction: LLVMValueRef, args: List<LLVMValueRef>,
resultLifetime: Lifetime): LLVMValueRef {
val result = call(llvmFunction, args, resultLifetime)
if (function.returnType.isNothing()) {
if (!function.isSuspend && function.returnType.isNothing()) {
functionGenerationContext.unreachable()
}

Expand Down
5 changes: 5 additions & 0 deletions backend.native/tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -1543,6 +1543,11 @@ task coroutines_controlFlow_while2(type: RunKonanTest) {
source = "codegen/coroutines/controlFlow_while2.kt"
}

task coroutines_returnsNothing1(type: RunKonanTest) {
goldValue = "OK\n"
source = "codegen/coroutines/returnsNothing1.kt"
}

task coroutines_returnsUnit1(type: RunKonanTest) {
goldValue = "117\ns1\n0\n"
source = "codegen/coroutines/returnsUnit1.kt"
Expand Down
40 changes: 40 additions & 0 deletions backend.native/tests/codegen/coroutines/returnsNothing1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 file.
*/

package codegen.coroutines.returnsNothing1

import kotlin.test.*

import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*

open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation<Any?> {
companion object : EmptyContinuation()
override fun resumeWith(result: Result<Any?>) { result.getOrThrow() }
}

suspend fun suspendForever(): Int = suspendCoroutineUninterceptedOrReturn {
COROUTINE_SUSPENDED
}

suspend fun foo(): Nothing {
suspendForever()
throw Error()
}

suspend fun bar() {
foo()
}

fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}

@Test fun runTest() {
builder {
bar()
}
println("OK")
}

0 comments on commit b870ce9

Please sign in to comment.