Make sure SwiftObject doesn't crash when compared to tagged pointers (#83269)

Fixes rdar://152912840
This commit is contained in:
David Smith
2025-07-25 00:31:01 +00:00
committed by GitHub
parent 6416cd266a
commit a5e6b8556a
2 changed files with 19 additions and 1 deletions

View File

@@ -438,7 +438,13 @@ STANDARD_OBJC_METHOD_IMPLS_FOR_SWIFT_OBJECTS
// Legacy behavior: Don't proxy to Swift Hashable or Equatable
return NO; // We know the ids are different
}
if (isObjCTaggedPointer(other)) {
// Swift class types cannot be tagged, and a Swift Equatable conformance
// cannot validly be called for an object of a different type, so this can
// only be incorrect if someone has an Equatable that's invalid in an
// extremely specific way (unsafeBitCasting `other` to an unrelated type)
return NO;
}
// Get Swift type for self and other
auto selfMetadata = _swift_getClassOfAllocated(self);

View File

@@ -22,6 +22,10 @@ struct MyNonEquatableStruct {
var text: String
}
class MyEquatableClass: Equatable {
static func == (lhs: MyEquatableClass, rhs: MyEquatableClass) -> Bool { true }
}
BridgeEquatableToObjC.test("Bridge equatable struct") {
let swiftA = MyEquatableStruct(text: "xABC")
let swiftB = swiftA
@@ -46,5 +50,13 @@ BridgeEquatableToObjC.test("Bridge non-equatable struct") {
expectEqual(objcResult, false)
}
BridgeEquatableToObjC.test("Compare tagged pointer to equatable SwiftObject") {
let literal = "The quick brown fox jumps over the lazy dog"
let bridgedLiteral = literal as NSString
let foo = MyEquatableClass()
let bridgedFoo = foo as AnyObject
let result = bridgedFoo.isEqual(bridgedLiteral)
expectEqual(result, false)
}
runAllTests()