diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 1bf5ee53b74..8b46c3f143e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -202,16 +202,6 @@ private inline fun generateFunctionBody( functionGenerationContext.resetDebugLocation() } -private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? { - if (modality == Modality.ABSTRACT) return null - val resolved = resolveFakeOverride()!! - if ((resolved.parent as IrClass).isAny()) { - return resolved - } - - return null -} - internal object VirtualTablesLookup { private fun FunctionGenerationContext.getInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef { val interfaceTableSize = load(structGep(typeInfo, 9 /* interfaceTableSize_ */)) @@ -307,6 +297,9 @@ internal object VirtualTablesLookup { } } +internal fun IrSimpleFunction.findOverriddenMethodOfAny() = + resolveFakeOverride(allowAbstract = false).takeIf { it?.parentClassOrNull?.isAny() == true } + /* * Special trampoline function to call actual virtual implementation. This helps with reducing * dependence between klibs/files (if vtable/itable of some class has changed, the call sites @@ -317,8 +310,10 @@ internal fun CodeGenerator.getVirtualFunctionTrampoline(irFunction: IrSimpleFunc * Resolve owner of the call with special handling of Any methods: * if toString/eq/hc is invoked on an interface instance, we resolve * owner as Any and dispatch it via vtable. + * Note: Keep on par with DFG builder. */ val anyMethod = irFunction.findOverriddenMethodOfAny() + return getVirtualFunctionTrampolineImpl(anyMethod ?: irFunction) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt index 5aefee933ac..4333dea8b1b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt @@ -769,7 +769,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } else -> { - val callee = value.symbol.owner + /* + * Resolve owner of the call with special handling of Any methods: + * if toString/eq/hc is invoked on an interface instance, we resolve + * owner as Any and dispatch it via vtable. + * Note: Keep on par with the codegen. + */ + val callee = value.symbol.owner.let { it.findOverriddenMethodOfAny() ?: it } val arguments = value.getArgumentsWithIr() .map { expressionToEdge(it.second) }