http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49883
Summary: clang + gcc 4.6 runtime = broken Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libobjc AssignedTo: unassig...@gcc.gnu.org ReportedBy: nic...@gcc.gnu.org >From Jonathan Schleifer -- > the following code does not work when using Clang with the runtime of gcc 4.6: #include <stdio.h> #include <stdlib.h> #import <objc/runtime.h> @interface A { Class isa; } + alloc; + (Class)class; @end @interface B: A @end @implementation A + alloc { A *instance = malloc(class_getInstanceSize(self)); instance->isa = self; return instance; } + (Class)class { return self; } - (BOOL)isKindOfClass: (Class)class { Class iter; for (iter = isa; iter != Nil; iter = class_getSuperclass(iter)) if (iter == class) return YES; return NO; } @end @implementation B @end int main() { B *b = [B alloc]; printf("%d\n", [b isKindOfClass: [B class]]); printf("%d\n", [b isKindOfClass: [A class]]); return 0; } --- Upon further inspection, it seems likely that clang's Objective-C compiler, when compiling for the GNU runtime, is abusing some fields in the ABI. In particular, it seems that clang is no longer setting the class->info field to 1 or 2, but to something like 17 or 18. This is in my view a bug in clang, but I'm also aware that some users really do need this to be sorted out and backported to 4.6.x. It should be possible to work around the problem by simply detecting the 17 or 18 when loading the class, and converting it to a 1 or 2. I also produced a preliminary (untested) patch to work around this problem -- Index: init.c =================================================================== --- init.c (revision 176090) +++ init.c (working copy) @@ -643,6 +643,14 @@ assert (CLS_ISMETA (class->class_pointer)); DEBUG_PRINTF (" installing class '%s'\n", class->name); + /* 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; but was told that it doesn't work, so someone will now need to install clang and figure out what is actually happening. Thanks