This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Why does casting a function generate a run-time abort?
On 18 Jun 2004, at 13.23, Richard Henderson wrote:
On Thu, Jun 17, 2004 at 06:57:40PM -0700, Ziemowit Laski wrote:
So, could someone give me some pointers (no pun intended) on how to
make the casting of functions into a first-class citizen in the eyes
of the back-end?
How about a much much better solution -- not casting at all.
You're wanting to do something special with language implementation
internals. Seems to me that the best solution is to represent this
special as well.
We've been talking about various ways to represent method calls in
C++ and Java such that they can be devirtualized during/after
optimization. I wonder if a similar approach can be done here?
For instance, if we added a METHOD_CALL_EXPR to GIMPLE, then we
wouldn't need to expose the objc_msgSend symbol at all at the
tree level; it wouldn't need to show up until we get to rtl.
Yes, I think that what you suggest could work, albeit at the cost of
having
to add additional machinery to GIMPLE.
How about the following: In my original example,
typedef struct objc_Object * foo_id ;
typedef struct blortstruct *blort ;
extern foo_id objc_msgSend(foo_id, ...);
int main(int argc, char * argv[])
{
blort foo = 0, bar = 0 ;
foo_id obj0;
obj0 = ((foo_id ((*)(foo_id, char *, blort, blort))) &objc_msgSend)
(obj0, "foo message", foo, bar);
return 0;
}
we transform
obj0 = ((foo_id ((*)(foo_id, char *, blort, blort))) &objc_msgSend)
(obj0, "foo message", foo, bar);
into something like:
{
extern foo_id objc_msgSend(foo_id, char *, blort, blort);
obj0 = objc_msgSend (obj0, "foo message", foo, bar);
}
?
Presently, this does not entirely work: :-(
/Volumes/DATA2/Proj/Stuff/msgsendkinky.c: In function `main':
/Volumes/DATA2/Proj/Stuff/msgsendkinky.c:10: error: conflicting types
for `objc_msgSend'
/Volumes/DATA2/Proj/Stuff/msgsendkinky.c:3: error: previous
declaration of `objc_msgSend'
/Volumes/DATA2/Proj/Stuff/msgsendkinky.c:10: warning: extern
declaration of `objc_msgSend' doesn't match global one
But perhaps we could add some __attribute__ (my favorite GCC hammer :-)
) to indicate that we really want a local prototype which shadows a
global one, but only in the scope in which it appears:
{
extern foo_id objc_msgSend(foo_id, char *, blort, blort)
__attribute__((local_prototype));
obj0 = objc_msgSend (obj0, "foo message", foo, bar);
}
?
Actually, wait! How about
{
extern foo_id __objc_msgSend_local_nnnn(foo_id, char *, blort,
blort) asm("objc_msgSend");
obj0 = __objc_msgSend_local_nnnn (obj0, "foo message", foo, bar);
}
instead? What do you think?
--Zem