JVM_IR: do not evaluate receiver of static calls if it is pure
#KT-46802 Fixed
This commit is contained in:
+12
@@ -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 {
|
||||
|
||||
+10
-6
@@ -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
|
||||
|
||||
|
||||
+12
@@ -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")
|
||||
Vendored
+23
@@ -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
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user