From 357f3184bfe2f56984c9a38ba09149eed6325856 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 1 Oct 2021 02:57:40 +0200 Subject: [PATCH] JVM IR: fix the type of IrGetField The `irGetField` utility uses the field's own type as the type of the resulting expression. But the field's type does not make sense outside of the place of declaration of the field if it references a generic type parameter of the containing class. Using this non-sensical generic type led, for example, to an error in Ieee754 intrinsic (KT-48648). The type of the expression should be kept as is in JvmPropertiesLowering, i.e. taken from `expression` which the lowering is replacing with the field access. #KT-48648 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../jvm/lower/JvmPropertiesLowering.kt | 15 +++++++------ .../box/ieee754/kt48648_genericField.kt | 21 +++++++++++++++++++ .../codegen/box/jvmField/kt47328_inherited.kt | 2 -- .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ 7 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/box/ieee754/kt48648_genericField.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 9301bd9ac0b..de3c2737e11 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -17734,6 +17734,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/ieee754/inline.kt"); } + @Test + @TestMetadata("kt48648_genericField.kt") + public void testKt48648_genericField() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/kt48648_genericField.kt"); + } + @Test @TestMetadata("lessDouble.kt") public void testLessDouble() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt index f732d7303b5..fb12bf6ec09 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt @@ -27,10 +27,8 @@ import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrNull -import org.jetbrains.kotlin.ir.types.isSubtypeOfClass -import org.jetbrains.kotlin.ir.types.makeNotNull +import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JvmAbi @@ -99,19 +97,20 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression { val backingField = irProperty.resolveFakeOverride()!!.backingField!! - val value = irGetField(patchFieldAccessReceiver(expression, irProperty), backingField) + val patchedReceiver = patchFieldAccessReceiver(expression, irProperty) return if (irProperty.isLateinit) { irBlock { - val tmpVal = irTemporary(value) + val fieldType = expression.type.makeNullable() + val tmpVal = irTemporary(IrGetFieldImpl(startOffset, endOffset, backingField.symbol, fieldType, patchedReceiver)) +irIfNull( - expression.type.makeNotNull(), + expression.type, irGet(tmpVal), backendContext.throwUninitializedPropertyAccessException(this, backingField.name.asString()), irGet(tmpVal) ) } } else { - value + IrGetFieldImpl(startOffset, endOffset, backingField.symbol, expression.type, patchedReceiver) } } diff --git a/compiler/testData/codegen/box/ieee754/kt48648_genericField.kt b/compiler/testData/codegen/box/ieee754/kt48648_genericField.kt new file mode 100644 index 00000000000..c62bc8d1523 --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/kt48648_genericField.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +class V1(y: T) { + @JvmField + var x: T = y +} + +class V2 { + lateinit var x: T +} + +fun check(a: V1, b: V2): Boolean = + a.x != b.x + +fun box(): String { + val v1 = V1(1.0f) + val v2 = V2() + v2.x = 2.0f + return if (check(v1, v2)) "OK" else "Fail" +} diff --git a/compiler/testData/codegen/box/jvmField/kt47328_inherited.kt b/compiler/testData/codegen/box/jvmField/kt47328_inherited.kt index aa0dcdb59af..3d75f28b46c 100644 --- a/compiler/testData/codegen/box/jvmField/kt47328_inherited.kt +++ b/compiler/testData/codegen/box/jvmField/kt47328_inherited.kt @@ -1,7 +1,5 @@ // !LANGUAGE: -ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR -// ^ generates 'GETFIELD B.x : I' instead of 'GETFIELD BB.x : I' // WITH_RUNTIME interface A { val x: Int } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 330c307656f..eb254cfab06 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -17614,6 +17614,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ieee754/inline.kt"); } + @Test + @TestMetadata("kt48648_genericField.kt") + public void testKt48648_genericField() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/kt48648_genericField.kt"); + } + @Test @TestMetadata("lessDouble.kt") public void testLessDouble() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 55c29f3957b..d30d2305317 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -17734,6 +17734,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ieee754/inline.kt"); } + @Test + @TestMetadata("kt48648_genericField.kt") + public void testKt48648_genericField() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/kt48648_genericField.kt"); + } + @Test @TestMetadata("lessDouble.kt") public void testLessDouble() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 2dcf893270c..faf58634c0e 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14588,6 +14588,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ieee754/inline.kt"); } + @TestMetadata("kt48648_genericField.kt") + public void testKt48648_genericField() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/kt48648_genericField.kt"); + } + @TestMetadata("lessDouble.kt") public void testLessDouble() throws Exception { runTest("compiler/testData/codegen/box/ieee754/lessDouble.kt");