]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
In gcc/testsuite/: 2010-12-23 Nicola Pero <nicola.pero@meta-innovation.com>
authorNicola Pero <nicola.pero@meta-innovation.com>
Thu, 23 Dec 2010 05:30:12 +0000 (05:30 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Thu, 23 Dec 2010 05:30:12 +0000 (05:30 +0000)
In gcc/testsuite/:
2010-12-23  Nicola Pero  <nicola.pero@meta-innovation.com>

* obj-c.dg/gnu-api-2-class.m: Test that class_addMethod() returns
NO if the method is already implemented in the class.
* obj-c++.dg/gnu-api-2-class.mm: Same change.

In libobjc/:
2010-12-23  Nicola Pero  <nicola.pero@meta-innovation.com>

* sendmsg.c (class_addMethod): Return NO if the method already
exists in the class.

From-SVN: r168199

gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/gnu-api-2-class.mm
gcc/testsuite/objc.dg/gnu-api-2-class.m
libobjc/ChangeLog
libobjc/sendmsg.c

index 22b83bf675875fddde960fe190bff46a9860183e..7f0c770145f8bdb48122ca89e89e0fed018bc5e9 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-23  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * obj-c.dg/gnu-api-2-class.m: Test that class_addMethod() returns
+       NO if the method is already implemented in the class.
+       * obj-c++.dg/gnu-api-2-class.mm: Same change.
+
 2010-12-22  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR tree-optimization/47019
index d6aa827bc8d976057863da9dc6515aa3d97651f8..da25663d171dcf5b6330b64f129b0853de48fd18 100644 (file)
@@ -140,6 +140,12 @@ int main ()
                           method_getTypeEncoding (method2)))
       abort ();
 
+    /* Test that if the method already exists in the class,
+       class_addMethod() returns NO.  */
+    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+                        method_getTypeEncoding (method2)))
+      abort ();
+
     objc_registerClassPair (new_class);    
 
     /* Now, MySubClass2 is basically the same as MySubClass!  We'll
@@ -152,6 +158,15 @@ int main ()
       if ([o variable] != o)
        abort ();
     }
+
+    /* Now, try that if you take an existing class and try to add an
+       already existing method, class_addMethod returns NO.  This is
+       subtly different from before, when 'new_class' was still in
+       construction.  Now it's a real class and the libobjc internals
+       differ between the two cases.  */
+    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+                        method_getTypeEncoding (method2)))
+      abort ();
   }
 
   std::cout << "Testing class_addProtocol ()...\n";
index 5e0df7e81b17b79b259bf7843997941fdb877093..d38d9c253dc3efbb91c1af8bde5a8272d6d61a48 100644 (file)
@@ -140,6 +140,12 @@ int main(int argc, void **args)
                           method_getTypeEncoding (method2)))
       abort ();
 
+    /* Test that if the method already exists in the class,
+       class_addMethod() returns NO.  */
+    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+                        method_getTypeEncoding (method2)))
+      abort ();
+
     objc_registerClassPair (new_class);    
 
     /* Now, MySubClass2 is basically the same as MySubClass!  We'll
@@ -152,6 +158,15 @@ int main(int argc, void **args)
       if ([o variable] != o)
        abort ();
     }
+
+    /* Now, try that if you take an existing class and try to add an
+       already existing method, class_addMethod returns NO.  This is
+       subtly different from before, when 'new_class' was still in
+       construction.  Now it's a real class and the libobjc internals
+       differ between the two cases.  */
+    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
+                        method_getTypeEncoding (method2)))
+      abort ();
   }
 
   printf ("Testing class_addProtocol ()...\n");
index d1521f94ce9675713775f6e4841c51218544c696..9922b53f709f15902d4c7dce1af13c62ced86cad 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-23  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * sendmsg.c (class_addMethod): Return NO if the method already
+       exists in the class.
+
 2010-12-22  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * init.c (duplicate_classes): New.
index 5192d1619732c3082122809501bbde10cc32d342..983dd78d455727d8e8d55b30e310d3e7f114e1c4 100644 (file)
@@ -759,6 +759,45 @@ class_addMethod (Class class_, SEL selector, IMP implementation,
   if (method_name == NULL)
     return NO;
 
+  /* If the method already exists in the class, return NO.  It is fine
+     if the method already exists in the superclass; in that case, we
+     are overriding it.  */
+  if (CLS_IS_IN_CONSTRUCTION (class_))
+    {
+      /* The class only contains a list of methods; they have not been
+        registered yet, ie, the method_name of each of them is still
+        a string, not a selector.  Iterate manually over them to
+        check if we have already added the method.  */
+      struct objc_method_list * method_list = class_->methods;
+      while (method_list)
+       {
+         int i;
+         
+         /* Search the method list.  */
+         for (i = 0; i < method_list->method_count; ++i)
+           {
+             struct objc_method * method = &method_list->method_list[i];
+             
+             if (method->method_name
+                 && strcmp ((char *)method->method_name, method_name) == 0)
+               return NO;
+           }
+         
+         /* The method wasn't found.  Follow the link to the next list of
+            methods.  */
+         method_list = method_list->method_next;
+       }
+      /* The method wasn't found.  It's a new one.  Go ahead and add
+        it.  */
+    }
+  else
+    {
+      /* Do the standard lookup.  This assumes the selectors are
+        mapped.  */
+      if (search_for_method_in_list (class_->methods, selector))
+       return NO;
+    }
+
   method_list = (struct objc_method_list *)objc_calloc (1, sizeof (struct objc_method_list));
   method_list->method_count = 1;