Sometimes an interface contains final methods, they shouldn't be in its itable
cause they can't be called virtually
This commit is contained in:
Igor Chevdar
2021-09-01 20:43:24 +05:00
parent 479e7a5169
commit e67a78abaf
3 changed files with 37 additions and 3 deletions
@@ -49,7 +49,6 @@ internal class OverriddenFunctionInfo(
&& function.bridgeDirectionsTo(overriddenFunction).allNotNeeded()
fun getImplementation(context: Context): IrSimpleFunction? {
val target = function.target
val implementation = if (!needBridge)
target
@@ -351,8 +350,11 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context, va
val interfaceVTableEntries: List<IrSimpleFunction> by lazy {
require(irClass.isInterface)
irClass.overridableOrOverridingMethods
.filter { f -> f.isReal || f.overriddenSymbols.any { f.needBridgeTo(it.owner) } }
irClass.simpleFunctions()
.filter { f ->
f.isOverridable && f.bridgeTarget == null
&& (f.isReal || f.overriddenSymbols.any { f.needBridgeTo(it.owner) })
}
.sortedBy { it.uniqueName }
}
@@ -2971,6 +2971,10 @@ task interfaceCallsNCasts_functionNameClash(type: KonanLocalTest) {
source = "codegen/interfaceCallsNCasts/functionNameClash.kt"
}
task interfaceCallsNCasts_finalMethod(type: KonanLocalTest) {
source = "codegen/interfaceCallsNCasts/finalMethod.kt"
}
task interfaceCallsNCasts_diamond(type: KonanLocalTest) {
source = "codegen/interfaceCallsNCasts/diamond.kt"
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package codegen.interfaceCallsNCasts.finalMethod
import kotlin.test.*
interface I1<T> {
fun defaultX(): T
fun foo(x: T = defaultX()): T
}
interface I2 : I1<Int> {
}
class C : I2 {
override fun defaultX() = 42
override fun foo(x: Int) = x
}
@Test
fun runTest() {
val c: I2 = C()
assertEquals(42, c.foo())
}