Skip to content

Commit 3542ea3

Browse files
authored
Fix AutoreleasingUnsafeMutablePointer assignment. (#3727)
Fix the implementation to obey the memory model by using `withMemoryRebound`. Also move toward using `Unsafe` not `Opaque`.
1 parent 2add29c commit 3542ea3

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,15 +408,22 @@ public struct AutoreleasingUnsafeMutablePointer<Pointee /* TODO : class */>
408408
@_transparent nonmutating set {
409409
// Autorelease the object reference.
410410
typealias OptionalAnyObject = AnyObject?
411-
Builtin.retain(unsafeBitCast(newValue, to: OptionalAnyObject.self))
412-
Builtin.autorelease(unsafeBitCast(newValue, to: OptionalAnyObject.self))
411+
let newAnyObject = unsafeBitCast(newValue, to: OptionalAnyObject.self)
412+
Builtin.retain(newAnyObject)
413+
Builtin.autorelease(newAnyObject)
413414
// Trivially assign it as an OpaquePointer; the pointer references an
414415
// autoreleasing slot, so retains/releases of the original value are
415416
// unneeded.
416-
typealias OptionalOpaquePointer = OpaquePointer?
417-
let p = UnsafeMutablePointer<OptionalOpaquePointer>(
418-
UnsafeMutablePointer<Pointee>(self))
419-
p.pointee = unsafeBitCast(newValue, to: OptionalOpaquePointer.self)
417+
typealias OptionalUnmanaged = Unmanaged<AnyObject>?
418+
UnsafeMutablePointer<Pointee>(_rawValue).withMemoryRebound(
419+
to: OptionalUnmanaged.self, capacity: 1) {
420+
if let newAnyObject = newAnyObject {
421+
$0.pointee = Unmanaged.passUnretained(newAnyObject)
422+
}
423+
else {
424+
$0.pointee = nil
425+
}
426+
}
420427
}
421428
}
422429

0 commit comments

Comments
 (0)