Why does casting a function generate a run-time abort?

Ziemowit Laski zlaski@apple.com
Fri Jun 18 09:24:00 GMT 2004


On 18 Jun 2004, at 1.02, Andrew Pinski wrote:

>>
>> Ziemowit Laski <zlaski@apple.com> writes:
>>
>>> Right; there is an ugly 'if(!c_dialect_objc())' in front of the whole
>>> thing.  Although I do see that an abort is indeed permitted under the
>>> circumstances, I'm still mystified as to why this became an issue in
>>> the first place.  Why not just construct a function call using the
>>> signature specified in the cast?  Aside from not being able to inline
>>> the call, I'm not quite sure what the problem is...
>>
>> A desire to flush out buggy code that *will* fail on platforms with
>> more complicated ABIs, I think, is the main motivation.

Well, it certainly _may_ fail, but the "will" is undecidable in the 
general case. :-(  I think that the ABI problems you describe can also 
be achieved by presenting a wrong function prototype (or no prototype 
at all) to the compiler.  Bad things can and occasionally do happen, 
but ultimately the root cause is pilot error. :-)

>>
>> Lemme ask you why Objective-C message dispatch needs this.  It's
>> impossible to get "right" on IA64 and a few others.

Unlike the GNU runtime, which uses a two-call message dispatch (whereby 
the first call returns a function pointer to call), the NeXT runtime 
does it all in one fell swoop; the messenger looks up the method 
implementation to use, and then immediately _jumps_ to it.  This saves 
us a stack frame tear-down and set-up. :-)  The initial messenger code 
is generic in that it operates only on the first two arguments (self 
and _cmd), which _all_ methods are guaranteed to have.  However, the 
final destination that we jump to may expect much more elaborate 
arguments, and so we must cast the original call site to that second 
signature.  Of course, this is also true for your second GNU-style 
call, so the GNU-vs-NeXT distinction is moot here.

When you say that this is impossible to get right on the Itanium, I 
think you're being too ambitious.  :-)  If  users cast a function to a 
clearly distinct type, I think we should take them at their word.  At 
most, I think we could offer a polite warning that their code may 
behave in unexpected ways.

Alas, I still didn't get any feedback on how/where to fix the 
gimplifier/inline temp variable bloat that results from all this.... 
:-)

>
> It is only needed with the NeXT^wApple runtime :) so ...
> The GNU runtime does not produce these casts at all and is safe.

Not true, Andrew; look at build_objc_method_call() in objc-act.c. :-)  
If you did not provide a sender cast, users writing ObjC code would 
have to ensure that all of their methods are ABI-compatible with IMP 
(e.g., is it OK to return a struct? a void?), which can get hairy 
really fast, and is target-dependent to boot.

And to all a good night,

--Zem



More information about the Gcc mailing list