Skip to content

Commit 4ba8819

Browse files
committed
[5.9][Runtime] Immediate release and return when destroying partial instance of pure ObjC class.
Make swift_deallocPartialClassInstance check if the object's class is a pure ObjC class, in which case there are no ivar destroyers and we can just return immediately. It's possible for an allocWithZone: override to cause self to be a special object constructed in read-only memory. swift_deallocPartialClassInstance calls object_setClass to avoid running the dealloc method of any Swift subclasses, but this call crashes if self is read-only. It's unnecessary when the object's class is pure ObjC and therefore there are no Swift subclasses, so just skip it entirely. rdar://107756747 (cherry picked from commit 3a396af)
1 parent 9c997ce commit 4ba8819

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

stdlib/public/runtime/HeapObject.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,17 @@ void swift::swift_deallocPartialClassInstance(HeapObject *object,
849849
// Destroy ivars
850850
auto *classMetadata = _swift_getClassOfAllocated(object)->getClassObject();
851851
assert(classMetadata && "Not a class?");
852+
853+
#if SWIFT_OBJC_INTEROP
854+
// If the object's class is already pure ObjC class, just release it and move
855+
// on. There are no ivar destroyers. This avoids attempting to mutate
856+
// placeholder objects statically created in read-only memory.
857+
if (classMetadata->isPureObjC()) {
858+
objc_release((id)object);
859+
return;
860+
}
861+
#endif
862+
852863
while (classMetadata != metadata) {
853864
#if SWIFT_OBJC_INTEROP
854865
// If we have hit a pure Objective-C class, we won't see another ivar

0 commit comments

Comments
 (0)