The bug was not taking into account implicit runtime DFG edges generated
by associated objects in devirtualization analysis
This commit is contained in:
Igor Chevdar
2020-01-22 14:05:15 +03:00
parent b05ddd4b4a
commit 0338b5aa0f
2 changed files with 26 additions and 0 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
@@ -257,6 +258,22 @@ internal object Devirtualization {
} else {
// String is implicitly created as argument of <main>.
addInstantiatingClass(symbolTable.mapType(context.irBuiltIns.stringType))
// Conservatively assume each associated object could be instantiated.
context.irModule!!.acceptChildrenVoid(object: IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitClass(declaration: IrClass) {
context.getLayoutBuilder(declaration).associatedObjects.values.forEach {
assert (it.kind == ClassKind.OBJECT) { "An object expected but was ${it.dump()}" }
addInstantiatingClass(symbolTable.mapType(it.defaultType))
}
super.visitClass(declaration)
}
})
}
// Traverse call graph from the roots.
rootSet.forEach { dfs(it, it.returnParameter.type) }
@@ -45,14 +45,23 @@ object Baz
fun testGlobalOptimizations1() {
val i1 = I1ImplHolder::class.findAssociatedObject<Associated1>()!! as I1
assertEquals(42, i1.foo())
val c = C(null)
i1.bar(c)
assertEquals("zzz", c.list!![0])
}
private class C(var list: List<String>?)
private interface I1 {
fun foo(): Int
fun bar(c: C)
}
private object I1Impl : I1 {
override fun foo() = 42
override fun bar(c: C) {
c.list = mutableListOf("zzz")
}
}
@Associated1(I1Impl::class)