This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, fortran] PR27709 - Using size of array pointer component as dimension of function result causes gfortran internal error.
- From: Paul Thomas <paulthomas2 at wanadoo dot fr>
- To: patch <gcc-patches at gcc dot gnu dot org>, "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>, David at ham dot dropbear dot id dot au
- Date: Thu, 25 May 2006 07:13:16 +0200
- Subject: [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.