https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90076
Bug ID: 90076 Summary: Polymorphic Allocate on Assignment Memory Leak 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: --- Allocate on assignment for polymorphic scalars causes a memory leak. The following program and execution demonstrates the problem. program assignment_memory_leak implicit none type, abstract :: base end type base type, extends(base) :: extended end type extended call run() contains subroutine run() class(base), allocatable :: var allocate(var, source = newVar()) var = newVar() ! This is a memory leak end subroutine run function newVar() class(base), allocatable :: newVar allocate(newVar, source = extended()) end function newVar end program assignment_memory_leak $ gfortran -g assignment_memory_leak.f90 -o assignment_memory_leak $ valgrind --leak-check=full ./assignment_memory_leak ==10130== Memcheck, a memory error detector ==10130== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==10130== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==10130== Command: ./assignment_memory_leak ==10130== ==10130== ==10130== HEAP SUMMARY: ==10130== in use at exit: 2 bytes in 2 blocks ==10130== total heap usage: 24 allocs, 22 frees, 13,523 bytes allocated ==10130== ==10130== 1 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==10130== at 0x483777F: malloc (vg_replace_malloc.c:299) ==10130== by 0x109241: newvar.3789 (assignment_memory_leak.f90:22) ==10130== by 0x1092D9: run.3791 (assignment_memory_leak.f90:15) ==10130== by 0x1091D6: MAIN__ (assignment_memory_leak.f90:10) ==10130== by 0x10947F: main (assignment_memory_leak.f90:10) ==10130== ==10130== 1 bytes in 1 blocks are definitely lost in loss record 2 of 2 ==10130== at 0x483777F: malloc (vg_replace_malloc.c:299) ==10130== by 0x109241: newvar.3789 (assignment_memory_leak.f90:22) ==10130== by 0x10936B: run.3791 (assignment_memory_leak.f90:16) ==10130== by 0x1091D6: MAIN__ (assignment_memory_leak.f90:10) ==10130== by 0x10947F: main (assignment_memory_leak.f90:10) ==10130== ==10130== LEAK SUMMARY: ==10130== definitely lost: 2 bytes in 2 blocks ==10130== indirectly lost: 0 bytes in 0 blocks ==10130== possibly lost: 0 bytes in 0 blocks ==10130== still reachable: 0 bytes in 0 blocks ==10130== suppressed: 0 bytes in 0 blocks ==10130== ==10130== For counts of detected and suppressed errors, rerun with: -v ==10130== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) Note that using a version of 9.0 from September that we use at work, the explicit allocate doesn't generate a memory leak, so I'm not worried about that for this bug report. Additionally, If I make the newVar function return the concrete type, I don't get any memory leaks. program assignment_memory_leak implicit none type, abstract :: base end type base type, extends(base) :: extended end type extended call run() contains subroutine run() class(base), allocatable :: var allocate(var, source = newVar()) var = newVar() ! This is fine now end subroutine run function newVar() type(extended) :: newVar end function newVar end program assignment_memory_leak $ gfortran -g assignment_memory_leak.f90 -o assignment_memory_leak $ valgrind --leak-check=full ./assignment_memory_leak ==10176== Memcheck, a memory error detector ==10176== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==10176== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==10176== Command: ./assignment_memory_leak ==10176== ==10176== ==10176== HEAP SUMMARY: ==10176== in use at exit: 0 bytes in 0 blocks ==10176== total heap usage: 22 allocs, 22 frees, 13,521 bytes allocated ==10176== ==10176== All heap blocks were freed -- no leaks are possible ==10176== ==10176== For counts of detected and suppressed errors, rerun with: -v ==10176== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) But if I remove the allocate statement, the compiler segfaults. program assignment_memory_leak implicit none type, abstract :: base end type base type, extends(base) :: extended end type extended call run() contains subroutine run() class(base), allocatable :: var var = newVar() ! This segfaults the compiler end subroutine run function newVar() type(extended) :: newVar end function newVar end program assignment_memory_leak $ gfortran -g assignment_memory_leak.f90 -o assignment_memory_leak assignment_memory_leak.f90:15:0: var = newVar() ! This segfaults the compiler internal compiler error: in build_function_decl, at fortran/trans-decl.c:2238 Please submit a full bug report, with preprocessed source if appropriate. See <https://bugs.archlinux.org/> for instructions. Those behaviors are the same for the version of 9.0 I use at work. I used the official version for Arch Linux to generate all of the above.