https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85537

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue seems to be that the indirect call doesn't set up the static
chain and this is because appearantly bar_ptr has static storage duration:

foo ()
{
  static voidD.27 (*<T5c1>) (void) bar_ptrD.3873 = bar_implD.3867;
  integer(kind=4)D.8 D.3885;
  voidD.27 (*<T5c1>) (void) bar_ptr.2_1;
  integer(kind=4)D.8 _2;

  <bb 2> :
  _2 = 0;
  CHAIN.5_4(D)->aD.3880 = _2;
  bar_impl (); [static-chain: CHAIN.5_4(D)]
  bar_ptr.2_1 = bar_ptrD.3873;
  bar_ptr.2_1 ();
  return;

I think this isn't supported:

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

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

> ./cc1 -quiet t.c
t.c: In function ‘foo’:
t.c:9:24: error: initializer element is not constant
    9 |   static int (*bp)() = bar;
      |                        ^~~


I'm not sure how bar_ptr ends up statically allocated, that must be an
error on the FE side - I'd have expected a SAVE to be needed?  And
the FE indeed accepts

      procedure(ibar), pointer, save :: bar_ptr => bar_impl

but it should probably reject that.  The IL it emits is the same, with
or without the save.

TREE_STATIC is set here:

  if (!sym->attr.use_assoc
        && (sym->attr.save != SAVE_NONE || sym->attr.data
              || (sym->value && sym->ns->proc_name->attr.is_main_program)))
    TREE_STATIC (decl) = 1;

beacuse sym->attr.save == SAVE_IMPLICIT

As said, the testcase is invalid if it needs SAVE since that prolongs
lifetime of the static chain over the duration of the contained function.

Reply via email to