This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]