[JVM_IR] Copy offsets from the original function to invokeSuspend.

Otherwise, implicit returns in void returning suspend functions
will not have the line number of the end brace.

Fixes KT-41962 and KT-40464.
This commit is contained in:
Mads Ager
2020-10-14 14:46:55 +02:00
committed by Alexander Udalov
parent 800bfe2cdb
commit ad88c60fd8
8 changed files with 29 additions and 10 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.builders.declarations
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
@@ -168,9 +169,13 @@ fun IrClass.addFunction(
isStatic: Boolean = false,
isSuspend: Boolean = false,
isFakeOverride: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
): IrSimpleFunction =
addFunction {
this.startOffset = startOffset
this.endOffset = endOffset
this.name = Name.identifier(name)
this.returnType = returnType
this.modality = modality
@@ -158,7 +158,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
val backendContext = context
val invokeSuspend = context.ir.symbols.continuationImplClass.owner.functions
.single { it.name == Name.identifier(INVOKE_SUSPEND_METHOD_NAME) }
addFunctionOverride(invokeSuspend) { function ->
addFunctionOverride(invokeSuspend, irFunction.startOffset, irFunction.endOffset) { function ->
+irSetField(irGet(function.dispatchReceiverParameter!!), resultField, irGet(function.valueParameters[0]))
// There can be three kinds of suspend function call:
// 1) direct call from another suspend function/lambda
@@ -73,17 +73,21 @@ private fun IrFunction.capturesCrossinline(): Boolean {
}
internal abstract class SuspendLoweringUtils(protected val context: JvmBackendContext) {
protected fun IrClass.addFunctionOverride(function: IrSimpleFunction): IrSimpleFunction =
addFunction(function.name.asString(), function.returnType).apply {
protected fun IrClass.addFunctionOverride(
function: IrSimpleFunction, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET
): IrSimpleFunction =
addFunction(function.name.asString(), function.returnType, startOffset = startOffset, endOffset = endOffset).apply {
overriddenSymbols = listOf(function.symbol)
valueParameters = function.valueParameters.map { it.copyTo(this) }
}
protected fun IrClass.addFunctionOverride(
function: IrSimpleFunction,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET,
makeBody: IrBlockBodyBuilder.(IrFunction) -> Unit
): IrSimpleFunction =
addFunctionOverride(function).apply {
addFunctionOverride(function, startOffset, endOffset).apply {
body = context.createIrBuilder(symbol).irBlockBody { makeBody(this@apply) }
}
@@ -196,7 +200,7 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
it.owner.name.asString() == INVOKE_SUSPEND_METHOD_NAME && it.owner.valueParameters.size == 1 &&
it.owner.valueParameters[0].type.isKotlinResult()
}.owner
return addFunctionOverride(superMethod).apply {
return addFunctionOverride(superMethod, irFunction.startOffset, irFunction.endOffset).apply {
body = irFunction.moveBodyTo(this, mapOf())?.transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
val parameter = (expression.symbol.owner as? IrValueParameter)?.takeIf { it.parent == irFunction }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
LineBreakpoint created at sequenceNested.kt:6
Run Java
Connected to the target VM
@@ -0,0 +1,14 @@
LineBreakpoint created at sequenceNested2.kt:8
Run Java
Connected to the target VM
sequenceNested2.kt:8
sequenceNested2.kt:9
sequenceNested2.kt:10
sequenceNested2.kt:11
sequenceNested2.kt:23
sequenceNested2.kt:23
sequenceNested2.kt:23
sequenceNested2.kt:24
Disconnected from the target VM
Process finished with exit code 0
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
LineBreakpoint created at sequenceNested2.kt:8
Run Java
Connected to the target VM
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
LineBreakpoint created at sequenceSimple.kt:6
Run Java
Connected to the target VM
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
LineBreakpoint created at soSuspendableCallInEndOfFun.kt:29
Run Java
Connected to the target VM