From 0ea39696e441675fa9c8d2e7dafd5ff6782e241d Mon Sep 17 00:00:00 2001 From: Nicola Pero Date: Sat, 8 Oct 2011 17:52:06 +0000 Subject: [PATCH] In libobjc/: 2011-10-08 Richard Frith-Macdonald Nicola Pero In libobjc/: 2011-10-08 Richard Frith-Macdonald Nicola Pero 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. In gcc/: 2011-10-08 Nicola Pero PR libobjc/50428 * doc/objc.texi (Garbage Collection): Updated example to protect +initialize against execution in subclasses. In gcc/testsuite/: 2011-10-08 Nicola Pero PR libobjc/50428 * objc/execute/initialize-1.m: New test. From-SVN: r179711 --- gcc/ChangeLog | 6 +++ gcc/doc/objc.texi | 3 +- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/objc/execute/initialize-1.m | 47 +++++++++++++++++++++++ libobjc/ChangeLog | 11 ++++++ libobjc/sendmsg.c | 31 +++------------ 6 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/objc/execute/initialize-1.m diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2bd1217c763..edf17165872 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-08 Nicola Pero + + PR libobjc/50428 + * doc/objc.texi (Garbage Collection): Updated example to protect + +initialize against execution in subclasses. + 2011-10-07 Richard Henderson * doc/extend.texi (__builtin_shuffle): Improve the description to diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi index dd04eda82f7..a36b0e70530 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 02a8ffd119e..74ab91220f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-08 Nicola Pero + + PR libobjc/50428 + * objc/execute/initialize-1.m: New test. + 2011-10-08 Paul Thomas 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 00000000000..9ca4aebbe69 --- /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 + +/* 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 b9f87fabec9..f88f2f45cdf 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,14 @@ +2011-10-08 Richard Frith-Macdonald + Nicola Pero + + 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 PR libobjc/50002 diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c index 8aa266dd11f..ea8ea970262 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 -- 2.30.2