:ADDPATCH fortran:
This problem involves dummy arguments in contained procedures that are use
associated derived types. gfortran was building separate tree types for the
structure and its components in both host and contained namespces.
I found that a front-end fix, in resolve_symbol, got more than a little bit
cumbersome because of the need to worry about reference counting and
cleaning up of the derived type symbol. The simplest, by far, was to attack
trans-types(gfc_get_derived_type) and to use the host + use associated
backend declarations for the derived type, rather than building afresh in
the contained namespace. In this way, the frontend symbols do their job and
are trashed cleanly at the end of the compilation.
This is one of the "Most Wanted Bugs" -
http://gcc.gnu.org/wiki/GfortranWanted
Bubblestrapped and regtested with Cygwin/PIV. Will check tonight with FC3.
OK for trunk and 4.1?
Paul
2005-12-13 Paul Thomas <pault@gcc.gnu.org>
PR fortran/20244
*trans-types.c(gfc_get_derived_type): After assertion that symbol is
FL_DERIVED, test for the derived type being available both by USE
association in a contained procedure and available by host
association
from the same module. In this case, the host associated backend
declarations are used for the structure and its components, rather
than building anew.
*gfortran.dg/used_dummy_types_1.f90: New test.
------------------------------------------------------------------------
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c (révision 108398)
+++ gcc/fortran/trans-types.c (copie de travail)
@@ -1402,9 +1402,37 @@
{
tree typenode, field, field_type, fieldlist;
gfc_component *c;
+ gfc_component * cm = NULL;
+ gfc_symtree * symtree = NULL;
+ gfc_symbol * dt = NULL;
+ gfc_namespace * ns = NULL;
gcc_assert (derived && derived->attr.flavor == FL_DERIVED);
+ /* If a derived type is already available by host association,
+ use its backend declaration and those of its components,
+ rather than building anew so that potential dummy and actual
+ arguments use the same TREE_TYPE. (PR20244) */
+ if (derived->attr.use_assoc && derived->ns->parent != NULL)
+ {
+ for (ns = derived->ns->parent; ns; ns = ns->parent)
+ {
+ symtree = gfc_find_symtree (ns->sym_root, derived->name);
+ if (symtree)
+ dt = symtree->n.sym;
+ if (dt && dt->attr.flavor == FL_DERIVED
+ && dt->module == derived->module
+ && dt->backend_decl)
+ {
+ derived->backend_decl = dt->backend_decl;
+ cm = dt->components;
+ c = derived->components;
+ for (; c; c = c->next, cm = cm->next)
+ c->backend_decl = cm->backend_decl;
+ }
+ }
+ }
+
/* derived->backend_decl != 0 means we saw it before, but its
components' backend_decl may have not been built. */
if (derived->backend_decl)
!=================used_dummy_types_1.f90===================
! { dg-do run }
! This checks the fix for PR20244 in which USE association
! of derived types would cause an ICE, if the derived type
! was also available by host association. This occurred
! because the backend declarations were different.
!
! Contributed by Paul Thomas <pault@gcc.gnu.org>
!==============
module mtyp
type t1
integer::a
end type t1
end module mtyp
!==============
module atest
use mtyp
type(t1)::ze
contains
subroutine test(ze_in )
use mtyp
implicit none
type(t1)::ze_in
ze_in = ze
end subroutine test
subroutine init( )
implicit none
ze = t1 (42)
end subroutine init
end module atest
!==============
use atest
type(t1) :: res = t1 (0)
call init ()
call test (res)
if (res%a.ne.42) call abort
end