http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51160

             Bug #: 51160
           Summary: Memory leak with abstract type
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: mreste...@gmail.com


Hi,
   the attached code, which I think is correct, leaks memory.
According to valgrind this happens in subroutine subr, at line

  class(et), intent(inout) :: y

Here is the output:

==29006== HEAP SUMMARY:
==29006==     in use at exit: 40,000 bytes in 100 blocks
==29006==   total heap usage: 223 allocs, 123 frees, 57,583 bytes allocated
==29006== 
==29006== 40,000 bytes in 100 blocks are definitely lost in loss record 1 of 1
==29006==    at 0x4C26F5D: malloc (vg_replace_malloc.c:263)
==29006==    by 0x400A20: __mod2_MOD___copy_mod2_Et (test.f90:38)
==29006==    by 0x4008E6: __mod1_MOD_sub (test.f90:24)
==29006==    by 0x400D0C: MAIN__ (test.f90:53)
==29006==    by 0x400E1E: main (test.f90:46)
==29006== 
==29006== LEAK SUMMARY:
==29006==    definitely lost: 40,000 bytes in 100 blocks
==29006==    indirectly lost: 0 bytes in 0 blocks
==29006==      possibly lost: 0 bytes in 0 blocks
==29006==    still reachable: 0 bytes in 0 blocks
==29006==         suppressed: 0 bytes in 0 blocks
==29006== 

The problem becomes more and more severe increasing n.

gfortran --version
GNU Fortran (GCC) 4.7.0 20111116 (experimental)

and I'm compiling with
gfortran -g test.f90 -o prg



module mod1
implicit none
 type, abstract :: at
  contains
  procedure(i_copy), deferred, pass(y) :: copy
 end type at
 abstract interface
  subroutine i_copy(y,x)
   import :: at
   implicit none
   class(at), intent(in)    :: x
   class(at), intent(inout) :: y
  end subroutine i_copy
 end interface
contains
 subroutine sub(q,p)
  class(at), intent(in) :: p
  class(at), intent(inout) :: q
  class(at), allocatable :: r
   allocate(r,source=p)
   call r%copy(p)
   call q%copy(r)
   deallocate(r)
 end subroutine sub
end module mod1

module mod2
 use mod1
implicit none
 type, extends(at) :: et
  real, allocatable :: u(:)
 contains
  procedure, pass(y) :: copy => subr
 end type et
contains
 subroutine subr(y,x)
  class(at), intent(in)    :: x
  class(et), intent(inout) :: y
   select type(x); type is(et)
    y%u = x%u
   end select
 end subroutine subr
end module mod2

program prog
 use mod1
 use mod2
 integer, parameter :: n = 100
 type(et) :: a, b
 allocate(a%u(n)); a%u = 1.5
 allocate(b%u(n))
 do i=1,n
   call sub(b,a)
 enddo
 deallocate(a%u,b%u)
end program prog

Reply via email to