This patch fixes PR libobjc/49883. To fix it, I installed clang and tried out what happens if you compile Objective-C code using clang and targetting the GCC runtime.
Unfortunately, the report was correct in that clang is producing incorrect code and abusing the higher bits of the class->info field to store some other information. On the good side, the fix I proposed in the discussion of PR libobjc/49883 actually works. :-) So, I applied that fix. I also found that clang still emits calls to the objc_lookup_class() function, so this patch also adds that function back into the runtime to get code compiled with clang work. Committed to trunk. Thanks PS: In case anyone wonders, I do want the GNU Objective-C Runtime to be usable with free, non-GCC Objective-C compilers. It should obviously work perfectly with GCC, the GNU compiler, which is its natural partner, but some people would like to use it with other free compilers and that seems a reasonable request. Refusing that request just provides an incentive to write and support other Objective-C runtimes, which is a waste of time and resources. ;-) Index: init.c =================================================================== --- init.c (revision 179711) +++ init.c (working copy) @@ -643,6 +643,15 @@ assert (CLS_ISMETA (class->class_pointer)); DEBUG_PRINTF (" installing class '%s'\n", class->name); + /* Workaround for a bug in clang: Clang may set flags other than + _CLS_CLASS and _CLS_META even when compiling for the + traditional ABI (version 8), confusing our runtime. Try to + wipe these flags out. */ + if (CLS_ISCLASS (class)) + __CLS_INFO (class) = _CLS_CLASS; + else + __CLS_INFO (class) = _CLS_META; + /* Initialize the subclass list to be NULL. In some cases it isn't and this crashes the program. */ class->subclass_list = NULL; Index: class.c =================================================================== --- class.c (revision 179711) +++ class.c (working copy) @@ -764,6 +764,15 @@ return objc_get_class (name)->class_pointer; } +/* This is not used by GCC, but the clang compiler seems to use it + when targetting the GNU runtime. That's wrong, but we have it to + be compatible. */ +Class +objc_lookup_class (const char *name) +{ + return objc_getClass (name); +} + /* This is used when the implementation of a method changes. It goes through all classes, looking for the ones that have these methods (either method_a or method_b; method_b can be NULL), and reloads Index: ChangeLog =================================================================== --- ChangeLog (revision 179711) +++ ChangeLog (working copy) @@ -1,3 +1,18 @@ +2011-10-09 Nicola Pero <nicola.p...@meta-innovation.com> + + PR libobjc/49883 + * init.c (__objc_exec_class): Work around a bug in clang's code + generation. Clang sets the class->info field to values different + from 0x1 or 0x2 (the only allowed values in the traditional GNU + Objective-C runtime ABI) to store some additional information, but + this breaks backwards compatibility. Wipe out all the bits in the + fields other than the first two upon loading a class. + +2011-10-09 Nicola Pero <nicola.p...@meta-innovation.com> + + * class.c (objc_lookup_class): Added back for compatibility with + clang which seems to emit calls to it. + 2011-10-08 Richard Frith-Macdonald <r...@gnu.org> Nicola Pero <nicola.p...@meta-innovation.com>