Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[K/N][Tests] Fix crashes when casting to an Obj-C class companion #5270

Closed
wants to merge 7 commits into from

Conversation

edisongz
Copy link
Contributor

@edisongz edisongz commented Feb 28, 2024

^KT-65260

@ivakub ivakub added the Native label Mar 11, 2024
Copy link
Contributor

@SvyatoslavScherbina SvyatoslavScherbina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests covering the change.

@edisongz edisongz force-pushed the master branch 2 times, most recently from 8be5416 to 764f903 Compare March 21, 2024 03:19
@edisongz edisongz changed the title [K/N] Fix: Crashes when casting to an Obj-C class companion [K/N][Tests] Fix: Crashes when casting to an Obj-C class companion Mar 21, 2024
Copy link
Contributor

@SvyatoslavScherbina SvyatoslavScherbina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior still doesn't seem entirely right:

NSNumber as NSObject.Companion

such a cast should fail, but it succeeds.

@edisongz edisongz force-pushed the master branch 2 times, most recently from abdeced to a110cd6 Compare March 29, 2024 07:46
@edisongz
Copy link
Contributor Author

The behavior still doesn't seem entirely right:

NSNumber as NSObject.Companion

such a cast should fail, but it succeeds.

I have a doubt about this case, corresponding to ObjC.

// This result is YES, ObjC class object is instance of meta class.
BOOL result = [NSNumber isKindOfClass:object_getClass(NSObject.class)]; 

So ThrowTypeCastException branch cannot be reached.
image

@SvyatoslavScherbina
Copy link
Contributor

The behavior still doesn't seem entirely right:

NSNumber as NSObject.Companion

such a cast should fail, but it succeeds.

I have a doubt about this case, corresponding to ObjC.

// This result is YES, ObjC class object is instance of meta class.
BOOL result = [NSNumber isKindOfClass:object_getClass(NSObject.class)]; 

Yes, but semantically NSNumber as NSObject.Companion is not the same.
[NSNumber isKindOfClass:object_getClass(NSObject.class)] is equivalent to NSNumber is NSObjectMeta, which should be true.
But NSNumber is NSObject.Companion has no equivalent in Objective-C. NSObject.Companion is a class that Kotlin synthesizes to reflect the concept of the class object.

NSNumber is NSNumber.Companion == true contradicts general Kotlin rules.
Consider e.g. the following example:

open class A {
    companion object : AMeta()
}
open class AMeta

open class B : A() {
    companion object : BMeta()
}
open class BMeta : AMeta()

fun main() {
    val bAny: Any = B
    println(bAny is A.Companion)
}

It prints false.
A.Companion is a class with only one instance -- A. So B can't be an instance of A.Companion.
Same with NSObject.Companion and NSNumber: NSNumber cant be an instance of NSObject.Companion, only NSObject is.

@edisongz edisongz changed the title [K/N][Tests] Fix: Crashes when casting to an Obj-C class companion [K/N][Tests] Fix crashes when casting to an Obj-C class companion Apr 8, 2024
KotlinBuild pushed a commit that referenced this pull request May 23, 2024
The Native code generator crashed when trying to do generate a
type-checking operation for an "Obj-C class companion" type, e.g.
`NSObject.Companion`. Such a companion object denotes an Objective-C
class object, so the only "instance" of such companion class is the
corresponding Objective-C class object.

The crash happened because the code generator lacked special handling
for the case of companion object classes in question.
This commit fixes the crash by adding such handling: a Kotlin object
is an instance of an "Obj-C companion" <=> its Obj-C peer is the 
corresponding class object, which is checked by plain pointer 
equality operation.

^KT-65260 Fixed
@SvyatoslavScherbina
Copy link
Contributor

Thank you for the contribution!
Merged manually as 450bb1c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants