Function pointers to a nested function / contained procedure

Richard Biener richard.guenther@gmail.com
Wed Mar 27 09:26:00 GMT 2019


On Wed, Mar 27, 2019 at 10:09 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Wed, Mar 27, 2019 at 10:02:21AM +0100, Richard Biener wrote:
> > On Wed, Mar 27, 2019 at 8:48 AM Thomas König <tk@tkoenig.net> wrote:
> > >
> > > Hi Eric,
> > > > There is an entire machinery in the middle-end and the back-ends to support this (look for trampolines/descriptors in the manual and the source code). This should essentially work out of the box for any language front-end.
> > > Thanks for the pointer. The documentation I have seen seems to point out what to do in a back end to implement this, less towards what to do in a front end. And the source is big :-)
> > > Could somebody maybe shed some additional light on what magic I would have to invoke in the Fortran front end?
> >
> > I think the only thing required is that the function nesting is
> > appearant by means of DECL_CONTEXT of the inner function being
> > the outer function.  Of course accesses of outer function variables
> > from the inner function have to use the same decl tree
> > (not just a copy of the decl with the same name).
>
> Yeah, and then tree-nested.c should do most of the magic needed to make it
> working (plus expansion emit trampolines unless target has some other ways
> to pass the static chain pointer).
>
> Just look what will
>
> __attribute__((noipa)) void foo (void (*fn) (void))
> {
>   fn ();
>   fn ();
> }
>
> int
> main ()
> {
>   int i = 0;
>   void bar (void) { i++; }
>   foo (bar);
>   return i - 2;
> }
>
> do in C, the attribute is there to make sure it isn't inlined or otherwise
> IPA optimized.

Btw, I've looked at the bug and the issue there is the FE does

void foo()
{
  int a;
  int bar()
    {
      return a;
    }

  static int (*bp)() = bar;
  bp();
}

that is, tries to statically initialize the procedure pointer.  That causes
the indirect call to not receive a static chain and thus be called with
the wrong ABI.

You can't do that.

Richard.

>
>         Jakub



More information about the Fortran mailing list