Hi Salvatore, This looks like it's related to some of the missing finalization functionality (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37336). Paul has some patches (e.g. https://gcc.gnu.org/pipermail/fortran/2022-January/057415.html) which implement most of the missing functionality. With those patches incorporated your code gives the following output with gfortran:
$ ./testfinal Allocating wrapper Calling new_outer_type Assigning outer%test_item Called delete_test_type End of new_outer_type DeAllocating wrapper Called delete_test_type So there is one more call to the finalizer than you found - I haven't checked carefully but I would guess this is a deallocation of LHS on assignment. In testing these patches using the Intel compiler we found that it seems to call the finalization wrapper more than it should, sometimes on objects that have already been deallocated. Your code, compiled with the Intel compiler and then run under valgrind shows the following: $ valgrind ./testfinal ==7340== Memcheck, a memory error detector ==7340== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7340== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==7340== Command: ./testfinal ==7340== ==7340== Conditional jump or move depends on uninitialised value(s) ==7340== at 0x493A51: __intel_sse2_strcpy (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x45D70E: for__add_to_lf_table (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x4410CB: for__open_proc (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x423A64: for__open_default (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x4305A9: for_write_seq_lis (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x4047E1: MAIN__ (testfinal.f90:62) ==7340== by 0x403CE1: main (in /home/abensonca/Scratch/ifortTests/ testfinal) ==7340== Allocating wrapper Calling new_outer_type Assigning outer%test_item Called delete_test_type ==7340== Conditional jump or move depends on uninitialised value(s) ==7340== at 0x40572A: do_alloc_copy (in /home/abensonca/Scratch/ifortTests/ testfinal) ==7340== by 0x406B9A: do_alloc_copy (in /home/abensonca/Scratch/ifortTests/ testfinal) ==7340== by 0x4084ED: for_alloc_assign_v2 (in /home/abensonca/Scratch/ ifortTests/testfinal) ==7340== by 0x404474: target_mod_mp_new_outer_type_ (testfinal.f90:48) ==7340== by 0x40485E: MAIN__ (testfinal.f90:65) ==7340== by 0x403CE1: main (in /home/abensonca/Scratch/ifortTests/ testfinal) ==7340== Called delete_test_type End of new_outer_type DeAllocating wrapper Called delete_test_type ==7340== ==7340== HEAP SUMMARY: ==7340== in use at exit: 48 bytes in 1 blocks ==7340== total heap usage: 14 allocs, 13 frees, 12,879 bytes allocated ==7340== ==7340== LEAK SUMMARY: ==7340== definitely lost: 48 bytes in 1 blocks ==7340== indirectly lost: 0 bytes in 0 blocks ==7340== possibly lost: 0 bytes in 0 blocks ==7340== still reachable: 0 bytes in 0 blocks ==7340== suppressed: 0 bytes in 0 blocks ==7340== Rerun with --leak-check=full to see details of leaked memory ==7340== ==7340== For counts of detected and suppressed errors, rerun with: -v ==7340== Use --track-origins=yes to see where uninitialised values come from ==7340== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) so there are some cases of what look like incorrect accesses (and some leaked memory). Your code compiled with gfortran (with Paul's patches in place) shows no errors or leaks from valgrind. So, in summary, in this case I think the current gfortran is missing some finalizations (which are fixed by Paul's patches), and ifort is likely doing something wrong and probably calling the finalizer more times than it should. -Andrew On Monday, January 24, 2022 6:49:23 AM PST Salvatore Filippone via Fortran wrote: > And here is the code embedded as text............ sorry about sending an > attachment that was purged > ------------------------- testfinal.f90 --------------------- > module test_type_mod > > type :: my_test_type > integer, allocatable :: i > contains > final :: delete_test_type > end type my_test_type > > interface my_test_type > module procedure new_test_type_object > end interface my_test_type > > contains > > subroutine delete_test_type(this) > type(my_test_type) :: this > > write(*,*) 'Called delete_test_type' > if (allocated(this%i)) deallocate(this%i) > > end subroutine delete_test_type > > > function new_test_type_object(item) result(res) > type(my_test_type) :: res > integer, intent(in) :: item > !Allocation on assignment > res%i=item > end function new_test_type_object > > > end module test_type_mod > > module target_mod > use test_type_mod > type :: outer_type > type(my_test_type), allocatable :: test_item > end type outer_type > > contains > > subroutine new_outer_type(outer,item) > type(outer_type), intent(out) :: outer > integer :: item > > allocate(outer%test_item) > write(*,*) 'Assigning outer%test_item' > outer%test_item = my_test_type(itemi) > write(*,*) 'End of new_outer_type' > end subroutine new_outer_type > > end module target_mod > > program testfinal > use target_mod > > implicit none > > integer :: i=10 > type(outer_type), allocatable :: wrapper > > write(*,*) 'Allocating wrapper ' > allocate(wrapper) > write(*,*) 'Calling new_outer_type ' > call new_outer_type(wrapper,i) > write(*,*) 'DeAllocating wrapper ' > deallocate(wrapper) > > end program testfinal > > On Mon, Jan 24, 2022 at 2:50 PM Salvatore Filippone < > > filippone.salvat...@gmail.com> wrote: > > Hi all > > The attached code compiles and runs fine under both GNU and Intel, but it > > produces different results, in particular the FINAL subroutine is invoked > > just once with GNU, three times with Intel. > > > > It seems to me that they cannot both be right; I am not sure what the > > standard is mandating in this case. > > Any ideas? > > Salvatore > > --------------- Intel > > [pr1eio03@login1: newstuff]$ ifort -v > > ifort version 19.1.1.217 > > [pr1eio03@login1: newstuff]$ ifort -o testfinal testfinal.f90 > > [pr1eio03@login1: newstuff]$ ./testfinal > > > > Allocating wrapper > > Calling new_outer_type > > Assigning outer%test_item > > Called delete_test_type > > Called delete_test_type > > End of new_outer_type > > DeAllocating wrapper > > Called delete_test_type > > > > ----------------------------- GNU > > sfilippo@lagrange newstuff]$ gfortran -v > > Using built-in specs. > > COLLECT_GCC=gfortran > > COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper > > OFFLOAD_TARGET_NAMES=nvptx-none > > OFFLOAD_TARGET_DEFAULT=1 > > Target: x86_64-redhat-linux > > Configured with: ../configure --enable-bootstrap > > --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr > > --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl= > > http://bugzilla.redhat.com/bugzilla --enable-shared > > --enable-threads=posix --enable-checking=release --enable-multilib > > --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions > > --enable-gnu-unique-object --enable-linker-build-id > > --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin > > --enable-initfini-array > > --with-isl=/builddir/build/BUILD/gcc-11.2.1-20210728/obj-x86_64-redhat-lin > > ux/isl-install --enable-offload-targets=nvptx-none --without-cuda-driver > > --enable-gnu-indirect-function --enable-cet --with-tune=generic > > --with-arch_32=i686 --build=x86_64-redhat-linux > > Thread model: posix > > Supported LTO compression algorithms: zlib zstd > > gcc version 11.2.1 20210728 (Red Hat 11.2.1-1) (GCC) > > [sfilippo@lagrange newstuff]$ gfortran -o testfinal testfinal.f90 > > [sfilippo@lagrange newstuff]$ ./testfinal > > > > Allocating wrapper > > Calling new_outer_type > > Assigning outer%test_item > > End of new_outer_type > > DeAllocating wrapper > > Called delete_test_type > > > > --------------------- -- * Andrew Benson: https://abensonca.github.io * Galacticus: https://github.com/galacticusorg/galacticus