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

            Bug ID: 120637
           Summary: Memory leak in finalization gfortran 15.1.1
           Product: gcc
           Version: 15.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: antony at cosmologist dot info
  Target Milestone: ---

This leaks memory on linux gfortran gcc version 13.1.0 (Ubuntu
13.1.0-8ubuntu1~22.04), and 15.1.1 source build, e.g. 

  gfortran inidriver.f90 && valgrind ./a.out

==2817== HEAP SUMMARY:
==2817==     in use at exit: 36,000,000 bytes in 3 blocks
==2817==   total heap usage: 29 allocs, 26 frees, 64,805,471 bytes allocated
==2817== 
==2817== LEAK SUMMARY:
==2817==    definitely lost: 24,000,000 bytes in 2 blocks
==2817==    indirectly lost: 0 bytes in 0 blocks
==2817==      possibly lost: 12,000,000 bytes in 1 blocks
==2817==    still reachable: 0 bytes in 0 blocks
==2817==         suppressed: 0 bytes in 0 blocks
==2817== Rerun with --leak-check=full to see details of leaked memory


    module MiscUtils
    implicit none

    contains

    logical function isFloat0(R)
    class(*), intent(in) :: R

    select type(R)
    type is (real)
        isFloat0 = .true.
    end select
    end function isFloat0

    end module MiscUtils

    module results3
    implicit none
    public

    Type ClTransferData2
      real, dimension(:,:,:), allocatable :: Delta_p_l_k
    end type ClTransferData2

    type TCLdata2
       Type(ClTransferData2) :: CTransScal, CTransTens, CTransVec
    end type TCLdata2 

    type :: CAMBdata2
        Type(TClData2) :: CLdata2
    contains
        ! Commenting this resolves this specific test case, 
        ! - but not more general issue. It should be valid either way.
        final :: CAMBdata2_Destructor
    end type  

    contains
    subroutine CAMBdata2_Destructor(this)
    type(CAMBdata2) :: this
    end subroutine CAMBdata2_Destructor

    end module results3

program driver
    use results3
    implicit none
    integer :: i

    do i = 1, 3
        call test()
    end do

contains

    subroutine test()
        implicit none
        type(CAMBdata2) :: OutData

        !This is fine
        allocate(OutData%ClData2%CTransScal%Delta_p_l_k(3, 1000, 800))
        !this is not
        allocate(OutData%ClData2%CTransVec%Delta_p_l_k(3, 1000, 1000))

    end subroutine test

end program driver

It's a quantum bug, that if you change random seemingly-irrelevant things the
result changes. The actual bug in the production code (CAMB) does not have the
final, and leaks from the CTransTens on a similar
allocation/automatic-deallocation pattern.

This is similar to old bug chain in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94109
I suspect the underlying issue from back then was not fully resolved. However,
people have only reported this in my live code in the last year, so it may be a
regression - not sure. 

It may vary by system, here's a docker command that can be used to reproduce
with source build of 15 branch from this week.

docker run --rm -v "$(pwd):/workspace" -w /workspace
cmbant/docker-gcc-build:gcc15 bash -c "
     gfortran camb_memory_leak_test.f90 && valgrind ./a.out"
  • [Bug fortran/120637] New: Memo... antony at cosmologist dot info via Gcc-bugs

Reply via email to