From 477d092bb84e9f1332dfa7db82106d86c020e53d Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Sun, 12 Feb 2023 17:30:21 +0100 Subject: [PATCH] Avoid object's interpretation with nullable type #KT-56215 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++++ .../ir/interpreter/InstructionsUnfolder.kt | 4 ++-- .../jetbrains/kotlin/ir/interpreter/Utils.kt | 4 ++-- .../checker/IrCompileTimeChecker.kt | 4 ++-- .../box/involvesIrInterpreter/kt56215.kt | 22 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../js/test/JsCodegenBoxTestGenerated.java | 6 +++++ .../fir/FirJsCodegenBoxTestGenerated.java | 6 +++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 +++++ .../ir/IrJsES6CodegenBoxTestGenerated.java | 6 +++++ .../K2NativeCodegenBoxTestGenerated.java | 6 +++++ .../NativeCodegenBoxTestGenerated.java | 6 +++++ .../test/IrCodegenBoxWasmTestGenerated.java | 5 +++++ 15 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/involvesIrInterpreter/kt56215.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 054084f2b3a..bb6c2cd8352 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 @@ -28259,6 +28259,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() throws Exception { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt index ca138c367ef..cc555fbfcb6 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt @@ -256,11 +256,11 @@ private fun unfoldSetField(expression: IrSetField, callStack: CallStack) { } private fun unfoldGetValue(expression: IrGetValue, environment: IrInterpreterEnvironment) { - if (expression.isAccessToObject()) { + if (expression.isAccessToNotNullableObject()) { // used to evaluate constants inside object // TODO is this correct behaviour? val irGetObject = expression.type.classOrNull?.owner!!.createGetObject() - return unfoldGetObjectValue(irGetObject, environment) + return unfoldGetObjectValue(irGetObject, environment) // if object already exists, it will be taken from `mapOfObjects` } environment.callStack.pushState(environment.callStack.loadState(expression.symbol)) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 8a1f9e33be9..64f59850526 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -294,10 +294,10 @@ internal fun IrClass.getSingleAbstractMethod(): IrFunction { return declarations.filterIsInstance().single { it.modality == Modality.ABSTRACT } } -internal fun IrGetValue.isAccessToObject(): Boolean { +internal fun IrGetValue.isAccessToNotNullableObject(): Boolean { val owner = this.symbol.owner val expectedClass = this.type.classOrNull?.owner - if (expectedClass == null || !expectedClass.isObject) return false + if (expectedClass == null || !expectedClass.isObject || this.type.isNullable()) return false return owner.origin == IrDeclarationOrigin.INSTANCE_RECEIVER || owner.name.asString() == "" } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt index cc17c63a9f4..5329f577001 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField import org.jetbrains.kotlin.ir.interpreter.fqName -import org.jetbrains.kotlin.ir.interpreter.isAccessToObject +import org.jetbrains.kotlin.ir.interpreter.isAccessToNotNullableObject import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.statements @@ -160,7 +160,7 @@ class IrCompileTimeChecker( } override fun visitGetValue(expression: IrGetValue, data: Nothing?): Boolean { - return visitedStack.contains(expression.symbol.owner.parent) || expression.isAccessToObject() + return visitedStack.contains(expression.symbol.owner.parent) || expression.isAccessToNotNullableObject() } override fun visitSetValue(expression: IrSetValue, data: Nothing?): Boolean { diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt b/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt new file mode 100644 index 00000000000..8e9b6689783 --- /dev/null +++ b/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt @@ -0,0 +1,22 @@ +object ObjectWithExtension + +fun ObjectWithExtension?.nullableExtensionFun(): String = + if(this == null) + "Null" + else + "Not null" + +fun ObjectWithExtension.extensionFun(): String = + if(this == null) + "Null" // unreachable branch, will be optimized by interpreter + else + "Not null" + +fun box(): String { + val nullObjectWithExtension: ObjectWithExtension? = null + if ("${nullObjectWithExtension.nullableExtensionFun()}" != "Null") return "Fail 1" + if ("${ObjectWithExtension.nullableExtensionFun()}" != "Not null") return "Fail 2" + + if ("${ObjectWithExtension.extensionFun()}" != "Not null") return "Fail 3" + return "OK" +} 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 2f6758e126d..9ee0c751d14 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 @@ -27149,6 +27149,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") 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 f7fdc9df68e..eb570f58a32 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 @@ -28259,6 +28259,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() 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 95ccfe7a5dc..3588f216089 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -22887,6 +22887,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index f59b56f4e09..92c822c8bac 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -20977,6 +20977,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index 679f794bfcc..234a29a9f2d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -20995,6 +20995,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest { runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index a821ad3d8d0..9381a27f81a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -20995,6 +20995,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java index 6f4ef93fb26..b600430e545 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java @@ -20995,6 +20995,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java index cf0bf526be3..ac53abc620a 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java @@ -23954,6 +23954,12 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index d07a1c00049..7a1907575ba 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -23720,6 +23720,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @Test + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @Nested @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java index 58ae980209c..bcb0a5a16cb 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java @@ -18635,6 +18635,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt55912.kt"); } + @TestMetadata("kt56215.kt") + public void testKt56215() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); + } + @TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)