https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105180
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jsm28 at gcc dot gnu.org --- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- int global = 0; int foo (void) { ++global; return 1; } void baz (void) { void bar (s, c) char *s; char c[static foo ()]; { } bar ("1", "1"); bar ("1", "1"); bar ("1", "1"); } int main () { baz (); if (global != 3) __builtin_abort (); return 0; } shows that for nested functions those side-effects are emitted, but at a wrong location. The side-effects in that case are evaluated when passing through the definition of bar inside of the baz function, rather than when bar is called. So above, foo () is called just once, not 3 times. If standard C declarations are used: int global = 0; int foo (void) { return ++global; } void bar (char *s, char c[static foo ()]) { } int main () { bar ("1", "1"); if (global != 1) __builtin_abort (); return 0; } then it works properly, in that case the pending sizes are recorded by c_parser_parms_list_declarator -> push_parm_decl -> grokdeclarator and queued by get_parm_info called from c_parser_parms_list_declarator. But in case of K&R argument declarations, those are done by: while (c_parser_next_token_is_not (parser, CPP_EOF) && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) c_parser_declaration_or_fndef (parser, false, false, false, true, false); in c_parser_declaration_or_fndef and in that case that nested c_parser_declaration_or_fndef calls start_decl which after calling grokdeclarator which collects the pending expressions just does: if (expr) add_stmt (fold_convert (void_type_node, expr)); and so it is unclear where exactly it is pushed for the non-nested functions, for nested ones at the current statement location (the definition of nested function). Bet we need to arrange for those side-effects to be instead remembered somewhere and queued into pending_sizes later.