JVM_IR: do not evaluate receiver of static calls if it is pure

#KT-46802 Fixed
This commit is contained in:
pyos
2021-05-19 09:45:11 +02:00
committed by TeamCityServer
parent ae1590d3cf
commit f1f13b6e97
7 changed files with 91 additions and 6 deletions
@@ -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 {
@@ -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
@@ -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")
@@ -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
}
@@ -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 {
@@ -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 {
@@ -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");