On Wed, Mar 27, 2019 at 10:09 AM Jakub Jelinek <ja...@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 <t...@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