Index: gcc/fortran/symbol.c =================================================================== *** gcc/fortran/symbol.c (révision 116503) --- gcc/fortran/symbol.c (copie de travail) *************** gfc_use_derived (gfc_symbol * sym) *** 1495,1510 **** if (s == NULL || s->attr.flavor != FL_DERIVED) { ! /* Check to see if type has been renamed in parent namespace. ! Leave cleanup of local symbols until the end of the ! compilation because doing it here is complicated by ! multiple association with the same type. */ s = find_renamed_type (sym, sym->ns->parent->sym_root); if (s != NULL) ! { ! switch_types (sym->ns->sym_root, sym, s); ! return s; ! } /* See if sym is identical to renamed, use-associated derived types in sibling namespaces. */ --- 1495,1504 ---- if (s == NULL || s->attr.flavor != FL_DERIVED) { ! /* Check to see if type has been renamed in parent namespace. */ s = find_renamed_type (sym, sym->ns->parent->sym_root); if (s != NULL) ! goto return_use_assoc; /* See if sym is identical to renamed, use-associated derived types in sibling namespaces. */ *************** gfc_use_derived (gfc_symbol * sym) *** 1521,1530 **** s = find_renamed_type (sym, ns->sym_root); if (s != NULL) ! { ! switch_types (sym->ns->sym_root, sym, s); ! return s; ! } } } --- 1515,1521 ---- s = find_renamed_type (sym, ns->sym_root); if (s != NULL) ! goto return_use_assoc; } } *************** gfc_use_derived (gfc_symbol * sym) *** 1557,1562 **** --- 1548,1556 ---- t->derived = s; } + if (sym->attr.use_assoc) + goto return_use_assoc; + st = gfc_find_symtree (sym->ns->sym_root, sym->name); st->n.sym = s; *************** gfc_use_derived (gfc_symbol * sym) *** 1571,1576 **** --- 1565,1578 ---- namelists, common lists and interface lists. */ gfc_free_symbol (sym); + return s; + + return_use_assoc: + /* Use associated types are not freed at this stage because some + references remain to 'sym'. We retain the symbol and leave it + to be cleaned up by gfc_free_namespace, at the end of the + compilation. */ + switch_types (sym->ns->sym_root, sym, s); return s; bad: Index: gcc/testsuite/gfortran.dg/used_types_5.f90 =================================================================== *** gcc/testsuite/gfortran.dg/used_types_5.f90 (révision 0) --- gcc/testsuite/gfortran.dg/used_types_5.f90 (révision 0) *************** *** 0 **** --- 1,59 ---- + ! { dg-do compile } + ! Tests the fix for a further regression caused by the + ! fix for PR28788, as noted in reply #9 in the Bugzilla + ! entry by Martin Reinecke . + ! The problem was caused by certain types of references + ! that point to a deleted derived type symbol, after the + ! type has been associated to another namespace. An + ! example of this is the specification expression for x + ! in subroutine foo below. At the same time, this tests + ! the correct association of typeaa between a module + ! procedure and a new definition of the type in MAIN. + ! + module types + + type :: typea + sequence + integer :: i + end type typea + + type :: typeaa + sequence + integer :: i + end type typeaa + + type(typea) :: it = typea(2) + + end module types + !------------------------------ + module global + + use types, only: typea, it + + contains + + subroutine foo (x) + use types + type(typeaa) :: ca + real :: x(it%i) + common /c/ ca + x = 42.0 + ca%i = 99 + end subroutine foo + + end module global + !------------------------------ + use global, only: typea, foo + type :: typeaa + sequence + integer :: i + end type typeaa + type(typeaa) :: cam + real :: x(4) + common /c/ cam + x = -42.0 + call foo(x) + if (any (x .ne. (/42.0, 42.0, -42.0, -42.0/))) call abort () + if (cam%i .ne. 99) call abort () + end + ! { dg-final { cleanup-modules "types global" } } Index: gcc/testsuite/gfortran.dg/used_types_6.f90 =================================================================== *** gcc/testsuite/gfortran.dg/used_types_6.f90 (révision 0) --- gcc/testsuite/gfortran.dg/used_types_6.f90 (révision 0) *************** *** 0 **** --- 1,37 ---- + ! { dg-do compile } + ! Tests the fix for a further regression caused by the + ! fix for PR28788, as noted in reply #13 in the Bugzilla + ! entry by Martin Tee . + ! The problem was caused by contained, use associated + ! derived types with pointer components of a derived type + ! use associated in a sibling procedure, where both are + ! associated by an ONLY clause. This is the reporter's + ! test case. + ! + MODULE type_mod + TYPE a + INTEGER :: n(10) + END TYPE a + + TYPE b + TYPE (a), POINTER :: m(:) => NULL () + END TYPE b + END MODULE type_mod + + MODULE seg_mod + CONTAINS + SUBROUTINE foo (x) + USE type_mod, ONLY : a ! failed + IMPLICIT NONE + TYPE (a) :: x + RETURN + END SUBROUTINE foo + + SUBROUTINE bar (x) + USE type_mod, ONLY : b ! failed + IMPLICIT NONE + TYPE (b) :: x + RETURN + END SUBROUTINE bar + END MODULE seg_mod + ! { dg-final { cleanup-modules "type_mod seg_mod" } }