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