Patchwork libobjc: fix for PR/49882 ("class_getSuperClass() returns nil on a newly allocated, but not registered, class")

login
register
mail settings
Submitter Nicola Pero
Date Aug. 6, 2011, 9:49 a.m.
Message ID <560C940B-E771-49DC-8E50-0F1BD5E8A2B9@meta-innovation.com>
Download mbox | patch
Permalink /patch/108765/
State New
Headers show

Comments

Nicola Pero - Aug. 6, 2011, 9:49 a.m.
This patch fixes PR libobjc/49882.  Applied to trunk.

Thanks

Patch

Index: libobjc/ChangeLog
===================================================================
--- libobjc/ChangeLog	(revision 177503)
+++ libobjc/ChangeLog	(working copy)
@@ -1,3 +1,10 @@ 
+2011-08-06  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	PR libobjc/49882
+	* class.c (class_getSuperclass): Return the superclass if the
+	class is in construction.
+	* objc/runtime.h (class_getSuperclass): Updated documentation.
+
 2011-08-05  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
 	* Makefile.in (INCLUDES): Search
Index: libobjc/class.c
===================================================================
--- libobjc/class.c	(revision 177503)
+++ libobjc/class.c	(working copy)
@@ -923,10 +923,13 @@  class_getSuperclass (Class class_)
   if (class_ == Nil)
     return Nil;
 
-  /* Classes that are in construction are not resolved and can not be
-     resolved!  */
+  /* Classes that are in construction are not resolved, and still have
+     the class name (instead of a class pointer) in the
+     class_->superclass field.  In that case we need to lookup the
+     superclass name to return the superclass.  We can not resolve the
+     class until it is registered.  */
   if (CLS_IS_IN_CONSTRUCTION (class_))
-    return Nil;
+    return objc_lookUpClass ((const char *)(class_->super_class));
   /* If the class is not resolved yet, super_class would point to a
      string (the name of the super class) as opposed to the actual
Index: libobjc/objc/runtime.h
===================================================================
--- libobjc/objc/runtime.h	(revision 177503)
+++ libobjc/objc/runtime.h	(working copy)
@@ -497,10 +497,10 @@  objc_EXPORT const char * class_getName (Class clas
 objc_EXPORT BOOL class_isMetaClass (Class class_);
 
 /* Return the superclass of 'class_'.  If 'class_' is Nil, or it is a
-   root class, return Nil.  If 'class_' is a class being constructed,
-   that is, a class returned by objc_allocateClassPair() but before it
-   has been registered with the runtime using
-   objc_registerClassPair(), return Nil.  */
+   root class, return Nil.  This function also works if 'class_' is a
+   class being constructed, that is, a class returned by
+   objc_allocateClassPair() but before it has been registered with the
+   runtime using objc_registerClassPair().  */
 objc_EXPORT Class class_getSuperclass (Class class_);
 
 /* Return the 'version' number of the class, which is an integer that
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 177503)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -1,3 +1,9 @@ 
+2011-08-06  Nicola Pero  <nicola.pero@meta-innovation.com>
+	
+	PR libobjc/49882
+	* objc.dg/gnu-api-2-class.m (main): Test class_getSuperclass()
+	with classes that are in construction.
+
 2011-08-05  Jason Merrill  <jason@redhat.com>
 
 	PR c++/48993
Index: gcc/testsuite/objc.dg/gnu-api-2-class.m
===================================================================
--- gcc/testsuite/objc.dg/gnu-api-2-class.m	(revision 177503)
+++ gcc/testsuite/objc.dg/gnu-api-2-class.m	(working copy)
@@ -394,6 +394,14 @@  int main(int argc, void **args)
     MySubClass *object = [[MySubClass alloc] init];
     if (class_getSuperclass (object_getClass (object)) != objc_getClass ("MyRootClass"))
       abort ();
+
+    /* Test that it works on a newly created, but not registered, class.  */
+    {
+      Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass3", 0);
+
+      if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
+	abort ();
+    }    
   }
 
   printf ("Testing class_getVersion ()...\n");