diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt index 43397307ce8..3ac0206c666 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt @@ -213,30 +213,8 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass private val samSuperClass = samSuperType?.let { it.classOrNull ?: error("Expected a class but was: ${it.render()}") } - private val adapteeCall: IrFunctionAccessExpression? = - // TODO: Copied from JVM. - if (referencedFunction.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) { - // The body of a callable reference adapter contains either only a call, or an IMPLICIT_COERCION_TO_UNIT type operator - // applied to a call. That call's target is the original function which we need to get owner/name/signature. - val call = when (val statement = referencedFunction.body!!.statements.single()) { - is IrTypeOperatorCall -> { - assert(statement.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { - "Unexpected type operator in ADAPTER_FOR_CALLABLE_REFERENCE: ${referencedFunction.render()}" - } - statement.argument - } - is IrReturn -> statement.value - else -> statement - } - if (call !is IrFunctionAccessExpression) { - throw UnsupportedOperationException("Unknown structure of ADAPTER_FOR_CALLABLE_REFERENCE: ${referencedFunction.render()}") - } - call - } else { - null - } + private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner - private val adaptedReferenceOriginalTarget: IrFunction? = adapteeCall?.symbol?.owner private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction private val functionReferenceClass: IrClass = @@ -404,13 +382,21 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass } private fun hasVarargMappedToElement(): Boolean { - if (adapteeCall == null) return false - for (i in 0 until adapteeCall.valueArgumentsCount) { - val arg = adapteeCall.getValueArgument(i) ?: continue - if (arg !is IrVararg) continue - for (varargElement in arg.elements) { - if (varargElement is IrGetValue) return true + if (adaptedReferenceOriginalTarget == null) return false + val originalParameters = adaptedReferenceOriginalTarget.allParameters + val adaptedParameters = functionReference.symbol.owner.allParameters + var index = 0 + // TODO: There should be similar code somewhere in the resolve. + while (index < originalParameters.size && index < adaptedParameters.size) { + val originalParameter = originalParameters[index] + val adaptedParameter = adaptedParameters[index] + if (originalParameter.defaultValue != null) return false + if (originalParameter.isVararg) { + if (originalParameter.varargElementType!!.erasureForTypeOperation() + == adaptedParameter.type.erasureForTypeOperation()) + return true } + ++index } return false } diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 5a13f6aea2e..3a744bbc7ad 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -2779,6 +2779,10 @@ task funInterface_nonTrivialProjectionInSuperType(type: KonanLocalTest) { source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt" } +task funInterface_kt43887(type: KonanLocalTest) { + source = "codegen/funInterface/kt43887.kt" +} + task objectExpression1(type: KonanLocalTest) { goldValue = "aabb\n" source = "codegen/objectExpression/expr1.kt" diff --git a/kotlin-native/backend.native/tests/codegen/funInterface/kt43887.kt b/kotlin-native/backend.native/tests/codegen/funInterface/kt43887.kt new file mode 100644 index 00000000000..e296bee93e5 --- /dev/null +++ b/kotlin-native/backend.native/tests/codegen/funInterface/kt43887.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2021 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.funInterface.kt43887 + +import kotlin.test.* + +import kotlinx.cinterop.* +typealias heap_t = IntVar +fun heap_create(size: Long): CPointer? = null +fun heap_alloc(heap: CPointer?, size: ULong): CPointer<*>? = null +fun heap_free(heap: CPointer?, ptr: CPointer<*>?): CPointer? = null +inline fun Heap(size: Long): CPointer? { + return heap_create(size) +} +inline fun CPointer?.use(f: (CPointer) -> Unit) { + alloc() + ?.also(f) + ?.also(::free) +} +inline fun CPointer?.alloc(): CPointer? { + return heap_alloc(this, sizeOf().toULong())?.reinterpret() +} +inline fun CPointer?.free(ptr: CPointer<*>?): Boolean { + return heap_free(this, ptr)?.pointed?.value ?: false +} + +@Test +fun runTest(): Unit = memScoped { + val heap = Heap(1024) + + heap.use { ptr -> + ptr.pointed.value = 40 + //println("PTR ${ptr.pointed}") + } +}