This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Fortran] Fix gfortran.df/module_equivalence_1.f90 on HPUX


The following patch addresses the failure of module_equivalence_1.f90
on PA/HPUX, but the underlying problem is present on all platforms,
though harmlessly latent on Linux (and others?).

The failure on PA/HPUX is caused by the assembler complaining about
duplicate .comm lines for the symbol test_equiv.eq.1.  This failure
may be reproduced on other platforms by compiling module_equivalence_1.f90
and noticing that the symbol test_equiv.eq.1 is indeed emitted multiple
times in the assembly language output.  On x86/Linux, we see

        .comm   my_common_,32,32
        .comm   test_equiv.eq.1_,16,16
        .comm   test_equiv.eq.1_,16,16
        .comm   test_equiv.eq.1_,16,16

Presumably gas on HPUX is stricter than gas on Linux.


After some investigation and much head scratching it appeared that the
reason was that trans-common.c:build_common_decl was creating multiple
DECLs for the same symbol.  This was baffling because the logic in
that function uses a global "gfc_common_ns" namespace to keep track
of it's common block symbols, which looks like it should be resusing
a single gfc_symbol, and thereby avoiding any possibility of duplicates.

Eventually, I discovered that the gfortran front-end uses a commit or
rollback mechanism for symbol creation, and that recently created
gfc_symbols may be destroyed/revoked if they aren't explicitly committed.
This then pointed to the logic error, corrected below, where in the
function gfc_trans_common, it calls gfc_commit_symbols before calling
finish_equivalences, which may itself create symbols via create_common.
Unfortunately, none of these symbols (including the problematic
test_equiv.eq.1 described above) are guaranteed to be committed,
and may unintentionally be revoked by the next statements commit/rollback
decision.  The fix is to simply move the call to gfc_commit_symbols in
gfc_trans_common after finish_equivalences, where it becomes the last
call in that function.

Unless, of course, I'm missing something and this duplicate declaration
logic is intentional (but non-portable)?

The following patch has been tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", including gfortran, and tested with a top-level
"make -k check" with no new failures.  Inspecting the assembler output
reveals that we now emit one ".comm" directive for test_equiv.eq.1
instead of the three lines we did previously.

Ok for mainline?



2006-04-30  Roger Sayle  <roger@eyesopen.com>

	* trans-common.c (gfc_trans_common): Call gfc_commit_symbols after
	finish_equivalences to commit symbols created there.


Index: trans-common.c
===================================================================
*** trans-common.c	(revision 113392)
--- trans-common.c	(working copy)
*************** gfc_trans_common (gfc_namespace *ns)
*** 1057,1065 ****
    /* Translate all named common blocks.  */
    gfc_traverse_symtree (ns->common_root, named_common);

-   /* Commit the newly created symbols for common blocks.  */
-   gfc_commit_symbols ();
-
    /* Translate local equivalence.  */
    finish_equivalences (ns);
  }
--- 1057,1065 ----
    /* Translate all named common blocks.  */
    gfc_traverse_symtree (ns->common_root, named_common);

    /* Translate local equivalence.  */
    finish_equivalences (ns);
+
+   /* Commit the newly created symbols for common blocks.  */
+   gfc_commit_symbols ();
  }


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]