diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2006-05-02 14:13:17 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-05-02 14:13:17 +0000 |
commit | 613e2ac8d3dc830f03c00b165ffcf85b96717240 (patch) | |
tree | 5e8905912be5f73f8c12dcef22be42404b8d7168 /gcc/fortran/module.c | |
parent | 597fb86c9078a5d7e1e84b222eb18012263cfb8c (diff) | |
download | gcc-613e2ac8d3dc830f03c00b165ffcf85b96717240.zip gcc-613e2ac8d3dc830f03c00b165ffcf85b96717240.tar.gz gcc-613e2ac8d3dc830f03c00b165ffcf85b96717240.tar.bz2 |
re PR fortran/27269 (Segfault with EQUIVALENCEs in modules together with ONLY clauses)
2006-05-02 Paul Thomas <pault@gcc.gnu.org>
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.
From-SVN: r113465
Diffstat (limited to 'gcc/fortran/module.c')
-rw-r--r-- | gcc/fortran/module.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 9949ccd..a5722c6 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 |