Patchwork libobjc: Fixed gnu-api-2-objc.m testcase

login
register
mail settings
Submitter Nicola Pero
Date June 5, 2011, 11:10 a.m.
Message ID <8DDA2652-35B9-4FFC-A253-6A31FF9DEECE@meta-innovation.com>
Download mbox | patch
Permalink /patch/98760/
State New
Headers show

Comments

Nicola Pero - June 5, 2011, 11:10 a.m.
This patch fixes two errors in the gnu-api-2-objc.m testcase for libobjc's Modern Objective-C API.

One of them is that class_addIvar() was called with the alignment, instead of the log2 of the alignment,
being passed as argument.  The error slipped in because a previous, buggy version of libobjc's class_addIvar()
didn't use the log2, and when fixing libobjc it seems I forgot to update this testcase.  It's important to fix this
in case people look at the testcase as an example of how to use the API. ;-)

The other one is that a root class was created, and an instance of it instantiated, without the required "isa" instance
variable to hold the Class.  This error slipped in because the instantiation was added later without realizing
the root class was a test, fake class without the required variable.  This is more serious and could cause the
testcase to fail under some conditions, depending on how the memory is allocated.  This patch fixes it. :-)

Committed to trunk.

Thanks

PS: I noticed that these testcases, and the gnu-api-2-class.m[m] ones, are failing on Apple m64.  That's a separate
issue and I'll submit a separate patch.

Patch

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 174655)
+++ ChangeLog   (working copy)
@@ -1,3 +1,10 @@ 
+2011-06-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/gnu-api-2-objc.m: Fixed testcase.  Use log2 of the
+       alignment, not the alignment, when calling class_addIvar().  Add
+       an 'isa' instance variable to the test root class.
+       * obj-c++.dg/gnu-api-2-objc.mm: Likewise.
+       
 2011-06-04  Jan Hubicka  <jh@suse.cz>
 
        PR tree-optimization/48893
Index: objc.dg/gnu-api-2-objc.m
===================================================================
--- objc.dg/gnu-api-2-objc.m    (revision 174655)
+++ objc.dg/gnu-api-2-objc.m    (working copy)
@@ -45,7 +45,24 @@ 
 - (id) variable { return variable_ivar; }
 @end
 
+/* Hack to calculate the log2 of a byte alignment.  */
+unsigned char
+log_2_of (unsigned int x)
+{
+  unsigned char result = 0;
 
+  /* We count how many times we need to divide by 2 before we reach 1.
+     This algorithm is good enough for the small numbers (such as 8,
+     16 or 64) that we have to deal with.  */
+  while (x > 1)
+    {
+      x = x / 2;
+      result++;
+    }
+
+  return result;
+}
+
 int main(int argc, void **args)
 {
   /* Functions are tested in alphabetical order.  */
@@ -56,8 +73,9 @@  int main(int argc, void **args)
     Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
 
     /* A new root class would obviously need at least an 'isa'
-       instance variable.  We don't add it so we never actually
-       instantiate an instance of the class, which wouldn't work.  */
+       instance variable.  */
+    class_addIvar (new_root_class, "isa", sizeof (Class), log_2_of (__alignof__ (Class)),
+                  @encode (Class));
 
     objc_registerClassPair (new_root_class);
     objc_registerClassPair (new_class);
@@ -114,7 +132,7 @@  int main(int argc, void **args)
     /* Add a bit of everything to the class to exercise undoing all these changes.  */
 
     /* Instance variable.  */
-    class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
+    class_addIvar (new_class, "my_variable", sizeof (float), log_2_of (__alignof__ (float)), @encode (float));
 
     /* Instance method.  */
     class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),
Index: obj-c++.dg/gnu-api-2-objc.mm
===================================================================
--- obj-c++.dg/gnu-api-2-objc.mm        (revision 174655)
+++ obj-c++.dg/gnu-api-2-objc.mm        (working copy)
@@ -45,7 +45,24 @@ 
 - (id) variable { return variable_ivar; }
 @end
 
+/* Hack to calculate the log2 of a byte alignment.  */
+unsigned char
+log_2_of (unsigned int x)
+{
+  unsigned char result = 0;
 
+  /* We count how many times we need to divide by 2 before we reach 1.
+     This algorithm is good enough for the small numbers (such as 8,
+     16 or 64) that we have to deal with.  */
+  while (x > 1)
+    {
+      x = x / 2;
+      result++;
+    }
+
+  return result;
+}
+
 int main ()
 {
   /* Functions are tested in alphabetical order.  */
@@ -56,8 +73,9 @@  int main ()
     Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
 
     /* A new root class would obviously need at least an 'isa'
-       instance variable.  We don't add it so we never actually
-       instantiate an instance of the class, which wouldn't work.  */
+       instance variable.  */
+    class_addIvar (new_root_class, "isa", sizeof (Class), log_2_of (__alignof__ (Class)),
+                  @encode (Class));
 
     objc_registerClassPair (new_root_class);
     objc_registerClassPair (new_class);
@@ -114,7 +132,7 @@  int main ()
     /* Add a bit of everything to the class to exercise undoing all these changes.  */
 
     /* Instance variable.  */
-    class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
+    class_addIvar (new_class, "my_variable", sizeof (float), log_2_of (__alignof__ (float)), @encode (float));
 
     /* Instance method.  */
     class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),