diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index b60a6ca6a46..6e3d48d4531 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -346,7 +346,7 @@ class ExpressionCodegen( classCodegen.context.irIntrinsics.getIntrinsic(expression.symbol) ?.invoke(expression, this, data)?.let { return it } - val callable = methodSignatureMapper.mapToCallableMethod(expression) + val callable = methodSignatureMapper.mapToCallableMethod(irFunction, expression) val callee = expression.symbol.owner val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature) val asmType = if (expression is IrConstructorCall) typeMapper.mapTypeAsDeclaration(expression.type) else expression.asmType diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index 27e138827d2..cd8086a4e49 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -286,7 +286,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value as? Boolean ?: true else null } - fun mapToCallableMethod(expression: IrFunctionAccessExpression): IrCallableMethod { + fun mapToCallableMethod(caller: IrFunction, expression: IrFunctionAccessExpression): IrCallableMethod { val callee = expression.symbol.owner.getOrCreateSuspendFunctionViewIfNeeded(context) val calleeParent = callee.parent if (calleeParent !is IrClass) { @@ -316,14 +316,17 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { } val declaration = findSuperDeclaration(callee, isSuperCall) - val signature = mapOverriddenSpecialBuiltinIfNeeded(declaration, isSuperCall) + val signature = mapOverriddenSpecialBuiltinIfNeeded(caller, declaration, isSuperCall) ?: mapSignatureSkipGeneric(declaration) return IrCallableMethod(owner, invokeOpcode, signature, isInterface) } // TODO: get rid of this (probably via some special lowering) - private fun mapOverriddenSpecialBuiltinIfNeeded(callee: IrFunction, superCall: Boolean): JvmMethodSignature? { + private fun mapOverriddenSpecialBuiltinIfNeeded(caller: IrFunction, callee: IrFunction, superCall: Boolean): JvmMethodSignature? { + // Do not remap special builtin methods when called from a bridge. The bridges are there to provide the + // remapped name or signature and forward to the actually declared method. + if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor() if (overriddenSpecialBuiltinFunction != null && !superCall) { return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 82b965b8902..7d93943ef28 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -120,6 +120,8 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass irFunction.overriddenSymbols.all { it.owner.getJvmName() != ourMethodName } ) { // Bridges for abstract fake overrides whose JVM names differ from overridden functions. + // The orphaned copy will get irFunction's name; the original irFunction will be renamed + // according to its overrides, val bridge = irFunction.orphanedCopy() irClass.declarations.add(bridge) targetForCommonBridges = bridge @@ -320,18 +322,13 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass isSpecial: Boolean, invokeStatically: Boolean = false ) { - val maybeOrphanedTarget = if (isSpecial) - target.orphanedCopy() - else - target - context.createIrBuilder(symbol).run { body = irBlockBody { if (specialMethodInfo != null) { valueParameters.take(specialMethodInfo.argumentsToCheck).forEach { addParameterTypeCheck( it, - maybeOrphanedTarget.valueParameters[it.index].type, + target.valueParameters[it.index].type, specialMethodInfo.defaultValueGenerator, this@createBridgeBody ) @@ -341,17 +338,17 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass irImplicitCast( IrCallImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, - maybeOrphanedTarget.returnType, - maybeOrphanedTarget.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION, - superQualifierSymbol = if (invokeStatically) maybeOrphanedTarget.parentAsClass.symbol else null + target.returnType, + target.symbol, origin = IrStatementOrigin.BRIDGE_DELEGATION, + superQualifierSymbol = if (invokeStatically) target.parentAsClass.symbol else null ).apply { passTypeArgumentsFrom(this@createBridgeBody) dispatchReceiver = irGet(dispatchReceiverParameter!!) extensionReceiverParameter?.let { - extensionReceiver = irImplicitCast(irGet(it), maybeOrphanedTarget.extensionReceiverParameter!!.type) + extensionReceiver = irImplicitCast(irGet(it), target.extensionReceiverParameter!!.type) } valueParameters.forEach { - putValueArgument(it.index, irImplicitCast(irGet(it), maybeOrphanedTarget.valueParameters[it.index].type)) + putValueArgument(it.index, irImplicitCast(irGet(it), target.valueParameters[it.index].type)) } }, returnType diff --git a/compiler/testData/codegen/box/bridges/strListRemove.kt b/compiler/testData/codegen/box/bridges/strListRemove.kt index a7ad053a487..3c77e134085 100644 --- a/compiler/testData/codegen/box/bridges/strListRemove.kt +++ b/compiler/testData/codegen/box/bridges/strListRemove.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // FILE: J.java diff --git a/compiler/testData/codegen/box/collections/removeAtInt.kt b/compiler/testData/codegen/box/collections/removeAtInt.kt index f0ac6c4fc76..fb0207a0561 100644 --- a/compiler/testData/codegen/box/collections/removeAtInt.kt +++ b/compiler/testData/codegen/box/collections/removeAtInt.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/box/specialBuiltins/bridgeNotEmptyMap.kt b/compiler/testData/codegen/box/specialBuiltins/bridgeNotEmptyMap.kt index cbb9a1667f5..cd795d11253 100644 --- a/compiler/testData/codegen/box/specialBuiltins/bridgeNotEmptyMap.kt +++ b/compiler/testData/codegen/box/specialBuiltins/bridgeNotEmptyMap.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS private object NotEmptyMap : MutableMap { diff --git a/compiler/testData/codegen/box/specialBuiltins/bridges.kt b/compiler/testData/codegen/box/specialBuiltins/bridges.kt index 67e24e4a62e..8f40a4bea0d 100644 --- a/compiler/testData/codegen/box/specialBuiltins/bridges.kt +++ b/compiler/testData/codegen/box/specialBuiltins/bridges.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR // KJS_WITH_FULL_RUNTIME -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: NATIVE interface A0 {