From f1f13b6e97daa67644dfe94aaaa3049cc7ad4527 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 19 May 2021 09:45:11 +0200 Subject: [PATCH] JVM_IR: do not evaluate receiver of static calls if it is pure #KT-46802 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../jvm/lower/JvmStaticAnnotationLowering.kt | 16 ++++++++----- .../adaptedReferences/jvmStatic.kt | 12 ++++++++++ .../isInitializedAndDeinitialize/jvmStatic.kt | 23 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../LightAnalysisModeTestGenerated.java | 10 ++++++++ 7 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt create mode 100644 compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.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 ae6aa316d29..10467cec378 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 @@ -2641,6 +2641,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/innerConstructorWithVararg.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt"); + } + @Test @TestMetadata("largeVararg.kt") public void testLargeVararg() throws Exception { @@ -28972,6 +28978,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/isInitializedMultiFile.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt"); + } + @Test @TestMetadata("nonInlineLambda.kt") public void testNonInlineLambda() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt index a9f94286a61..7bfa31302f7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.* -import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext @@ -17,10 +16,10 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.util.* @@ -68,10 +67,15 @@ private fun IrExpression.coerceToUnit(irBuiltIns: IrBuiltIns) = private fun IrMemberAccessExpression<*>.makeStatic(context: JvmBackendContext, replaceCallee: IrSimpleFunction?) = dispatchReceiver?.let { receiver -> dispatchReceiver = null - // Not really the right symbol, but we don't use the scope here anyway. - context.createIrBuilder(symbol).irBlock(startOffset, endOffset) { - +receiver.coerceToUnit(context.irBuiltIns) // evaluate for side effects - +if (replaceCallee != null) irCall(this@makeStatic as IrCall, replaceCallee) else this@makeStatic + val newCall = if (replaceCallee != null) irCall(this@makeStatic as IrCall, replaceCallee) else this@makeStatic + if (receiver.isTrivial()) { + // Receiver has no side effects (aside from maybe class initialization) so discard it. + newCall + } else { + IrBlockImpl(startOffset, endOffset, newCall.type).apply { + statements += receiver.coerceToUnit(context.irBuiltIns) // evaluate for side effects + statements += newCall + } } } ?: this diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt new file mode 100644 index 00000000000..d3bbb65eda6 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// TARGET_BACKEND: JVM +object Test { + @JvmStatic + fun foo(x: String, y: String = "") = x + y +} + +fun callFoo(f: (String) -> String, value: String) = f(value) + +fun test() = Test + +fun box() = callFoo(Test::foo, "O") + callFoo(test()::foo, "K") diff --git a/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt b/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt new file mode 100644 index 00000000000..030de8b1b94 --- /dev/null +++ b/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR +object Test { + @JvmStatic + lateinit var value: Any + + val isInitialized + get() = Test::value.isInitialized + + val isInitializedThroughFn + get() = self()::value.isInitialized + + fun self() = Test +} + +fun box(): String { + if (Test.isInitialized) return "fail 1" + Test.value = "OK" + if (!Test.isInitializedThroughFn) return "fail 2" + return Test.value as String +} \ No newline at end of file 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 3fc400508c8..bf467e0972f 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 @@ -2641,6 +2641,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/innerConstructorWithVararg.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt"); + } + @Test @TestMetadata("largeVararg.kt") public void testLargeVararg() throws Exception { @@ -28948,6 +28954,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/isInitializedMultiFile.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt"); + } + @Test @TestMetadata("nonInlineLambda.kt") public void testNonInlineLambda() 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 05db339530e..7de883def85 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 @@ -2641,6 +2641,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/innerConstructorWithVararg.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt"); + } + @Test @TestMetadata("largeVararg.kt") public void testLargeVararg() throws Exception { @@ -28972,6 +28978,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/isInitializedMultiFile.kt"); } + @Test + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt"); + } + @Test @TestMetadata("nonInlineLambda.kt") public void testNonInlineLambda() 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 17ef57576f9..f8d701f8cf2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2317,6 +2317,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/innerConstructorWithVararg.kt"); } + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/jvmStatic.kt"); + } + @TestMetadata("largeVararg.kt") public void testLargeVararg() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/largeVararg.kt"); @@ -24593,6 +24598,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt"); } + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/jvmStatic.kt"); + } + @TestMetadata("nonInlineLambda.kt") public void testNonInlineLambda() throws Exception { runTest("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/nonInlineLambda.kt");