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] PR27709 - Using size of array pointer component as dimension of function result causes gfortran internal error.


:ADDPATCH fortran:

This was http://gcc.gnu.org/ml/fortran/2006-05/msg00357.html and thread.

Well, in spite of living up to my name, I relented and was convinced that this is good code and that the bug should be fixed. Thanks to Richard, Brooks and David Ham for a useful discussion.

Not only was I persuaded by this discussion but I was promptly hit by the same bug myself; so I had a double incentive to fix it.

The problem is clearly indicated in the attached testcase. The internal error is triggered by multiple component references in an array bound specification expression.

It turned out that the routine that emits the error, resolve.c(find_array_spec), is also the cause of it. As it is coded, it makes no attempt to go any deeper than one component reference and fails because it only checks the reference against any derived types that it finds in the primary derived type. Thus, multiple component references in linked lists work; eg. real, dimension (size (self%next%next%data, 1)) :: local is OK.

The fix is implemented by supplying a gfc_symbol that points to the derived type used in the last component reference. The components of this derived type are used for comparison with the next component reference. The testcase is that posted with the PR.

Regtested on FC5/Athlon1700. OK for trunk and, when reopened, 4.1?

Paul

2006-05-21 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/27709
   * resolve.c (find_array_spec): Add gfc_symbol, derived, and
   use to track repeated component references.

2006-05-21 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/27709
   * gfortran.dg/spec_expr_4.f90: New test.


Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c	(revision 113950)
--- gcc/fortran/resolve.c	(working copy)
*************** find_array_spec (gfc_expr * e)
*** 2285,2293 ****
--- 2285,2295 ----
  {
    gfc_array_spec *as;
    gfc_component *c;
+   gfc_symbol *derived;
    gfc_ref *ref;
  
    as = e->symtree->n.sym->as;
+   derived = NULL;
  
    for (ref = e->ref; ref; ref = ref->next)
      switch (ref->type)
*************** find_array_spec (gfc_expr * e)
*** 2301,2309 ****
  	break;
  
        case REF_COMPONENT:
! 	for (c = e->symtree->n.sym->ts.derived->components; c; c = c->next)
  	  if (c == ref->u.c.component)
! 	    break;
  
  	if (c == NULL)
  	  gfc_internal_error ("find_array_spec(): Component not found");
--- 2303,2321 ----
  	break;
  
        case REF_COMPONENT:
! 	if (derived == NULL)
! 	  derived = e->symtree->n.sym->ts.derived;
! 
! 	c = derived->components;
! 
! 	for (; c; c = c->next)
  	  if (c == ref->u.c.component)
! 	    {
! 	      /* Track the sequence of component references.  */
! 	      if (c->ts.type == BT_DERIVED)
! 		derived = c->ts.derived;
! 	      break;
! 	    }
  
  	if (c == NULL)
  	  gfc_internal_error ("find_array_spec(): Component not found");
! { dg-do compile }
! Tests the fix for PR27709 in which the specification expression on
! line 22 was not resolved because of the multiple component references.
!
! Contributed by David Ham  <David@ham.dropbear.id.au>
!
module elements
  implicit none
  type element_type
     type(ele_numbering_type), pointer :: numbering
  end type element_type
  type ele_numbering_type
     integer, dimension(:,:), pointer :: number2count
  end type ele_numbering_type
end module elements
module global_numbering
  use elements
  implicit none
contains
  function element_local_coords(element) result (coords)
    type(element_type), intent(in) :: element    
    real, dimension(size(element%numbering%number2count, 1)) :: coords
    coords=0.0 
  end function element_local_coords
end module global_numbering

  use global_numbering
  type (element_type) :: e
  type (ele_numbering_type), target :: ent
  allocate (ent%number2count (2,2))
  e%numbering => ent
  print *, element_local_coords (e)
end
2006-05-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/27709
	* resolve.c (find_array_spec): Add gfc_symbol, derived, and
	use to track repeated component references.

2006-05-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/27709
	* gfortran.dg/spec_expr_4.f90: New test.


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