From a5a0f70a03fbd182e526955a237085e81ef4d5ef Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sat, 14 Apr 2018 08:35:08 +0100 Subject: [PATCH] Unregister classes when deleting them. Coverage checking of the test suite showed that objc_disposeClassPair wasn't tested at all, which then led to discovering that it didn't unregister the class. --- Test/AllocatePair.m | 5 +++++ class.h | 7 +++++++ class_table.c | 6 ++++++ runtime.c | 1 + 4 files changed, 19 insertions(+) diff --git a/Test/AllocatePair.m b/Test/AllocatePair.m index 9a4cf47..1a3f2f3 100644 --- a/Test/AllocatePair.m +++ b/Test/AllocatePair.m @@ -31,6 +31,11 @@ int main() e = objc_allocateClassPair(d, "E", 0); objc_registerClassPair(e); assert(loaded == 0); + assert(objc_getClass("C") == c); + assert(objc_getClass("D") == d); + assert(objc_getClass("E") == e); + objc_disposeClassPair(e); + assert(objc_getClass("E") == nil); return 0; } diff --git a/class.h b/class.h index e7989db..d4baa46 100644 --- a/class.h +++ b/class.h @@ -272,11 +272,18 @@ static inline BOOL objc_test_class_flag(struct objc_class *aClass, return (aClass->info & (unsigned long)flag) == (unsigned long)flag; } + /** * Adds a class to the class table. */ void class_table_insert(Class class); +/** + * Removes a class from the class table. Must be called with the runtime lock + * held! + */ +void class_table_remove(Class cls); + /** * Array of classes used for small objects. Small objects are embedded in * their pointer. In 32-bit mode, we have one small object class (typically diff --git a/class_table.c b/class_table.c index 66d95b1..4344641 100644 --- a/class_table.c +++ b/class_table.c @@ -457,6 +457,12 @@ BOOL objc_registerSmallObjectClass_np(Class class, uintptr_t mask) return YES; } +PRIVATE void class_table_remove(Class cls) +{ + assert(objc_test_class_flag(cls, objc_class_flag_user_created)); + class_table_internal_remove(class_table, (void*)cls->name); +} + //////////////////////////////////////////////////////////////////////////////// // Public API diff --git a/runtime.c b/runtime.c index b3b734f..4b81805 100644 --- a/runtime.c +++ b/runtime.c @@ -719,6 +719,7 @@ void objc_disposeClassPair(Class cls) LOCK_RUNTIME_FOR_SCOPE(); safe_remove_from_subclass_list(meta); safe_remove_from_subclass_list(cls); + class_table_remove(cls); } // Free the method and ivar lists.