The attached code should display Show: f1 1.0000000 Show: f1 2.0000000 Show: f1 3.0000000 Show: f1 4.0000000 three times - however the last call shows Show: f1 2.0000000 Show: f1 3.0000000 Show: f1 4.0000000 Show: f1 0.0000000 i.e. all the array elements seem to be off by 1 (zero based indexing?). Notice that: 1) the problem only shows up when the call to LCB uses array slices, not when using the whole array 2) the problem disappears if the array WORK has explicit size. I am using gfortran --version GNU Fortran (GCC) 4.9.0 20130322 (experimental) Regards, Marco Restelli module m1 implicit none public :: c_stv private type, abstract :: c_stv contains procedure, pass(z) :: lcb procedure, pass(x) :: show end type c_stv contains subroutine lcb(z,y) class(c_stv), intent(in) :: y(:) class(c_stv), intent(inout) :: z integer :: k write(*,*) 'Inside LCB: size is ',size(y) do k=1,size(y) call y(k)%show() enddo end subroutine lcb subroutine show(x) class(c_stv), intent(in) :: x end subroutine show end module m1 module m2 use m1, only: c_stv implicit none public :: t_stv private type, extends(c_stv) :: t_stv real :: f1 contains procedure, pass(x) :: show end type t_stv contains subroutine show(x) class(t_stv), intent(in) :: x write(*,*) 'Show: f1 ', x%f1 end subroutine show end module m2 program test use m1, only: c_stv use m2, only: t_stv implicit none integer :: k type(t_stv) :: x !type(t_stv) :: work(4) ! works fine type(t_stv), allocatable :: work(:) allocate(work(4)) do k=1,4 work(k)%f1 = real(k) enddo write(*,*) 'Values in work are:' do k=1,4 call work(k)%show() enddo write(*,*) 'Call with whole array: works fine' call x%lcb(work) write(*,*) 'Call with array slice: off by 1' call x%lcb(work(:4)) end program test
It does indeed look as if 0-based indexing is being erroneously used: call x%lcb(work(0:3)) prints: Call with array slice: off by 1 Inside LCB: size is 4 Show: f1 1.00000000 Show: f1 2.00000000 Show: f1 3.00000000 Show: f1 4.00000000
Interesting test case - it also fails with crayftn 8.1 and pgi 12.10 (for those: both calls), but works with ifort 13.0. The whole array call has (-fdump-tree-original): work.dim[0].lbound = 1; work.offset = -1; class.6._data = work; while for the failing, off-by-one call one has parm.9.dim[0].lbound = 1; parm.9.offset = 0; class.8._data = parm.9; Due to offset == -1 vs. 0, the off-by-one error occurs.
Reduced test case which shows that the problem is CLASS-specific: module m2 implicit none type :: t_stv real :: f1 end type contains subroutine lcb(y) class(t_stv), intent(in) :: y(:) write(*,*) 'Inside LCB: size is ',size(y) print *,y(1:size(y))%f1 end subroutine end module program test use m2 implicit none type(t_stv), allocatable :: work(:) allocate(work(4)) work(:)%f1 = (/ 1.,2.,3.,4./) write(*,*) 'Values in work are:' print *, work(1:4)%f1 write(*,*) 'Call with whole array: works fine' call lcb(work) write(*,*) 'Call with array slice: off by 1' call lcb(work(:4)) end program When making 'y' a TYPE instead of CLASS, the output is as expected.
When I use gfortran version 7 to compile the code listed in comment 3, executing the resulting binary yields the following output: ./pr56691 Values in work are: 1.00000000 2.00000000 3.00000000 4.00000000 Call with whole array: works fine Inside LCB: size is 4 1.00000000 2.00000000 3.00000000 4.00000000 Call with array slice: off by 1 Inside LCB: size is 4 1.00000000 2.00000000 3.00000000 4.00000000 This is the expected result. The bug might be fixed. LANG=C gfortran-7 -o pr56691 pr56691.f90 -v -W -Wall Driving: gfortran-7 -o pr56691 pr56691.f90 -v -W -Wall -mmacosx-version-min=10.11.6 -asm_macosx_version_min=10.11 -l gfortran -shared-libgcc Using built-in specs. COLLECT_GCC=gfortran-7 COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/7.0.0/lto-wrapper Target: x86_64-apple-darwin15.6.0 Configured with: ../gcc/configure --enable-languages=c,c++,fortran,lto --with-gmp=/sw --with-libiconv-prefix=/sw --with-isl=/sw --with-mpc=/sw --with-system-zlib --program-suffix=-7 Thread model: posix gcc version 7.0.0 20161215 (experimental) [trunk revision 243680] (GCC) COLLECT_GCC_OPTIONS='-o' 'pr56691' '-v' '-Wextra' '-Wall' '-mmacosx-version-min=10.11.6' '-asm_macosx_version_min=10.11' '-shared-libgcc' '-mtune=core2' /usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/7.0.0/f951 pr56691.f90 -fPIC -quiet -dumpbase pr56691.f90 -mmacosx-version-min=10.11.6 -mtune=core2 -auxbase pr56691 -Wextra -Wall -version -fintrinsic-modules-path /usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/finclude -o /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccv54gNH.s GNU Fortran (GCC) version 7.0.0 20161215 (experimental) [trunk revision 243680] (x86_64-apple-darwin15.6.0) compiled by GNU C version 7.0.0 20161215 (experimental) [trunk revision 243680], GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 GNU Fortran2008 (GCC) version 7.0.0 20161215 (experimental) [trunk revision 243680] (x86_64-apple-darwin15.6.0) compiled by GNU C version 7.0.0 20161215 (experimental) [trunk revision 243680], GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 COLLECT_GCC_OPTIONS='-o' 'pr56691' '-v' '-Wextra' '-Wall' '-mmacosx-version-min=10.11.6' '-shared-libgcc' '-mtune=core2' as -arch x86_64 -v -force_cpusubtype_ALL -mmacosx-version-min=10.11 -o /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccSNEf1F.o /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccv54gNH.s Apple LLVM version 8.0.0 (clang-800.0.42.1) Target: x86_64-apple-darwin15.6.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1as -triple x86_64-apple-macosx10.11.0 -filetype obj -main-file-name ccv54gNH.s -target-cpu core2 -fdebug-compilation-dir /Users/Peter/Devel/f90 -dwarf-debug-producer Apple LLVM version 8.0.0 (clang-800.0.42.1) -dwarf-version=2 -mrelocation-model pic -o /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccSNEf1F.o /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccv54gNH.s Reading specs from /usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/../../../libgfortran.spec rename spec lib to liborig COLLECT_GCC_OPTIONS='-o' 'pr56691' '-v' '-Wextra' '-Wall' '-mmacosx-version-min=10.11.6' '-shared-libgcc' '-mtune=core2' COMPILER_PATH=/usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/7.0.0/:/usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/7.0.0/:/usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/:/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/:/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/ LIBRARY_PATH=/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/:/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/../../../ COLLECT_GCC_OPTIONS='-o' 'pr56691' '-v' '-Wextra' '-Wall' '-mmacosx-version-min=10.11.6' '-shared-libgcc' '-mtune=core2' /usr/local/libexec/gcc/x86_64-apple-darwin15.6.0/7.0.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.11.6 -weak_reference_mismatches non-weak -o pr56691 -L/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0 -L/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/../../.. /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccSNEf1F.o -lgfortran -no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lquadmath -lm -lgcc_ext.10.5 -lgcc -lSystem -v collect2 version 7.0.0 20161215 (experimental) [trunk revision 243680] /usr/bin/ld -dynamic -arch x86_64 -macosx_version_min 10.11.6 -weak_reference_mismatches non-weak -o pr56691 -L/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0 -L/usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0/../../.. /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccSNEf1F.o -lgfortran -no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lquadmath -lm -lgcc_ext.10.5 -lgcc -lSystem -v @(#)PROGRAM:ld PROJECT:ld64-274.2 configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS) Library search paths: /usr/local/lib/gcc/x86_64-apple-darwin15.6.0/7.0.0 /usr/local/lib /usr/lib /usr/local/lib Framework search paths: /Library/Frameworks/ /System/Library/Frameworks/ /usr/bin/nm -n /var/folders/97/4qnhjhtn25s86s9hkz0h37_m0000gn/T//ccSNEf1F.o
(In reply to physiker from comment #4) > When I use gfortran version 7 to compile the code listed in comment 3, > executing the resulting binary yields the following output: > > ./pr56691 > Values in work are: > 1.00000000 2.00000000 3.00000000 4.00000000 > Call with whole array: works fine > Inside LCB: size is 4 > 1.00000000 2.00000000 3.00000000 4.00000000 > Call with array slice: off by 1 > Inside LCB: size is 4 > 1.00000000 2.00000000 3.00000000 4.00000000 > > This is the expected result. The bug might be fixed. Confirmed. In fact I see it working already in 6.2. It can definitely be closed.
The test in comment 0 is still giving an off by 1 result (7.0 at r243758): Call with array slice: off by 1 Inside LCB: size is 4 Show: f1 2.00000000 Show: f1 3.00000000 Show: f1 4.00000000 Show: f1 0.00000000
(In reply to Dominique d'Humieres from comment #6) > The test in comment 0 is still giving an off by 1 result (7.0 at r243758): Right, I missed that. Sorry for closing too early. Reduced test case for the remaining failure: module m2 implicit none type :: t_stv real :: f1 end type contains subroutine lcb(y) class(t_stv), intent(in) :: y(:) integer :: k write(*,*) 'Inside LCB: size is ',size(y) do k=1,size(y) write(*,*) 'f1: ', k, y(k)%f1 enddo end subroutine end module program test use m2 implicit none type(t_stv), allocatable :: work(:) allocate(work(4)) work(:)%f1 = (/ 1.,2.,3.,4./) write(*,*) 'Call with whole array: works fine' call lcb(work) write(*,*) 'Call with array slice: off by 1' call lcb(work(:4)) end program Prints: Call with whole array: works fine Inside LCB: size is 4 f1: 1 1.00000000 f1: 2 2.00000000 f1: 3 3.00000000 f1: 4 4.00000000 Call with array slice: off by 1 Inside LCB: size is 4 f1: 1 2.00000000 f1: 2 3.00000000 f1: 3 4.00000000 f1: 4 0.00000000
GCC 7.1 has been released.
*** Bug 84074 has been marked as a duplicate of this bug. ***
The test in comment 3 has likely been fixed by revision r222361 (pr60322).
Author: pault Date: Sat Feb 10 18:16:14 2018 New Revision: 257550 URL: https://gcc.gnu.org/viewcvs?rev=257550&root=gcc&view=rev Log: 2018-02-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/84141 PR fortran/84155 * trans-array.c (gfc_array_init_size): Revert the change made in revision 257356 setting the dtype. * trans-types.c (gfc_get_dtype): Do not use the cached dtype. Call gfc_get_dtype_rank_type every time. PR fortran/56691 * trans-array.c (gfc_conv_expr_descriptor): If the source array is a descriptor type, use its offset, removing the condition that is be a class expression. 2018-02-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/56691 * gfortran.dg/type_to_class_4.f03: New test. Added: trunk/gcc/testsuite/gfortran.dg/type_to_class_4.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-types.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk. Thanks for the report, Marco. Paul