JVM IR: Mangle overridden symbols in non-inline functions (KT-52394)
This commit is contained in:
+6
@@ -21475,6 +21475,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt52394.kt")
|
||||||
|
public void testKt52394() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt52394.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||||
public void testMangledDefaultParameterFunction() throws Exception {
|
public void testMangledDefaultParameterFunction() throws Exception {
|
||||||
|
|||||||
+3
-15
@@ -343,14 +343,12 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
for (override in irFunction.allOverridden()) {
|
for (override in irFunction.allOverridden()) {
|
||||||
if (override.isFakeOverride) continue
|
if (override.isFakeOverride) continue
|
||||||
|
|
||||||
val target = override.mangleFunctionIfNeeded()
|
val signature = override.jvmMethod
|
||||||
|
|
||||||
val signature = target.jvmMethod
|
|
||||||
if (targetMethod != signature && signature !in blacklist) {
|
if (targetMethod != signature && signature !in blacklist) {
|
||||||
val bridge = generated.getOrPut(signature) {
|
val bridge = generated.getOrPut(signature) {
|
||||||
Bridge(target, signature)
|
Bridge(override, signature)
|
||||||
}
|
}
|
||||||
bridge.overriddenSymbols += target.symbol
|
bridge.overriddenSymbols += override.symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,16 +360,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
.forEach { irClass.addBridge(it, bridgeTarget) }
|
.forEach { irClass.addBridge(it, bridgeTarget) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.mangleFunctionIfNeeded(): IrSimpleFunction {
|
|
||||||
if (!hasMangledReturnType && !hasMangledParameters) return this
|
|
||||||
val replacement = context.inlineClassReplacements.getReplacementFunction(this) ?: return this
|
|
||||||
if (name.asString().substringAfterLast('-') == replacement.name.asString().substringAfterLast('-')) {
|
|
||||||
// function is already mangled
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
return replacement
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrSimpleFunction.isClashingWithPotentialBridge(name: Name, signature: Method): Boolean =
|
private fun IrSimpleFunction.isClashingWithPotentialBridge(name: Name, signature: Method): Boolean =
|
||||||
(!this.isFakeOverride || this.modality == Modality.FINAL) && this.name == name && this.jvmMethod == signature
|
(!this.isFakeOverride || this.modality == Modality.FINAL) && this.name == name && this.jvmMethod == signature
|
||||||
|
|
||||||
|
|||||||
+10
@@ -81,6 +81,16 @@ internal abstract class JvmValueClassAbstractLowering(val context: JvmBackendCon
|
|||||||
val replacement = replacements.getReplacementFunction(function)
|
val replacement = replacements.getReplacementFunction(function)
|
||||||
if (replacement == null) {
|
if (replacement == null) {
|
||||||
function.transformChildrenVoid()
|
function.transformChildrenVoid()
|
||||||
|
// Non-mangled functions can override mangled functions under some conditions, e.g., a function
|
||||||
|
// `fun f(): Nothing` can override a function `fun f(): UInt`. The former is not mangled, while
|
||||||
|
// the latter is.
|
||||||
|
//
|
||||||
|
// This is a potential problem for bridge generation, where we have to ensure that the overridden
|
||||||
|
// symbols are always up to date. Right now they might not be since we lower each file independently
|
||||||
|
// and since deserialized declarations are not mangled at all.
|
||||||
|
if (function is IrSimpleFunction) {
|
||||||
|
function.overriddenSymbols = replacements.replaceOverriddenSymbols(function)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-3
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
|||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||||
import org.jetbrains.kotlin.ir.types.isInt
|
import org.jetbrains.kotlin.ir.types.isInt
|
||||||
@@ -304,11 +305,21 @@ class MemoizedInlineClassReplacements(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overriddenSymbols = function.overriddenSymbols.map {
|
overriddenSymbols = replaceOverriddenSymbols(function)
|
||||||
getReplacementFunction(it.owner)?.symbol ?: it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body()
|
body()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> =
|
||||||
|
storageManager.createMemoizedFunction { irSimpleFunction ->
|
||||||
|
irSimpleFunction.overriddenSymbols.map {
|
||||||
|
computeOverrideReplacement(it.owner).symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeOverrideReplacement(function: IrSimpleFunction): IrSimpleFunction =
|
||||||
|
getReplacementFunction(function) ?: function.also {
|
||||||
|
function.overriddenSymbols = replaceOverriddenSymbols(function)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -29,4 +30,8 @@ class MemoizedMultiFieldValueClassReplacements(
|
|||||||
override val getReplacementFunction: (IrFunction) -> IrSimpleFunction? = storageManager.createMemoizedFunctionWithNullableValues {
|
override val getReplacementFunction: (IrFunction) -> IrSimpleFunction? = storageManager.createMemoizedFunctionWithNullableValues {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol> = storageManager.createMemoizedFunction {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
|
||||||
abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: IrFactory, protected val context: JvmBackendContext) {
|
abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: IrFactory, protected val context: JvmBackendContext) {
|
||||||
/**
|
/**
|
||||||
@@ -17,4 +18,5 @@ abstract class MemoizedValueClassAbstractReplacements(protected val irFactory: I
|
|||||||
|
|
||||||
abstract val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction>
|
abstract val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction>
|
||||||
|
|
||||||
|
abstract val replaceOverriddenSymbols: (IrSimpleFunction) -> List<IrSimpleFunctionSymbol>
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// WITH_REFLECT
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
import kotlin.reflect.full.declaredFunctions
|
||||||
|
|
||||||
|
annotation class Anno(val value: String)
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class A(val value: String)
|
||||||
|
|
||||||
|
abstract class B {
|
||||||
|
@Anno(value = "K")
|
||||||
|
abstract fun f(): A?
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : B() {
|
||||||
|
override fun f(): A? = A("O")
|
||||||
|
}
|
||||||
|
|
||||||
|
class D : B() {
|
||||||
|
override fun f(): Nothing? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val o = if ((D() as B).f() == null) (C() as B).f()!!.value else "Fail"
|
||||||
|
|
||||||
|
val annotations = B::class.declaredFunctions.single().annotations
|
||||||
|
val k = (annotations.single() as Anno).value
|
||||||
|
|
||||||
|
return o + k
|
||||||
|
}
|
||||||
+6
@@ -21001,6 +21001,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt52394.kt")
|
||||||
|
public void testKt52394() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt52394.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||||
public void testMangledDefaultParameterFunction() throws Exception {
|
public void testMangledDefaultParameterFunction() throws Exception {
|
||||||
|
|||||||
+6
@@ -21475,6 +21475,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt52394.kt")
|
||||||
|
public void testKt52394() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt52394.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||||
public void testMangledDefaultParameterFunction() throws Exception {
|
public void testMangledDefaultParameterFunction() throws Exception {
|
||||||
|
|||||||
+5
@@ -17534,6 +17534,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt51672.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt52394.kt")
|
||||||
|
public void testKt52394() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt52394.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||||
public void testMangledDefaultParameterFunction() throws Exception {
|
public void testMangledDefaultParameterFunction() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||||
|
|||||||
Reference in New Issue
Block a user