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

Reply via email to