diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 65dab306b5b..f6247375892 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -25,10 +25,7 @@ import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.KonanPhase import org.jetbrains.kotlin.backend.konan.PhaseManager import org.jetbrains.kotlin.backend.konan.descriptors.* -import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody -import org.jetbrains.kotlin.backend.konan.ir.IrSuspendableExpression -import org.jetbrains.kotlin.backend.konan.ir.IrSuspensionPoint -import org.jetbrains.kotlin.backend.konan.ir.ir2string +import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -493,7 +490,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) { if (declaration == null || target == declaration.descriptor) { - if (target.returnType!!.isUnit()) { + if (target.returnsUnit()) { assert (value == null) codegen.ret(null) } else { @@ -1457,7 +1454,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val evaluated = evaluateExpression(value) val target = expression.returnTarget - val ret = if (target.returnType!!.isUnit()) { + val ret = if (target.returnsUnit()) { null } else { evaluated @@ -1498,7 +1495,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid // It is local return from current function. codegen.br(getExit()) // Generate branch on exit block. - if (!KotlinBuiltIns.isUnit(inlineBody.type)) { // If function returns more then "unit" + if (!target.returnsUnit()) { // If function returns more then "unit" codegen.assignPhis(getResult() to value!!) // Assign return value to result PHI node. } } @@ -1752,6 +1749,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid } } + private fun CallableDescriptor.returnsUnit() = returnType == context.builtIns.unitType && !isSuspend + /** * Evaluates all arguments of [expression] that are explicitly represented in the IR. * Returns results in the same order as LLVM function expects, assuming that all explicit arguments diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/SuspendFunctionsLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/SuspendFunctionsLowering.kt index ecd381b2c9c..009f2a2bd64 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/SuspendFunctionsLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/SuspendFunctionsLowering.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.makeNotNullable internal class SuspendFunctionsLowering(val context: Context): DeclarationContainerLoweringPass { @@ -827,6 +828,8 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai +irThrowIfNotNull(exceptionArgument) // Coroutine might start with an exception. statements.forEach { +it } }) + if (irFunction.descriptor.returnType!!.isUnit()) + +irReturn(irUnit()) // Insert explicit return for Unit functions. } } } @@ -1039,7 +1042,11 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai +irGet(dataArgument) }) tempStatements.add(irVar(currentSuspendResult, suspensionPoint)) - return irWrap(irCast(irGet(currentSuspendResult), suspendCall.type, suspendCall.type), tempStatements) + val expressionResult = when { + suspendCall.type.isUnit() -> IrCompositeImpl(startOffset, endOffset, suspendCall.type) + else -> irCast(irGet(currentSuspendResult), suspendCall.type, suspendCall.type) + } + return irWrap(expressionResult, tempStatements) } }