From 5954db18cb14da18db342ccf6d78ebab641eb94a Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 21 Sep 2020 13:33:42 +0200 Subject: [PATCH] JVM_IR: fix lifting of arguments to object super constructors If the arguments are reordered, they can not only be reads of temporary variables, but also implicit type casts of said reads. Fixes #KT-42002 --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++++ ...AnonymousObjectSuperConstructorLowering.kt | 20 +++++++++++-------- ...tOrderInObjectSuperCallWithPlatformType.kt | 13 ++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ 6 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 05d4f63a0c1..5e830a98c8e 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -315,6 +315,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCall.kt"); } + @TestMetadata("argumentOrderInObjectSuperCallWithPlatformType.kt") + public void testArgumentOrderInObjectSuperCallWithPlatformType() throws Exception { + runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt"); + } + @TestMetadata("argumentOrderInSuperCall.kt") public void testArgumentOrderInSuperCall() throws Exception { runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInSuperCall.kt"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt index 5c298df7a12..3b0e95726e3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.util.transformInPlace internal val anonymousObjectSuperConstructorPhase = makeIrFilePhase( @@ -78,16 +79,19 @@ private class AnonymousObjectSuperConstructorLowering(val context: JvmBackendCon ) } + fun IrExpression.transform(remapping: Map): IrExpression = + when (this) { + is IrConst<*> -> this + is IrGetValue -> IrGetValueImpl(startOffset, endOffset, remapping[symbol.owner]?.symbol ?: symbol) + is IrTypeOperatorCall -> + IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeOperand, argument.transform(remapping)) + else -> IrGetValueImpl(startOffset, endOffset, addArgument(this).symbol) + } + fun IrDelegatingConstructorCall.transform(lift: List) = apply { val remapping = lift.associateWith { addArgument(it.initializer!!) } - for (i in 0 until symbol.owner.valueParameters.size) { - val argument = getValueArgument(i) ?: continue - val mapped = when (argument) { - is IrConst<*> -> null - is IrGetValue -> remapping[argument.symbol.owner] - else -> addArgument(argument) - } ?: continue - putValueArgument(i, IrGetValueImpl(argument.startOffset, argument.endOffset, mapped.symbol)) + for (i in symbol.owner.valueParameters.indices) { + putValueArgument(i, getValueArgument(i)?.transform(remapping)) } } diff --git a/compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt b/compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt new file mode 100644 index 00000000000..8502dde7267 --- /dev/null +++ b/compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt @@ -0,0 +1,13 @@ +// TARGET_PLATFORM: JVM +// FILE: A.java +public class A { + public static String f() { + return "O"; + } +} +// FILE: a.kt +open class C(x: String, y: String) { + val result = x + y +} + +fun box() = object : C(y = "K", x = A.f()) {}.result diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 95310bab86d..19e85f7974b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -315,6 +315,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCall.kt"); } + @TestMetadata("argumentOrderInObjectSuperCallWithPlatformType.kt") + public void testArgumentOrderInObjectSuperCallWithPlatformType() throws Exception { + runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt"); + } + @TestMetadata("argumentOrderInSuperCall.kt") public void testArgumentOrderInSuperCall() throws Exception { runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInSuperCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 0cc4e3e6a9d..09583f04fab 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -315,6 +315,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCall.kt"); } + @TestMetadata("argumentOrderInObjectSuperCallWithPlatformType.kt") + public void testArgumentOrderInObjectSuperCallWithPlatformType() throws Exception { + runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt"); + } + @TestMetadata("argumentOrderInSuperCall.kt") public void testArgumentOrderInSuperCall() throws Exception { runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInSuperCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 1d4b532a073..cc5e5335747 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -315,6 +315,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCall.kt"); } + @TestMetadata("argumentOrderInObjectSuperCallWithPlatformType.kt") + public void testArgumentOrderInObjectSuperCallWithPlatformType() throws Exception { + runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInObjectSuperCallWithPlatformType.kt"); + } + @TestMetadata("argumentOrderInSuperCall.kt") public void testArgumentOrderInSuperCall() throws Exception { runTest("compiler/testData/codegen/box/argumentOrder/argumentOrderInSuperCall.kt");