Highlevel explanation ---------------------- libobjc keeps track of all the modules it has seen. This list of modules seen is used to determine if +load should be sent. If a category on a class is defined in a different module than the class and the class is defined in a module already seen, the category will not be sent the +load message. This bug is also reported for GNUstep as: https://savannah.gnu.org/bugs/?func=detailitem&item_id=9379 And this bug report contains a patch for the libobjc shipped with GNUstep. How to reproduce ---------------- I can't seem to attach files which show the problem, so here goes a description. (For files see the GNUstep bug report mentioned above). * Create two files, A.m and B.m * A.m should contain: implementation of class A including +load implementation implementation of category on B including +load implementation * B.m should contain: implementation of class B including +load implementation implementation of category on A including +load implementation * compile with gcc -o loadTest A.m B.m -lobjc * run and check that 3 of the 4 load implemnetations are called Fix --- I have a patch for the GNUstep libobjc. There are however two problems with it: * It is probably not a very clean fix, so it needs to be improved. But I am not an export on the libobjc runtime. * I do not know for which version of gcc to create a patch. I am willing to modify my patch for gcc, but before I download the gcc sources I would like to have pointer to the relevant version.
Created attachment 6588 [details] testcase program To run this testcase: * unpack the tar file * go to the directory containing the source * compile with: gcc -o loadTest loadTest.m loadOther.m -lobjc * Run: ./loadTest * The output will indicate success or failure.
Hmm, +initialize has the same problem, see PR 14382. Could send the patch to gcc- patches@gcc.gnu.org as that is where patches to libobjc go?
Created attachment 6592 [details] patch for init.c which fixes the +load issue. Will apply cleanly to the GNUstep libobjc.
(In reply to comment #2) > Hmm, +initialize has the same problem, see PR 14382. Actually, I am not sure about that. First of all, the implementation of sending +load and +initialize is completely different. (Which manifest itself in different behaviour). Second, I am not sure if the behaviour should be the same regarding who receives the messages. > Could send the patch to gcc- > patches@gcc.gnu.org as that is where patches to libobjc go? I will attach my patch here. But because this is not created against any gcc version I know of it will most probably not apply cleanly. But at least you can see where the problem is. As I said before, I am willing to modify the patch. But I am hesitant of just grabbing a random version of gcc, figuring out how to compile and install etc. just to create a patch for the wrong version of gcc.
Since gcc is the official home (maintainer) for libobjc, that is why I (as a maintainer of libobjc) requested the patch send to gcc-patches@. Read <http://gcc.gnu.org/contribute.html> for more information on how to contribute. Note GNUStep's libobjc is only exists because the libobjc in gcc was not really being maintained but since it is now and been merged in from GNUStep's, there is only one thing left for gcc's to be able to do that GNUStep's cannot, build by itself (which I will be working on soon).
Author: nicola Date: Tue Dec 21 15:34:19 2010 New Revision: 168122 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168122 Log: In libobjc/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/16110 * init.c (__objc_send_message_in_list): Renamed to __objc_send_load_using_method_list. Do not take an 'op' argument. Register the 'load' selector if needed. (__objc_send_load): Do not register the 'load' selector. Updated call to __objc_send_message_in_list. (__objc_create_classes_tree): Add the class of any claimed category that was loaded in the module to the list of classes for which we try to execute +load. In gcc/testsuite/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/16110 * objc.dg/special/special.exp: Added new test. * objc.dg/special/load-category-1.m: New. * objc.dg/special/load-category-1a.m: New. * objc.dg/special/load-category-1.h: New. Added: trunk/gcc/testsuite/objc.dg/special/load-category-1.h trunk/gcc/testsuite/objc.dg/special/load-category-1.m trunk/gcc/testsuite/objc.dg/special/load-category-1a.m Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/objc.dg/special/special.exp trunk/libobjc/ChangeLog trunk/libobjc/init.c
I fixed this in trunk. Thanks