Fix for PR libobjc/49883 ("clang + gcc 4.6 runtime = broken") and a small related clang fix

Nicola Pero nicola.pero@meta-innovation.com
Tue Oct 11 09:15:00 GMT 2011


>> 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.
> 
> The clang folks are pretty responsive.  I'd always give them a chance to `fix' thier code, before putting hack-arounds in our code in general.

That discussion did happen in private.  It wasn't pleasant.  They won't change their code.  In fact,
I just want to fix things and not get into more discussions.

Anyhow, summarizing, the traditional GNU runtime ABI has the values 0x1L or 0x2L in the class->info field.
But there is no formal definition document for the ABI, so all we can say is that GCC has always set that field
to either 0x1L or 0x2L.  By the way, the lack of a formal definition document is a problem, and if, at some point,
I get to implement a new ABI for the GNU Objective-C runtime (which I want to do) I will produce a formal
document describing it - so that anyone can implement a compatible compiler or runtime.

But, for the existing ABI, there is no document describing it, hence all that can be said is that GCC only stores
the values 0x1L or 0x2L in the class->field.  The GNU runtime then uses some of the other bits to store information
on the class at runtime - eg. when the class is +initialized it sets a bit, when it is resolved it sets another, etc.

clang started abusing a higher bit of that field to store information not normally present in the ABI.  That worked
with older versions of the GNU runtime, because (by sheer chance in my view) the higher bit they set was not
being used.  The fact that it was not being used was an implementation accident (in my view) since other higher
bits were actually used.

The new GNU runtime included in GCC 4.6.x and higher has classes "in construction" (part of the new Objective-C
API) and so the next available bit in the class->info field was used to keep track of the fact that a class is in
construction.  That was just the next available bit, but (unknown to me) it is precisely the bit that clang was (ab)using.
As a consequence, code compiled with clang no longer works with the GNU runtime from GCC 4.6.x.  As there is no
formal definition document for the ABI, while it seems obvious to me that they broke the ABI (since they produce
object files with some reserved bits set that no version of GCC would ever produce), they claim they didn't because
their hack worked with GCC up to 4.5.x and the GNU runtime ignored whether that bit was set or not - up until 4.5.x.

It's a standoff because they use that higher bit to basically produce a richer ABI, so they can't easily get rid
of it now, and they won't.  The hack-around I added clears this higher bit, unlocks the standoff and gets things
to work again.

Let's hope there are no more such issues, and if we introduce a new GNU Objective-C runtime ABI, we need
to make sure it is well documented so that it is possible to easily ensure compatibility between different compilers
and runtimes.

Thanks



More information about the Gcc-patches mailing list