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.