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. # List of single-file tests.
set(TESTS set(TESTS
AllocatePair.m
BlockImpTest.m BlockImpTest.m
BoxedForeignException.m BoxedForeignException.m
ExceptionTest.m ExceptionTest.m

@ -486,7 +486,7 @@ Class class_getSuperclass(Class cls)
if (Nil == cls) { return Nil; } if (Nil == cls) { return Nil; }
if (!objc_test_class_flag(cls, objc_class_flag_resolved)) 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; return cls->super_class;
} }

@ -698,9 +698,19 @@ Class objc_allocateClassPair(Class superclass, const char *name, size_t extraByt
// Initialize the metaclass // Initialize the metaclass
// Set the meta-metaclass pointer to the name. The runtime will fix this // Set the meta-metaclass pointer to the name. The runtime will fix this
// in objc_resolve_class(). // in objc_resolve_class().
// 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->isa = (Class)superclass->isa->isa->name;
metaClass->super_class = superclass->isa; metaClass->super_class = superclass->isa;
} }
}
metaClass->name = strdup(name); metaClass->name = strdup(name);
metaClass->info = objc_class_flag_meta | objc_class_flag_user_created | metaClass->info = objc_class_flag_meta | objc_class_flag_user_created |
objc_class_flag_new_abi; objc_class_flag_new_abi;

Loading…
Cancel
Save