This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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] | |
* The "automatic deallocation&allocation if necessary" on assignmentsAre you working on this? If so, that would be great because....
is the main thing left to be done.
* I have probably forgotten something.... I thought to provide the modifications that are needed to the derived type constructor.
I attach the current (partly a bit ugly) version of the patch (someday,I would find an explanation useful! Coming back to this after a couple of months makes me feel as if I am in the throes of a sever bout of memory loss.
I will clean things up and write some kind of explanation for it), and a
testcase.
Yes, noted; see below for what I am now finding with the iso_varying_string testsuite.
Paul,
Changes I've made since last time: I've messed (= probably broken
something) a bit with the deallocation of scalar INTENT(OUT) arguments
in trans-expr.c (gfc_conv_function_call), and tried to make sure
function results aren't deallocated until after they have been used.
+Your activities have made this kludge even more necessary for the IVS testcases. I think that what you have done is correct and I am on to the reasons for it - or, at least, I have found that concatenation is the primary cause of the ICEs; eg. when concatenating two iso_varying_strings when one has zero length. The operation explicitly references outside of the allocated domain. Other compilers seem able to handle this, so I suspect that there is some trick that we are missing here. I can partially get round it by modifying the fortran in the iso_varying_string module. Whether this is a bug in the module or in gfortran, I do not rightly know yet.
+#if 0
+ case (SCALAR):
+/* This is horrible! FIXME. Problem with(eg.) vst_5.f95:205 */
+ goto get_me_out_of_here;
+#endif
+
+ case (SCALAR_POINTER):
+ tmp = build_fold_indirect_ref (tmp);
+ break;
+ case (ARRAY):
+ tmp = parmse.expr;
+ break;
+ }
+ tmp = deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
+ if (e->symtree->n.sym->result)
+ /* Don't deallocate function results until they have been used. */
+ gfc_add_expr_to_block (&se->post, tmp);
+ else
+ gfc_add_expr_to_block (&se->pre, tmp);
+ }
+
+get_me_out_of_here:
+
/* Allocatable arrays need to be freed when they go out of scope. */Rats! This was a desperate attempt to get to the bottom of the problem above. I never restored the code after the attempt - sorry!
+
+ /* Paul had deledted this from here ... */
+ if (sym->ts.type == BT_DERIVED && sym->ts.derived->attr.alloc_comp
+ && !(sym->attr.function || sym->attr.result))
+ {
+ int rank;
+ rank = sym->as ? sym->as->rank : 0;
+ tmp = deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
+ gfc_add_expr_to_block (&fnblock, tmp);
+ }
+ /* ... to here! */
+
This is very good. If any of you out there are intersted in testing this patch, take a look at the code that the testcase produces! - I should explain that Erik has done all the tidy stuff; my contribution on the automatic deallocation is what produces the byte pollution...
! { dg-do run} ! { dg-options "-O2 -fdump-tree-original" } ! ! Check some basic functionality of allocatable components, including that they ! are nullified when created and automatically deallocated when ! 1. A variable goes out of scope ! 2. INTENT(OUT) dummies ! 3. Function results ! module alloc_m
implicit none
type :: alloc1 real, allocatable :: x(:) end type alloc1
end module alloc_m
program alloc
use alloc_m
implicit none
type :: alloc2 type(alloc1), allocatable :: a1(:) integer, allocatable :: a2(:) end type alloc2
type(alloc2) :: b integer :: i type(alloc2), allocatable :: c(:)
if (allocated(b%a2) .OR. allocated(b%a1)) then write (0, *) 'main - 1' call abort() end if
! 3 calls to _gfortran_deallocate (INTENT(OUT) dummy) call allocate_alloc2(b) call check_alloc2(b)
do i = 1, size(b%a1) ! 1 call to _gfortran_deallocate deallocate(b%a1(i)%x) end do
! 3 calls to _gfortran_deallocate (INTENT(OUT) dummy) call allocate_alloc2(b)
call check_alloc2(return_alloc2()) ! 3 calls to _gfortran_deallocate (function result)
allocate(c(1)) ! 3 calls to _gfortran_deallocate (INTENT(OUT) dummy) call allocate_alloc2(c(1)) ! 4 calls to _gfortran_deallocate deallocate(c)
! 7 calls to _gfortran_deallocate (b (3) and c(4) goes aout of scope)
contains
subroutine allocate_alloc2(b) type(alloc2), intent(out) :: b integer :: i
if (allocated(b%a2) .OR. allocated(b%a1)) then write (0, *) 'allocate_alloc2 - 1' call abort() end if
allocate (b%a2(3)) b%a2 = [ 1, 2, 3 ]
allocate (b%a1(3))
do i = 1, 3 if (allocated(b%a1(i)%x)) then write (0, *) 'allocate_alloc2 - 2', i call abort() end if allocate (b%a1(i)%x(3)) b%a1(i)%x = i + [ 1.0, 2.0, 3.0 ] end do
end subroutine allocate_alloc2
type(alloc2) function return_alloc2() result(b) if (allocated(b%a2) .OR. allocated(b%a1)) then write (0, *) 'return_alloc2 - 1' call abort() end if
allocate (b%a2(3)) b%a2 = [ 1, 2, 3 ]
allocate (b%a1(3))
do i = 1, 3 if (allocated(b%a1(i)%x)) then write (0, *) 'return_alloc2 - 2', i call abort() end if allocate (b%a1(i)%x(3)) b%a1(i)%x = i + [ 1.0, 2.0, 3.0 ] end do end function return_alloc2
subroutine check_alloc2(b) type(alloc2), intent(in) :: b
if (.NOT.(allocated(b%a2) .AND. allocated(b%a1))) then write (0, *) 'check_alloc2 - 1' call abort() end if if (any(b%a2 /= [ 1, 2, 3 ])) then write (0, *) 'check_alloc2 - 2' call abort() end if do i = 1, 3 if (.NOT.allocated(b%a1(i)%x)) then write (0, *) 'check_alloc2 - 3', i call abort() end if if (any(b%a1(i)%x /= i + [ 1.0, 2.0, 3.0 ])) then write (0, *) 'check_alloc2 - 4', i call abort() end if end do end subroutine check_alloc2
end program alloc
! { dg-final { scan-tree-dump-times "deallocate" 24 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |