http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58043

            Bug ID: 58043
           Summary: Incorrect behaviour of polymorphic array
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: frank.otto at pci dot uni-heidelberg.de

Created attachment 30580
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30580&action=edit
test case

The following test case (also attached) produces incorrect output using
gfortran 4.8.1 (also tested: 4.8.0, 4.7.3). It uses a polymorphic array
[dofs(:)] where the polymorphic type [dof_t] contains an allocatable array
[grd(:)]. When accessed through an element of the polymorphic array, the
array descriptor of grd(:) seems wrong.

**** testcase.f90 ****

module types_m
implicit none

type,abstract :: dof_t
   integer :: gdim
   real(kind=8),allocatable :: grd(:)
   contains
   procedure(dofinit_if),deferred :: init
end type dof_t

type,extends(dof_t) :: adof_t
   contains
   procedure :: init => adofinit
end type adof_t

abstract interface
   subroutine dofinit_if(dof,gdim,xi,xf)
      import :: dof_t
      class(dof_t) :: dof
      integer      :: gdim
      real(kind=8) :: xi,xf
   end subroutine dofinit_if
end interface

contains

subroutine adofinit(dof,gdim,xi,xf)
   class(adof_t) :: dof
   integer       :: gdim,g
   real(kind=8)  :: xi,xf,dx
   dof%gdim = gdim
   allocate(dof%grd(gdim))
   dx = (xf-xi)/(gdim-1)
   do g=1,gdim
      dof%grd(g) = xi + (g-1)*dx
   enddo
   write (*,'(a)') "---- grd in adofinit ----"
   do g=1,gdim
      write (*,'(i5,f12.4)') g, dof%grd(g)
   enddo
end subroutine adofinit

end module types_m


program main
use types_m
implicit none

class(dof_t),pointer :: dofs(:)
integer              :: g

allocate(adof_t :: dofs(1))
call dofs(1)%init(17, -8.d0, 8.d0)

write (*,'(a)') "---- grd in main ----"
do g=1,dofs(1)%gdim
   write (*,'(i5,f12.4)') g, dofs(1)%grd(g)
enddo

end program main



**** gfortran version ****

$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/cvos/shared/apps/gcc/4.8.1/libexec/gcc/x86_64-unknown-linux-gnu/4.8.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.8.1/configure --prefix=/cvos/shared/apps/gcc/4.8.1
--enable-languages=c,c++,fortran,go,objc
--with-gmp=/cvos/shared/apps/gcc/4.8/support
--with-mpfr=/cvos/shared/apps/gcc/4.8/support
--with-mpc=/cvos/shared/apps/gcc/4.8/support
--with-isl=/cvos/shared/apps/gcc/4.8/support
--with-cloog=/cvos/shared/apps/gcc/4.8/support --disable-nls --enable-shared
--enable-threads=posix --with-system-zlib --with-tune=native
Thread model: posix
gcc version 4.8.1 (GCC) 



**** Compilation ****

$ gfortran -Wall testcase.f90 
(no messages)



**** Observed Output ****

$ ./a.out
---- grd in adofinit ----
    1     -8.0000
    2     -7.0000
    3     -6.0000
    4     -5.0000
    5     -4.0000
    6     -3.0000
    7     -2.0000
    8     -1.0000
    9      0.0000
   10      1.0000
   11      2.0000
   12      3.0000
   13      4.0000
   14      5.0000
   15      6.0000
   16      7.0000
   17      8.0000
---- grd in main ----
    1     -8.0000
    2     -1.0000
    3      6.0000
    4      0.0000
    5      0.0000
    6      0.0000
    7      0.0000
    8      0.0000
    9      0.0000
   10      0.0000
   11      0.0000
   12      0.0000
   13      0.0000
   14      0.0000
   15      0.0000
   16      0.0000
   17      0.0000



**** Expected Output ****

Both blocks of numbers should be the same.

When compiled with Intel Fortran 13.1.0, the test case produces the expected
output, and also no warnings are produced.



**** Comments ****

What also doesn't work:
* dof_t%grd as pointer instead of allocatable (same output)
* in main, dofs(:) as allocatable instead of pointer (same output)

What does work:
* Using a scalar [class(dof_t),pointer::dof] polymorphic variable instead
  of the polymorphic array.

The observed behaviour looks like something is wrong with the array
descriptor of grd(:), because this array is (in main) traversed with
a too large stride -- only every 7th element is visited. In a larger
program, this behaviour eventually leads to invalid memory access.

Reply via email to