https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84472

            Bug ID: 84472
           Summary: Missing finalization and memory leak
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fortranfan at outlook dot com
  Target Milestone: ---

Consider the following:

--- begin console output ---
C:\Temp>type m.f90
module m

   use, intrinsic :: iso_fortran_env, only : output_unit

   implicit none

   private

   type :: t
      private
      character(len=:), pointer :: m_s => null()
   contains
      private
      final :: final_t
      procedure, pass(this), public :: clean => clean_t
      procedure, pass(this), public :: init => init_t
   end type

   interface t
      module procedure :: construct_t
   end interface

   public :: t

contains

   function construct_t( name ) result(new_t)

      ! argument list
      character(len=*), intent(in), optional :: name
      ! function result
      type(t) :: new_t

      if ( present(name) ) then
         call new_t%init( name )
      end if

   end function

   subroutine final_t( this )

      ! argument list
      type(t), intent(inout) :: this

      write( output_unit, fmt="(g0)", advance="no" ) "finalizer invoked"
      if ( associated(this%m_s) ) then
         write( output_unit, fmt=* ) "for object ", trim(this%m_s)
      else
         write( output_unit, fmt=* )
      end if
      call clean_t( this )

   end subroutine

   subroutine clean_t( this )

      ! argument list
      class(t), intent(inout) :: this

      if ( associated(this%m_s) ) then
         deallocate( this%m_s )
      end if
      this%m_s => null()

   end subroutine

   subroutine init_t( this, name )

      ! argument list
      class(t), intent(inout)      :: this
      character(len=*), intent(in) :: name

      call this%clean()
      allocate( this%m_s, source=name )

   end subroutine

end module

C:\Temp>gfortran -c -Wall -std=f2008ts m.f90

C:\Temp>type p.f90
program p

   use m, only : t

   implicit none

   type(t) :: foo

   call foo%init( name="123" )

   foo = t( name="foo" )

   call foo%clean()

   stop

end program

C:\Temp>gfortran -c -Wall -std=f2008ts p.f90

C:\Temp>gfortran m.o p.o -o p.exe

C:\Temp>p.exe

C:\Temp>"C:\Program Files (x86)\Dr. Memory\bin\drmemory.exe" -- p.exe
-show_reachable
~~Dr.M~~ Dr. Memory version 1.11.0
~~Dr.M~~ (Uninitialized read checking is not yet supported for 64-bit)
~~Dr.M~~ Running "p.exe -show_reachable"
~~Dr.M~~
~~Dr.M~~ Error #1: LEAK 3 direct bytes 0x0000000003101da0-0x0000000003101da3 +
0
 indirect bytes
~~Dr.M~~ # 0 replace_malloc                    
[d:\drmemory_package\common\allo
c_replace.c:2576]
~~Dr.M~~ # 1 insert                            
[../../../gcc-8-20180204-mingw/l
ibgfortran/io/unit.c:206]
~~Dr.M~~ # 2 _gfortrani_fbuf_init              
[../../../gcc-8-20180204-mingw/l
ibgfortran/io/fbuf.c:42]
~~Dr.M~~ # 3 __m_MOD_init_t
~~Dr.M~~ # 4 MAIN__
~~Dr.M~~ # 5 main
~~Dr.M~~
~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~       0 unique,     0 total unaddressable access(es)
~~Dr.M~~       0 unique,     0 total invalid heap argument(s)
~~Dr.M~~       0 unique,     0 total GDI usage error(s)
~~Dr.M~~       0 unique,     0 total handle leak(s)
~~Dr.M~~       0 unique,     0 total warning(s)
~~Dr.M~~       1 unique,     1 total,      3 byte(s) of leak(s)
~~Dr.M~~       0 unique,     0 total,      0 byte(s) of possible leak(s)
~~Dr.M~~ ERRORS IGNORED:
~~Dr.M~~       2 potential error(s) (suspected false positives)
~~Dr.M~~          (details: C:\Users\parekhv\AppData\Roaming\Dr.
Memory\DrMemory
-p.exe.14260.000\potential_errors.txt)
~~Dr.M~~       3 unique,     4 total,    246 byte(s) of still-reachable
allocati
on(s)
~~Dr.M~~          (re-run with "-show_reachable" for details)
~~Dr.M~~ Details: C:\Users\parekhv\AppData\Roaming\Dr.
Memory\DrMemory-p.exe.142
60.000\results.txt

C:\Temp>
--- end console output ---


Per section '4.5.6.3 When finalization occurs' of document 10-007r1 toward
Fortran 2008 standard, for an instruction such as 'foo = t( name="foo" )' in
the program shown above, one can expect finalization to occur for object foo
before it gets redefined and also for the entity created by the function with
generic interface t.  Thus the expected program output is:
finalizer invoked for object 123
finalizer invoked for object foo

In addition, I would expect the program to not leak any memory, but as shown
above there is a leak of 3 bytes which may correspond to the above-mentioned
missing finalization for the initial object foo.

Thank you for your time and attention.

Best Regards,

Reply via email to