diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt index cfcf73cc4c9..e6b83b9d168 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt @@ -5,14 +5,12 @@ package org.jetbrains.kotlin.backend.jvm.codegen -import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.jvm.InlineClassAbi import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.ir.* import org.jetbrains.kotlin.backend.jvm.unboxInlineClass import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor -import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.ir.declarations.* @@ -21,11 +19,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.allOverridden -import org.jetbrains.kotlin.ir.util.file -import org.jetbrains.kotlin.ir.util.isSuspend -import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmBackendErrors import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.MethodNode @@ -41,24 +36,17 @@ internal fun MethodNode.acceptWithStateMachine( val state = context.state val languageVersionSettings = state.languageVersionSettings assert(languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) { "Experimental coroutines are unsupported in JVM_IR backend" } - val element = if (irFunction.isSuspend) - irFunction.psiElement ?: classCodegen.irClass.psiElement - else - context.suspendLambdaToOriginalFunctionMap[classCodegen.irClass.attributeOwnerId]!!.psiElement - val lineNumber = if (irFunction.isSuspend) { - val irFile = irFunction.file - if (irFunction.startOffset >= 0) { - // if it suspend function like `suspend fun foo(...)` - irFile.fileEntry.getLineNumber(irFunction.startOffset) + 1 - } else { - val klass = classCodegen.irClass - if (klass.startOffset >= 0) { - // if it suspend lambda transformed into class `runSuspend { .... }` - irFile.fileEntry.getLineNumber(klass.startOffset) + 1 - } else 0 - } - } else element?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0 + val lineNumber = if (irFunction.startOffset >= 0) { + // if it suspend function like `suspend fun foo(...)` + irFunction.file.fileEntry.getLineNumber(irFunction.startOffset) + 1 + } else { + val klass = classCodegen.irClass + if (klass.startOffset >= 0) { + // if it suspend lambda transformed into class `runSuspend { .... }` + irFunction.file.fileEntry.getLineNumber(klass.startOffset) + 1 + } else error("Cannot determine lineNumber of element ${irFunction.render()}") + } val visitor = CoroutineTransformerMethodVisitor( methodVisitor, access, name, desc, signature, exceptions.toTypedArray(), @@ -68,7 +56,10 @@ internal fun MethodNode.acceptWithStateMachine( disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let { it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit() }, - reportSuspensionPointInsideMonitor = { reportSuspensionPointInsideMonitor(element as KtElement, state, it) }, + reportSuspensionPointInsideMonitor = { + classCodegen.context.ktDiagnosticReporter.at(irFunction, classCodegen.irClass) + .report(JvmBackendErrors.SUSPENSION_POINT_INSIDE_MONITOR, it) + }, lineNumber = lineNumber, sourceFile = classCodegen.irClass.file.name, // SuspendLambda.invokeSuspend is not suspend needDispatchReceiver = irFunction.isSuspend && (irFunction.dispatchReceiverParameter != null diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/output.txt index aea1cbecc35..0bb75df7bfb 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/output.txt @@ -4,10 +4,10 @@ compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/so compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:14:13: error: a suspension point at SourceKt$test$2.invokeSuspend(source.kt:17) is inside a critical section builder { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:50:34: error: a suspension point at SourceKt$withCrossinline$c$1.invokeSuspend(source.kt:52) is inside a critical section - val c : suspend () -> Unit = { - ^ compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:49:1: error: a suspension point at SourceKt$test$3$invokeSuspend$$inlined$withCrossinline$2.invokeSuspend(source.kt:60) is inside a critical section inline fun withCrossinline(crossinline a: suspend () -> Unit): suspend () -> Unit { ^ +compiler/testData/compileKotlinAgainstCustomBinaries/suspensionPointInMonitor/source.kt:50:34: error: a suspension point at SourceKt$withCrossinline$c$1.invokeSuspend(source.kt:52) is inside a critical section + val c : suspend () -> Unit = { + ^ COMPILATION_ERROR