summaryrefslogtreecommitdiff
path: root/libobjc
diff options
context:
space:
mode:
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-23 05:30:12 +0000
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-23 05:30:12 +0000
commitd99173cc1253976d3e780be7748c90a9a0514ce1 (patch)
tree4c03d92f75f328d1525418507d7cd68c4f35720f /libobjc
parentb0f6262da886eef8722574a82e0ee94bf55a9673 (diff)
downloadgcc-d99173cc1253976d3e780be7748c90a9a0514ce1.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168199 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc')
-rw-r--r--libobjc/ChangeLog5
-rw-r--r--libobjc/sendmsg.c39
2 files changed, 44 insertions, 0 deletions
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index d1521f94ce9..9922b53f709 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -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.
diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c
index 5192d161973..983dd78d455 100644
--- a/libobjc/sendmsg.c
+++ b/libobjc/sendmsg.c
@@ -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;