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:
+6
@@ -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 {
|
||||
|
||||
+7
-8
@@ -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 }
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user