public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Function pointers to a nested function / contained procedure
@ 2019-03-26 21:55 Thomas Koenig
  2019-03-26 22:25 ` Eric Botcazou
  0 siblings, 1 reply; 6+ messages in thread
From: Thomas Koenig @ 2019-03-26 21:55 UTC (permalink / raw)
  To: gcc mailing list, fortran

Hello world,

Fortran allows pointers to contained procedures (other languages
might call this nested functions), and also allows them to be
called using procedure pointers (function pointers in C).  This is
permitted as long as the host instance is still active (the parent
function is still running).

Contained procedures can access variables in their host instance.

gfortran currently allows procedure pointers to contained procedures,
but the association of variables in the host instance fails (PR 85537),
so accessing such a variable (usually) results in a segfault.

At the moment, I am at a loss of how to try to fix this.  Any ideas?
Is there any other language which has such a feature, so a bit of
judicious copy & paste could be applied?

Regards

	Thomas

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Function pointers to a nested function / contained procedure
  2019-03-26 21:55 Function pointers to a nested function / contained procedure Thomas Koenig
@ 2019-03-26 22:25 ` Eric Botcazou
  0 siblings, 0 replies; 6+ messages in thread
From: Eric Botcazou @ 2019-03-26 22:25 UTC (permalink / raw)
  To: Thomas Koenig; +Cc: gcc, fortran

> At the moment, I am at a loss of how to try to fix this.  Any ideas?
> Is there any other language which has such a feature, so a bit of
> judicious copy & paste could be applied?

(GNU) C and Ada since the dawn of time.  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.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Function pointers to a nested function / contained procedure
  2019-03-27  9:09   ` Jakub Jelinek
@ 2019-03-27  9:26     ` Richard Biener
  0 siblings, 0 replies; 6+ messages in thread
From: Richard Biener @ 2019-03-27  9:26 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Thomas König, GCC Development, fortran

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Function pointers to a nested function / contained procedure
  2019-03-27  9:02 ` Richard Biener
@ 2019-03-27  9:09   ` Jakub Jelinek
  2019-03-27  9:26     ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2019-03-27  9:09 UTC (permalink / raw)
  To: Richard Biener; +Cc: Thomas König, GCC Development, fortran

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.

	Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Function pointers to a nested function / contained procedure
  2019-03-27  7:48 Thomas König
@ 2019-03-27  9:02 ` Richard Biener
  2019-03-27  9:09   ` Jakub Jelinek
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2019-03-27  9:02 UTC (permalink / raw)
  To: Thomas König; +Cc: GCC Development, fortran

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).

Richard.

> Regards, Thomas

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Function pointers to a nested function / contained procedure
@ 2019-03-27  7:48 Thomas König
  2019-03-27  9:02 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Thomas König @ 2019-03-27  7:48 UTC (permalink / raw)
  To: gcc, fortran

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?

Regards, Thomas

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-03-27  9:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-26 21:55 Function pointers to a nested function / contained procedure Thomas Koenig
2019-03-26 22:25 ` Eric Botcazou
2019-03-27  7:48 Thomas König
2019-03-27  9:02 ` Richard Biener
2019-03-27  9:09   ` Jakub Jelinek
2019-03-27  9:26     ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).