diff options
| -rw-r--r-- | gcc/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/doc/objc.texi | 3 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/objc/execute/initialize-1.m | 47 | ||||
| -rw-r--r-- | libobjc/ChangeLog | 11 | ||||
| -rw-r--r-- | libobjc/sendmsg.c | 31 |
6 files changed, 76 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2bd1217..edf1716 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com> + + PR libobjc/50428 + * doc/objc.texi (Garbage Collection): Updated example to protect + +initialize against execution in subclasses. + 2011-10-07 Richard Henderson <rth@redhat.com> * doc/extend.texi (__builtin_shuffle): Improve the description to diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi index dd04eda..a36b0e7 100644 --- a/gcc/doc/objc.texi +++ b/gcc/doc/objc.texi @@ -635,7 +635,8 @@ following class does this: + (void)initialize @{ - class_ivar_set_gcinvisible (self, "weakPointer", YES); + if (self == objc_lookUpClass ("WeakPointer")) + class_ivar_set_gcinvisible (self, "weakPointer", YES); @} - initWithPointer:(const void*)p diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02a8ffd..74ab912 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com> + + PR libobjc/50428 + * objc/execute/initialize-1.m: New test. + 2011-10-08 Paul Thomas <pault@gcc.gnu.org> PR fortran/47844 diff --git a/gcc/testsuite/objc/execute/initialize-1.m b/gcc/testsuite/objc/execute/initialize-1.m new file mode 100644 index 0000000..9ca4aeb --- /dev/null +++ b/gcc/testsuite/objc/execute/initialize-1.m @@ -0,0 +1,47 @@ +/* Contributed by Nicola Pero - Sat 8 Oct 2011 16:47:48 BST */ +#include <objc/objc.h> + +/* Test that if a class has no +initialize method, the superclass + implementation is called. */ + +static int class_variable = 0; + +@interface TestClass +{ + Class isa; +} ++ (void) initialize; ++ (int) classVariable; +@end + +@implementation TestClass ++ (void) initialize +{ + class_variable++; +} ++ (int) classVariable +{ + return class_variable; +} +@end + +@interface TestSubClass : TestClass +@end + +@implementation TestSubClass +@end + +int main (void) +{ + if ([TestClass classVariable] != 1) + { + abort (); + } + + if ([TestSubClass classVariable] != 2) + { + abort (); + } + + return 0; +} diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index b9f87fa..f88f2f4 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,14 @@ +2011-10-08 Richard Frith-Macdonald <rfm@gnu.org> + Nicola Pero <nicola.pero@meta-innovation.com> + + PR libobjc/50428 + * sendmsg.c (__objc_send_initialize): If a class does not have an + +initialize method, search for an +initialize method in the + superclass and in the ancestor classes and execute the first one + that is found. This makes the GNU runtime behave in the same way + as the Apple/NeXT runtime with respect to +initialize methods and + subclassing. + 2011-08-06 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/50002 diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c index 8aa266d..ea8ea97 100644 --- a/libobjc/sendmsg.c +++ b/libobjc/sendmsg.c @@ -516,34 +516,13 @@ __objc_send_initialize (Class class) { SEL op = sel_registerName ("initialize"); - IMP imp = 0; - struct objc_method_list * method_list = class->class_pointer->methods; - - while (method_list) - { - int i; - struct objc_method * method; - - for (i = 0; i < method_list->method_count; i++) - { - method = &(method_list->method_list[i]); - if (method->method_name - && method->method_name->sel_id == op->sel_id) - { - imp = method->method_imp; - break; - } - } - - if (imp) - break; - - method_list = method_list->method_next; - } - if (imp) + struct objc_method *method = search_for_method_in_hierarchy (class->class_pointer, + op); + + if (method) { DEBUG_PRINTF (" begin of [%s +initialize]\n", class->name); - (*imp) ((id) class, op); + (*method->method_imp) ((id)class, op); DEBUG_PRINTF (" end of [%s +initialize]\n", class->name); } #ifdef DEBUG |
