From 872526115d88f06d87789db91fc77831e3c271ea Mon Sep 17 00:00:00 2001 From: sayle Date: Tue, 2 May 2006 14:13:17 +0000 Subject: [PATCH] 2006-05-02 Paul Thomas PR fortran/27269 * module.c: Add static flag in_load_equiv. (mio_expr_ref): Return if no symtree and in_load_equiv. (load_equiv): If any of the equivalence members have no symtree, free the equivalence and the associated expressions. PR fortran/27324 * trans-common.c (gfc_trans_common): Invert the order of calls to finish equivalences and gfc_commit_symbols. PR fortran/27269 PR fortran/27324 * gfortran.dg/module_equivalence_2.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113465 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 12 +++++++ gcc/fortran/module.c | 42 ++++++++++++++++++++-- gcc/fortran/trans-common.c | 7 ++-- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gfortran.dg/module_equivalence_2.f90 | 24 +++++++++++++ 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/module_equivalence_2.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index f275c5f8dd3..abc6c4a9178 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2006-05-02 Paul Thomas + + PR fortran/27269 + * module.c: Add static flag in_load_equiv. + (mio_expr_ref): Return if no symtree and in_load_equiv. + (load_equiv): If any of the equivalence members have no symtree, free + the equivalence and the associated expressions. + + PR fortran/27324 + * trans-common.c (gfc_trans_common): Invert the order of calls to + finish equivalences and gfc_commit_symbols. + 2006-04-29 Francois-Xavier Coudert PR fortran/25681 diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 9949ccd4f2d..a5722c6682b 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -182,6 +182,9 @@ static gfc_use_rename *gfc_rename_list; static pointer_info *pi_root; static int symbol_number; /* Counter for assigning symbol numbers */ +/* Tells mio_expr_ref not to load unused equivalence members. */ +static bool in_load_equiv; + /*****************************************************************/ @@ -2135,6 +2138,11 @@ mio_symtree_ref (gfc_symtree ** stp) { require_atom (ATOM_INTEGER); p = get_integer (atom_int); + + /* An unused equivalence member; bail out. */ + if (in_load_equiv && p->u.rsym.symtree == NULL) + return; + if (p->type == P_UNKNOWN) p->type = P_SYMBOL; @@ -3008,14 +3016,18 @@ load_commons(void) mio_rparen(); } -/* load_equiv()-- Load equivalences. */ +/* load_equiv()-- Load equivalences. The flag in_load_equiv informs + mio_expr_ref of this so that unused variables are not loaded and + so that the expression can be safely freed.*/ static void load_equiv(void) { - gfc_equiv *head, *tail, *end; + gfc_equiv *head, *tail, *end, *eq; + bool unused; mio_lparen(); + in_load_equiv = true; end = gfc_current_ns->equiv; while(end != NULL && end->next != NULL) @@ -3039,16 +3051,40 @@ load_equiv(void) mio_expr(&tail->expr); } + /* Unused variables have no symtree. */ + unused = false; + for (eq = head; eq; eq = eq->eq) + { + if (!eq->expr->symtree) + { + unused = true; + break; + } + } + + if (unused) + { + for (eq = head; eq; eq = head) + { + head = eq->eq; + gfc_free_expr (eq->expr); + gfc_free (eq); + } + } + if (end == NULL) gfc_current_ns->equiv = head; else end->next = head; - end = head; + if (head != NULL) + end = head; + mio_rparen(); } mio_rparen(); + in_load_equiv = false; } /* Recursive function to traverse the pointer_info tree and load a diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 3b16e5e0065..bf19d12c91f 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -1057,9 +1057,10 @@ gfc_trans_common (gfc_namespace *ns) /* 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); + + /* Commit the newly created symbols for common blocks and module + equivalences. */ + gfc_commit_symbols (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5b92bb4258..e71a7f0b343 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-05-02 Paul Thomas + + PR fortran/27269 + PR fortran/27324 + * gfortran.dg/module_equivalence_2.f90: New test. + 2006-05-02 Jakub Jelinek PR middle-end/27337 diff --git a/gcc/testsuite/gfortran.dg/module_equivalence_2.f90 b/gcc/testsuite/gfortran.dg/module_equivalence_2.f90 new file mode 100644 index 00000000000..3ec8efb41a4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_equivalence_2.f90 @@ -0,0 +1,24 @@ +! { dg-do run } +! Tests the fix for PR27269 and PR27xxx. +! The former caused a segfault in trying to process +! module b, with an unused equivalence in a. The latter +! produced an assembler error due to multiple declarations +! for a module equivalence, when one of the variables was +! initialized, as M in module a. +! +module a + integer, parameter :: dp = selected_real_kind (10) + real(dp) :: reM, M = 1.77d0 + equivalence (M, reM) +end module a + +module b + use a, only : dp +end module b + + use a + use b + if (reM .ne. 1.77d0) call abort () + reM = 0.57d1 + if (M .ne. 0.57d1) call abort () +end -- 2.11.4.GIT