This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Incorrect behavior when assigning pointer


Hi Tobias:

> I think it would be useful to find out whether gfortran has a bug, but
> your program it too convoluted to really see it. (Maybe one does, if one
> prints out your program and manually runs it with pen and paper.)

Here's a simplified version (although, perhaps not simple enough still):

module G_Nodes

  type :: nc
    type(tn), pointer :: hostNode
  end type nc

  type, extends(nc) :: ncBh
  end type ncBh

  type, public, extends(ncBh) :: ncBhStd
    double precision :: massSeedData
  end type ncBhStd

  type, public :: tn
    class (ncBh), allocatable, dimension(:) :: cBh
  end type tn

  type(ncBhStd) :: defaultBhC

contains

  subroutine Node_C_Bh_Move(targetNode)
    implicit none
    type (tn  ), intent(inout) , target       :: targetNode
    class(ncBh), allocatable   , dimension(:) :: instancesTemporary

! These two lines result in the wrong result:
    allocate(instancesTemporary(2),source=defaultBhC)
    call Move_Alloc(instancesTemporary,targetNode%cBh)
! These two lines give the correct result:
!!deallocate(targetNode%cBh)
!!allocate(targetNode%cBh(2))
    targetNode%cBh(1)%hostNode => targetNode
    targetNode%cBh(2)%hostNode => targetNode
    return
  end subroutine Node_C_Bh_Move

 function bhGet(self,instance)
    implicit none
    class (ncBh), pointer               :: bhGet
    class (tn  ), intent(inout), target :: self
    integer     , intent(in   )         :: instance

    bhGet => self%cBh(instance)
    return
  end function bhGet

end module G_Nodes

program test
  use G_Nodes
  implicit none
  type (tn  ), target  :: b
  class(ncBh), pointer :: bh
  class(ncBh), allocatable, dimension(:) :: t

  allocate(b%cBh(1),source=defaultBhC)
  b%cBh(1)%hostNode => b
  write (0,*) "#1 this works"
  write (0,*) loc(b),'=',loc(b%cBh(1)%hostNode)
  write (0,*)

  call Node_C_Bh_Move(b)

  write (0,*) "#2 this works"
  write (0,*) loc(b),'=',loc(b%cBh(1)%hostNode)
  write (0,*) loc(b),'=',loc(b%cBh(2)%hostNode)
  write (0,*)

  write (0,*) "#3 this does not"
  bh => bhGet(b,instance=1)
  write (0,*) loc(b),'=',loc(bh%hostNode)
  bh => bhGet(b,instance=2)
  write (0,*) loc(b),'=',loc(bh%hostNode)

end program test

$ gfortran test.F90 -o test.exe -g
$ test.exe 
 #1 this works
              6299264 =              6299264

 #2 this works
              6299264 =              6299264
              6299264 =              6299264

 #3 this does not
              6299264 =              6299264
              6299264 =                    0

The numbers shown are now the loc()'s of the pointers (to keep the code 
simpler). #2 shows that if I access the "hostNode"'s directly, using 
b%cBh(2)%hostNode for example, then the correct result is given, but if I use 
the bhGet() function to get the cBh component and then access its hostNode 
component I get the wrong result.

Also, it seems that replacing the allocate()+move_alloc() with a 
deallocate()+allocate() (see commented lines in Node_C_Bh_Move()) results in 
the correct behavior.

-Andrew.

-- 

* Andrew Benson: http://users.obs.carnegiescience.edu/abenson/contact.html

* Galacticus: http://sites.google.com/site/galacticusmodel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]