Native: enable lazy IR generation before running fake override builder
^KT-48816 Fixed Native compiler uses lazy IR for declarations provided by cinterop. The problem: `FakeOverrideBuilder` requests super types during type checking, accessing `.owner` for them. So if a type and super type are represented as lazy IR, and lazy IR generation is not enabled yet, then the super type symbol won't be bound by this moment, and the access will fail. This happens in KT-48816: fake override builder tries to access `.owner` for `IrClassSymbol` of `NSObject` (super type of `NSDate` and `NSUUID`). Fix this by enabling lazy IR generation before building fake overrides.
This commit is contained in:
committed by
Space
parent
b76e670ad5
commit
ea7160947a
+1
-2
@@ -363,8 +363,7 @@ internal class KonanIrLinker(
|
||||
}
|
||||
|
||||
override fun postProcess() {
|
||||
if (lazyIrForCaches)
|
||||
stubGenerator.unboundSymbolGeneration = true
|
||||
stubGenerator.unboundSymbolGeneration = true
|
||||
super.postProcess()
|
||||
}
|
||||
|
||||
|
||||
@@ -4327,6 +4327,10 @@ if (PlatformInfo.isAppleTarget(project)) {
|
||||
it.defFile 'interop/objc/kt42172/objclib.def'
|
||||
it.headers "$projectDir/interop/objc/kt42172/objclib.h"
|
||||
}
|
||||
createInterop("objc_kt48816") {
|
||||
it.defFile 'interop/objc/kt48816/objclib.def'
|
||||
it.headers "$projectDir/interop/objc/kt48816/objclib.h"
|
||||
}
|
||||
}
|
||||
|
||||
createInterop("withSpaces") {
|
||||
@@ -4952,6 +4956,20 @@ if (PlatformInfo.isAppleTarget(project)) {
|
||||
}
|
||||
}
|
||||
|
||||
interopTest("interop_objc_kt48816_without_lazy_ir_for_caches") {
|
||||
// Without a fix, fails in two-stage mode.
|
||||
source = "interop/objc/kt48816/main.kt"
|
||||
interop = "objc_kt48816"
|
||||
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature disabled:
|
||||
flags = ["-Xlazy-ir-for-caches=disable"]
|
||||
}
|
||||
|
||||
interopTest("interop_objc_kt48816_with_lazy_ir_for_caches") {
|
||||
source = "interop/objc/kt48816/main.kt"
|
||||
interop = "objc_kt48816"
|
||||
flags = ["-Xlazy-ir-for-caches=enable"]
|
||||
}
|
||||
|
||||
standaloneTest("objc_arc_contract") {
|
||||
doBeforeBuild {
|
||||
mkdir(buildDir)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48816
|
||||
open class Base<Ref> {
|
||||
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
|
||||
return null
|
||||
}
|
||||
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
class Usage: Base<B>()
|
||||
class B
|
||||
|
||||
// The compilation should fail with the above;
|
||||
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
|
||||
|
||||
val B.uuid: NSUUID get() = fail()
|
||||
val B.date: NSDate get() = fail()
|
||||
|
||||
fun test1() {
|
||||
val uuidProperty = B::uuid
|
||||
val dateProperty = B::date
|
||||
val usage = Usage()
|
||||
with(usage) {
|
||||
assertNull(uuidProperty.getValue(usage, uuidProperty))
|
||||
assertNull(dateProperty.getValue(usage, dateProperty))
|
||||
}
|
||||
}
|
||||
|
||||
// One more reproducer, just in case:
|
||||
class Property<out R>
|
||||
|
||||
open class Base2 {
|
||||
fun getValue(property: Property<MyClass1>) = null
|
||||
fun getValue(property: Property<MyClass2>) = null
|
||||
}
|
||||
class Usage2 : Base2()
|
||||
|
||||
fun test2() {
|
||||
val usage = Usage2()
|
||||
assertNull(usage.getValue(Property<MyClass1>()))
|
||||
assertNull(usage.getValue(Property<MyClass2>()))
|
||||
}
|
||||
|
||||
fun main() {
|
||||
test1()
|
||||
test2()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
language = Objective-C
|
||||
headerFilter = **/objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
|
||||
@@ -0,0 +1,9 @@
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface MyClass1 : NSObject
|
||||
@end;
|
||||
|
||||
@interface MyClass2 : NSObject
|
||||
@end;
|
||||
Reference in New Issue
Block a user