Dave Korn wrote:
> This is now PR40309. Looks almost trivially easy to fix for anyone familiar
> with the structure of the fortran frontend.
Less so for someone like me who has no real clue about fortran internals,
though. I see there are two places in fortran/parse.c that call
main_program_symbol(): either as a result of a PROGRAM statement
case ST_PROGRAM:
if (seen_program)
goto duplicate_main;
seen_program = 1;
prog_locus = gfc_current_locus;
push_state (&s, COMP_PROGRAM, gfc_new_block);
main_program_symbol(gfc_current_ns, gfc_new_block->name);
... or if the code starts with a nameless block:
/* Anything else starts a nameless main program block. */
default:
if (seen_program)
goto duplicate_main;
seen_program = 1;
prog_locus = gfc_current_locus;
push_state (&s, COMP_PROGRAM, gfc_new_block);
main_program_symbol (gfc_current_ns, "MAIN__");
One thing I don't understand is why there is a function
gfc_sym_mangled_function_id() in trans-decl.c that has this code:
/* Main program is mangled into MAIN__. */
if (sym->attr.is_main_program)
return get_identifier ("MAIN__");
Is this something to do with the relationship between fortran symbols and
their mangled assembler equivalents? What happens if we have a named program
section that isn't called "MAIN__"? Won't this return the wrong identifier?
It appears that this or something else is causing both functions to have the
same DECL_NAME when they are passed to gimple_expand_cfg() in cfgexpand.c, so
they both get identified as the main function and potentially have static ctor
calls to __main() inserted. This is because the testcase I'm looking at uses
a "program main" directive. The two function decls have different underlying
sym_refs - "MAIN__" vs. "main" - but they both point to the same
IDENTIFIER_NODE, for "main" in their DECL_NAME fields.
I think this is probably an invalid way for the front-end to drive the
mid-end - it's ok when the two functions are semantically the same, as when
C++ clones constructors, but these are actually two entirely different
functions, and in particular, only one of them should cause
expand_main_function to be called. I'd like that to be the real "main"
function, which is where the fortran runtime init gets called, rather than
"MAIN__", which is the user-level main function, because the runtime init
itself might need to use st_printf and that won't work until __main() is
called, but I'm not sure how to disetangle the two now.
cheers,
DaveK