Fix (and add test case for) a bug where objc_allocateClassPair() failed if the

superclass had not yet been loaded.
main
theraven 13 years ago
parent ae3b44ac78
commit fb2e6756f6

@ -0,0 +1,38 @@
#include "Test.h"
#include <objc/runtime.h>
#include <stdio.h>
// Regression test for a bug where allocating a class as a subclass of an
// unresolved class failed.
static int loaded;
static void load(Class self, SEL _cmd)
{
loaded++;
}
int main()
{
Class a, b, c, d, e;
a = objc_allocateClassPair([Test class], "A", 0);
objc_registerClassPair(a);
b = objc_allocateClassPair(a, "B", 0);
class_addMethod(object_getClass(b), @selector(load), (IMP)load, "@:");
objc_registerClassPair(b);
class_getSuperclass(b);
c = objc_allocateClassPair(b, "C", 0);
objc_registerClassPair(c);
d = objc_allocateClassPair(c, "D", 0);
objc_registerClassPair(d);
e = objc_allocateClassPair(d, "E", 0);
objc_registerClassPair(e);
assert(loaded == 0);
return 0;
}

@ -5,6 +5,7 @@
# List of single-file tests.
set(TESTS
AllocatePair.m
BlockImpTest.m
BoxedForeignException.m
ExceptionTest.m

@ -486,7 +486,7 @@ Class class_getSuperclass(Class cls)
if (Nil == cls) { return Nil; }
if (!objc_test_class_flag(cls, objc_class_flag_resolved))
{
objc_resolve_class(cls);
return objc_getClass((const char*)cls->super_class);
}
return cls->super_class;
}

@ -698,8 +698,18 @@ Class objc_allocateClassPair(Class superclass, const char *name, size_t extraByt
// Initialize the metaclass
// Set the meta-metaclass pointer to the name. The runtime will fix this
// in objc_resolve_class().
metaClass->isa = (Class)superclass->isa->isa->name;
metaClass->super_class = superclass->isa;
// If the superclass is not yet resolved, then we need to look it up
// via the class table.
if (!objc_test_class_flag(superclass, objc_class_flag_resolved))
{
metaClass->super_class = (Class)objc_getClass((char*)superclass->super_class);
metaClass->isa = (Class)metaClass->super_class->isa->name;
}
else
{
metaClass->isa = (Class)superclass->isa->isa->name;
metaClass->super_class = superclass->isa;
}
}
metaClass->name = strdup(name);
metaClass->info = objc_class_flag_meta | objc_class_flag_user_created |

Loading…
Cancel
Save