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
This commit is contained in:
Alexander Udalov
2021-10-01 02:57:40 +02:00
parent 279f184703
commit 357f3184bf
7 changed files with 51 additions and 10 deletions
@@ -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 {
@@ -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)
}
}
@@ -0,0 +1,21 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
class V1<T : Number>(y: T) {
@JvmField
var x: T = y
}
class V2<T : Number> {
lateinit var x: T
}
fun check(a: V1<Float>, b: V2<Float>): Boolean =
a.x != b.x
fun box(): String {
val v1 = V1(1.0f)
val v2 = V2<Float>()
v2.x = 2.0f
return if (check(v1, v2)) "OK" else "Fail"
}
@@ -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 }
@@ -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 {
@@ -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 {
@@ -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");