This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR24092 - recursive derived types - part 2


:ADDPATCH fortran:

Herewith is the promised, improved patch for PR24092.

Not only does this patch not produce unrequited field lists but it is somewhat easier to understand. I have split out a loop through the components, which obtains the backend_decls for the derived type components, building them if necessary. After this loop is a test to see if the fields exist. This happens in the circumstance that we are seeking to fix and is best discussed with repect to the test case:

type :: it
character*10 :: k
integer :: c(2)
end type it
type :: bt !! 2nd - gets to check derived type components
type (nt), pointer :: p
end type bt
type :: nt !! 3rd - builds type(nt)
type (it) :: i
type (bt) :: b !! 4th - builds type(bt) & original call returns.
end type nt
type (bt), pointer :: ptr !! Starting point => make a type(bt)


Thus, the original call to gfc_get_derived_type is interrupted by the test for the field list, which by now has been done in the course of constructing type(nt).

The original mainloop over the components is slightly simplified by use of the backend_decls, built in the first loop, for the fields. Also, the gcc_assert has been moved to apply to the field, rather than the backend_decl. Except, in the recursive case, this part of the code is reached on the first time call.

For intrinsic types, the code is unchanged.

Bootstrapped and regtested on FC3/Athlon. OK for mainline and 4.0?

Paul T


2005-10-10  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/24092
	* trans-types.c (gfc_get_derived_type): Insert code to obtain backend
	declaration for derived types, building if necessary.  Return the
	derived type if the fields have been built by this process.  Otherwise,
	continue as before but using the already obtained backend_decls for the
	derived type components.  Chnege the gcc_assert to act on the field.

2005-10-10  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/24092
	gfortran.dg/derived_pointer_recursion.f90: New test.


Index: gcc/gcc/fortran/trans-types.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-types.c,v
retrieving revision 1.50
diff -c -p -r1.50 trans-types.c
*** gcc/gcc/fortran/trans-types.c	29 Jul 2005 00:02:37 -0000	1.50
--- gcc/gcc/fortran/trans-types.c	9 Oct 2005 16:39:55 -0000
*************** gfc_get_derived_type (gfc_symbol * deriv
*** 1407,1427 ****
        derived->backend_decl = typenode;
      }
  
    /* Build the type member list. Install the newly created RECORD_TYPE
       node as DECL_CONTEXT of each FIELD_DECL.  */
    fieldlist = NULL_TREE;
    for (c = derived->components; c; c = c->next)
      {
!       if (c->ts.type == BT_DERIVED && c->pointer)
!         {
!           if (c->ts.derived->backend_decl)
! 	    /* We already saw this derived type so use the exiting type.
! 	       It doesn't matter if it is incomplete.  */
! 	    field_type = c->ts.derived->backend_decl;
!           else
! 	    /* Recurse into the type.  */
! 	    field_type = gfc_get_derived_type (c->ts.derived);
!         }
        else
  	{
  	  if (c->ts.type == BT_CHARACTER)
--- 1407,1436 ----
        derived->backend_decl = typenode;
      }
  
+   /* Go through the derived type components, building them as
+      necessary. The reason for doing this now is that it is
+      possible to recurse back to this derived type through a
+      pointer component (PR24092). If this happens, the fields
+      will be built and so we can return the type.  */
+   for (c = derived->components; c; c = c->next)
+     {
+       if (c->ts.type != BT_DERIVED)
+ 	continue;
+ 
+       if (!c->pointer || c->ts.derived->backend_decl == NULL)
+ 	c->ts.derived->backend_decl = gfc_get_derived_type (c->ts.derived);
+     }
+ 
+   if (TYPE_FIELDS (derived->backend_decl))
+     return derived->backend_decl;
+ 
    /* Build the type member list. Install the newly created RECORD_TYPE
       node as DECL_CONTEXT of each FIELD_DECL.  */
    fieldlist = NULL_TREE;
    for (c = derived->components; c; c = c->next)
      {
!       if (c->ts.type == BT_DERIVED)
!         field_type = c->ts.derived->backend_decl;
        else
  	{
  	  if (c->ts.type == BT_CHARACTER)
*************** gfc_get_derived_type (gfc_symbol * deriv
*** 1456,1463 ****
  
        DECL_PACKED (field) |= TYPE_PACKED (typenode);
  
!       gcc_assert (!c->backend_decl);
!       c->backend_decl = field;
      }
  
    /* Now we have the final fieldlist.  Record it, then lay out the
--- 1465,1473 ----
  
        DECL_PACKED (field) |= TYPE_PACKED (typenode);
  
!       gcc_assert (field);
!       if (!c->backend_decl)
! 	c->backend_decl = field;
      }
  
    /* Now we have the final fieldlist.  Record it, then lay out the

-------------------------derived_pointer_recursion.f90---------------------

! { dg-do compile }
! { dg-options "-O0" }
!  Tests patch for PR24092 - This would ICE because of the loop in the
!  derived type definitions.
!
   module llo
      type :: it
         character*10  :: k
         integer :: c(2)
      end type it
      type :: bt
         type (nt), pointer :: p
      end type bt
      type :: nt
         type (it) :: i
         type (bt) :: b
      end type nt
      type (bt), pointer :: ptr
   end module llo
!  copyright 1996 Loren P. Meissner -- May be distributed if this line is included.
!  Linked List operations with Pointer to Pointer



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]