Skip to content

Commit

Permalink
[K/N][Tests] Fix crashes when casting to an Obj-C class companion
Browse files Browse the repository at this point in the history
When generating section `__objc_classrefs`, need to consider distinguishing
`_OBJC_CLASS_$_` and `_OBJC_METACLASS_$_`
  • Loading branch information
edisongz committed Mar 29, 2024
1 parent 757812a commit abdeced
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1331,14 +1331,17 @@ internal abstract class FunctionGenerationContext(
generationState.dependenciesTracker.add(irClass)
if (irClass.isObjCMetaClass()) {
val name = irClass.getExternalObjCMetaClassBinaryName()
val objCClass = getObjCClass(name, isMetaclass = true)
val objCClass = getObjCClass(name)

val getClass = llvm.externalNativeRuntimeFunction(
"object_getClass",
LlvmRetType(llvm.int8PtrType),
listOf(LlvmParamType(llvm.int8PtrType))
)
call(getClass, listOf(objCClass), exceptionHandler = exceptionHandler)

val objCMetaclass = getObjCClass(name, isMetaclass = true)
call(getClass, listOf(objCMetaclass), exceptionHandler = exceptionHandler)
} else {
getObjCClass(irClass.getExternalObjCClassBinaryName())
}
Expand Down
31 changes: 25 additions & 6 deletions native/native.tests/testData/codegen/cinterop/objc/kt65260.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,37 @@
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import platform.Foundation.*
import platform.darwin.*
import kotlinx.cinterop.internal.*
import kotlin.test.*

fun box(): String {
fun test1() {
try {
// Test: cast to NSObject Metaclass
Any() as NSObject.Companion
// Test: cast to subclass of NSObject Metaclass
Any() as NSString.Companion
Any() as NSArray.Companion
} catch (e: Exception) {
// Cannot access 'TypeCastException': it is internal in Kotlin/Native.
assertTrue(e is ClassCastException)
}
}

fun test2() {
try {
Any() as NSNumber.Companion
} catch (e: Exception) {
assertTrue(e is ClassCastException)
}
}

fun test3() {
assertFalse(Any() is NSObject.Companion)
assertFalse(Any() is NSNumber.Companion)

val nsObjectClass: Any = NSObject
assertFalse(nsObjectClass is NSNumberMeta)
}

fun box(): String {
test1()
test2()
test3()

return "OK"
}

0 comments on commit abdeced

Please sign in to comment.