diff options
Diffstat (limited to 'gcc/fortran/symbol.c')
| -rw-r--r-- | gcc/fortran/symbol.c | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 9a28df6..33af725 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -1345,7 +1345,7 @@ switch_types (gfc_symtree * st, gfc_symbol * from, gfc_symbol * to) gfc_symbol * gfc_use_derived (gfc_symbol * sym) { - gfc_symbol *s, *p; + gfc_symbol *s; gfc_typespec *t; gfc_symtree *st; int i; @@ -1379,15 +1379,7 @@ gfc_use_derived (gfc_symbol * sym) s->refs++; /* Unlink from list of modified symbols. */ - if (changed_syms == sym) - changed_syms = sym->tlink; - else - for (p = changed_syms; p; p = p->tlink) - if (p->tlink == sym) - { - p->tlink = sym->tlink; - break; - } + gfc_commit_symbol (sym); switch_types (sym->ns->sym_root, sym, s); @@ -2238,6 +2230,26 @@ gfc_undo_symbols (void) } +/* Free sym->old_symbol. sym->old_symbol is mostly a shallow copy of sym; but + few components might have been given new values. */ + +static void +free_old_symbol (gfc_symbol * sym) +{ + if (sym->old_symbol == NULL) + return; + + if (sym->old_symbol->as != sym->as) + gfc_free_array_spec (sym->old_symbol->as); + + if (sym->old_symbol->value != sym->value) + gfc_free_expr (sym->old_symbol->value); + + gfc_free (sym->old_symbol); + sym->old_symbol = NULL; +} + + /* Makes the changes made in the current statement permanent-- gets rid of undo information. */ @@ -2253,17 +2265,40 @@ gfc_commit_symbols (void) p->mark = 0; p->new = 0; - if (p->old_symbol != NULL) - { - gfc_free (p->old_symbol); - p->old_symbol = NULL; - } + free_old_symbol (p); } - changed_syms = NULL; } +/* Makes the changes made in one symbol permanent -- gets rid of undo + information. */ + +void +gfc_commit_symbol (gfc_symbol * sym) +{ + gfc_symbol *p; + + if (changed_syms == sym) + changed_syms = sym->tlink; + else + { + for (p = changed_syms; p; p = p->tlink) + if (p->tlink == sym) + { + p->tlink = sym->tlink; + break; + } + } + + sym->tlink = NULL; + sym->mark = 0; + sym->new = 0; + + free_old_symbol (sym); +} + + /* Recursive function that deletes an entire tree and all the common head structures it points to. */ |
