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

            Bug ID: 90068
           Summary: Array Constructor Containing Function Call Leaks
                    Memory
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: brichardson at structint dot com
  Target Milestone: ---

It appears that without an intermediate value to save the result of the
function call, the value returned by the function ends up being leaked memory.

The following example program and commands demonstrate the problem.

program array_memory_leak
    implicit none

    type, abstract :: base
    end type base

    type, extends(base) :: extended
    end type extended

    type :: container
        class(base), allocatable :: thing
    end type

    type, extends(base) :: collection
        type(container), allocatable :: stuff(:)
    end type collection

    call run()
contains
    subroutine run()
        type(collection) :: my_thing
        type(container) :: a_container

        a_container = newContainer(newExtended()) ! This is fine
        my_thing = newCollection([a_container])

        my_thing = newCollection([newContainer(newExtended())]) ! This is a
memory leak
    end subroutine run

    function newExtended()
        type(extended) :: newExtended
    end function newExtended

    function newContainer(thing)
        class(base), intent(in) :: thing
        type(container) :: newContainer

        allocate(newContainer%thing, source = thing)
    end function newContainer

    function newCollection(things)
        type(container), intent(in) :: things(:)
        type(collection) :: newCollection

        newCollection%stuff = things
    end function newCollection
end program array_memory_leak

$ gfortran -g array_memory_leak.f90 -o array_memory_leak
$ valgrind --leak-check=full ./array_memory_leak        
==7652== Memcheck, a memory error detector
==7652== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7652== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==7652== Command: ./array_memory_leak
==7652== 
==7652== 
==7652== HEAP SUMMARY:
==7652==     in use at exit: 1 bytes in 1 blocks
==7652==   total heap usage: 29 allocs, 28 frees, 13,554 bytes allocated
==7652== 
==7652== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7652==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==7652==    by 0x109A0B: newcontainer.3817 (array_memory_leak.f90:38)
==7652==    by 0x10A17C: run.3822 (array_memory_leak.f90:27)
==7652==    by 0x1091E6: MAIN__ (array_memory_leak.f90:18)
==7652==    by 0x10A96B: main (array_memory_leak.f90:18)
==7652== 
==7652== LEAK SUMMARY:
==7652==    definitely lost: 1 bytes in 1 blocks
==7652==    indirectly lost: 0 bytes in 0 blocks
==7652==      possibly lost: 0 bytes in 0 blocks
==7652==    still reachable: 0 bytes in 0 blocks
==7652==         suppressed: 0 bytes in 0 blocks
==7652== 
==7652== For counts of detected and suppressed errors, rerun with: -v
==7652== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

I'm running the official version of gcc on Arch Linux. I'm also running a
version of 9.0 from September at work, which exhibits the same behavior.

Reply via email to