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.