From 85aa6383ad4e6f9411e0e8649ebb4170e7854763 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 17 Mar 2021 13:23:39 +0100 Subject: [PATCH] JVM_IR: cast bound property receivers to original type Because the receiver type is used for determining where to put accessors, and the type of fake overrides' receivers is the same as for the original declaration, casting to the type of the parameter leads to assertion errors. #KT-44658 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../jvm/lower/PropertyReferenceLowering.kt | 19 +++++++++-------- .../accessorForProtectedPropertyReference.kt | 21 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../VisualizerBlackBoxTestGenerated.java | 6 ++++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++++ 11 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.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 1e69b35c4f2..3ec9818841e 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 @@ -39269,6 +39269,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @Test + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + @Test public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 9885be40fdb..e47c833e4ea 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -342,6 +342,7 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem referenceClass.addOverride(getSignature) { computeSignatureString(expression) } } + val boundReceiver = expression.getBoundReceiver() val backingField = superClass.properties.single { it.name.asString() == "receiver" }.backingField!! val get = superClass.functions.find { it.name.asString() == "get" } val set = superClass.functions.find { it.name.asString() == "set" } @@ -350,20 +351,20 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem val field = expression.field?.owner if (field == null) { fun IrBuilderWithScope.setCallArguments(call: IrCall, arguments: List) { - var index = 1 + val receiverFromField = boundReceiver?.let { irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type) } call.copyTypeArgumentsFrom(expression) - val hasBoundReceiver = expression.getBoundReceiver() != null call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let { - if (hasBoundReceiver) - irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type) - else - irImplicitCast(irGet(arguments[index++]), it.type) + // TODO: in `C::x`, the receiver must be cast to `C` in order to put accessors for protected + // properties in the correct class (box/syntheticAccessors/accessorForProtectedPropertyReference.kt). + // Since there is no information about `C` in `IrPropertyReference`, we rely on fake overrides here + // (expecting that the getter is `C.getX` and not `.getX`) and that does not work with FIR. + receiverFromField ?: irImplicitCast(irGet(arguments[1]), call.symbol.owner.parentAsClass.defaultType) } call.extensionReceiver = call.symbol.owner.extensionReceiverParameter?.let { - if (hasBoundReceiver) - irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type) + if (call.symbol.owner.dispatchReceiverParameter == null) + receiverFromField ?: irImplicitCast(irGet(arguments[1]), it.type) else - irImplicitCast(irGet(arguments[index++]), it.type) + irImplicitCast(irGet(arguments[if (receiverFromField != null) 1 else 2]), it.type) } } diff --git a/compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt b/compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt new file mode 100644 index 00000000000..fefd093c881 --- /dev/null +++ b/compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt @@ -0,0 +1,21 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: WASM +// FILE: 1.kt +package a + +open class A { + protected val v = "O" + protected var w = "" +} + +// FILE: 2.kt +import a.* + +class B : A() { + fun foo(): String { + B::w.set(this, "K") + return ::v.get() + B::w.get(this) + } +} + +fun box() = B().foo() 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 e169b93bd59..2d7ad275648 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 @@ -39251,6 +39251,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @Test + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + @Test public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); 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 f1aaa6b23e9..5c53ee8f893 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 @@ -39269,6 +39269,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @Test + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + @Test public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4f2f23347fd..3e06fa0e6cd 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -31426,6 +31426,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } diff --git a/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/VisualizerBlackBoxTestGenerated.java b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/VisualizerBlackBoxTestGenerated.java index 875998c8d14..bc09a31150c 100644 --- a/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/VisualizerBlackBoxTestGenerated.java +++ b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/VisualizerBlackBoxTestGenerated.java @@ -39388,6 +39388,12 @@ public class VisualizerBlackBoxTestGenerated extends AbstractVisualizerBlackBoxT runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @Test + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + @Test public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, true); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 88a8a04213f..1ef87feae8d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -26561,6 +26561,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 415fd065dc6..62cc9d57f5d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -25982,6 +25982,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 8ff28762f32..1eca5a46681 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -25942,6 +25942,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 69ac7a39ff2..ab95f6273a6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -14379,6 +14379,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedInvokeVirtual.kt"); } + @TestMetadata("accessorForProtectedPropertyReference.kt") + public void testAccessorForProtectedPropertyReference() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/accessorForProtectedPropertyReference.kt"); + } + public void testAllFilesPresentInSyntheticAccessors() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/syntheticAccessors"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); }