blob: 2831b088743e28371e0f4c2c05461f3a89747b2f [file] [log] [blame]
! { dg-do run }
!
! [OOP] Fortran runtime error: internal error: bad hash value in dynamic dispatch
!
! Contributed by David Car <david.car7@gmail.com>
module BaseStrategy
type, public, abstract :: Strategy
contains
procedure(strategy_update), pass( this ), deferred :: update
procedure(strategy_pre_update), pass( this ), deferred :: preUpdate
procedure(strategy_post_update), pass( this ), deferred :: postUpdate
end type Strategy
abstract interface
subroutine strategy_update( this )
import Strategy
class (Strategy), target, intent(in) :: this
end subroutine strategy_update
end interface
abstract interface
subroutine strategy_pre_update( this )
import Strategy
class (Strategy), target, intent(in) :: this
end subroutine strategy_pre_update
end interface
abstract interface
subroutine strategy_post_update( this )
import Strategy
class (Strategy), target, intent(in) :: this
end subroutine strategy_post_update
end interface
end module BaseStrategy
!==============================================================================
module LaxWendroffStrategy
use BaseStrategy
private :: update, preUpdate, postUpdate
type, public, extends( Strategy ) :: LaxWendroff
class (Strategy), pointer :: child => null()
contains
procedure, pass( this ) :: update
procedure, pass( this ) :: preUpdate
procedure, pass( this ) :: postUpdate
end type LaxWendroff
contains
subroutine update( this )
class (LaxWendroff), target, intent(in) :: this
print *, 'Calling LaxWendroff update'
end subroutine update
subroutine preUpdate( this )
class (LaxWendroff), target, intent(in) :: this
print *, 'Calling LaxWendroff preUpdate'
end subroutine preUpdate
subroutine postUpdate( this )
class (LaxWendroff), target, intent(in) :: this
print *, 'Calling LaxWendroff postUpdate'
end subroutine postUpdate
end module LaxWendroffStrategy
!==============================================================================
module KEStrategy
use BaseStrategy
! Uncomment the line below and it runs fine
! use LaxWendroffStrategy
private :: update, preUpdate, postUpdate
type, public, extends( Strategy ) :: KE
class (Strategy), pointer :: child => null()
contains
procedure, pass( this ) :: update
procedure, pass( this ) :: preUpdate
procedure, pass( this ) :: postUpdate
end type KE
contains
subroutine init( this, other )
class (KE), intent(inout) :: this
class (Strategy), target, intent(in) :: other
this % child => other
end subroutine init
subroutine update( this )
class (KE), target, intent(in) :: this
if ( associated( this % child ) ) then
call this % child % update()
end if
print *, 'Calling KE update'
end subroutine update
subroutine preUpdate( this )
class (KE), target, intent(in) :: this
if ( associated( this % child ) ) then
call this % child % preUpdate()
end if
print *, 'Calling KE preUpdate'
end subroutine preUpdate
subroutine postUpdate( this )
class (KE), target, intent(in) :: this
if ( associated( this % child ) ) then
call this % child % postUpdate()
end if
print *, 'Calling KE postUpdate'
end subroutine postUpdate
end module KEStrategy
!==============================================================================
program main
use LaxWendroffStrategy
use KEStrategy
type :: StratSeq
class (Strategy), pointer :: strat => null()
end type StratSeq
type (LaxWendroff), target :: lw_strat
type (KE), target :: ke_strat
type (StratSeq), allocatable, dimension( : ) :: seq
allocate( seq(10) )
call init( ke_strat, lw_strat )
call ke_strat % preUpdate()
call ke_strat % update()
call ke_strat % postUpdate()
! call lw_strat % update()
seq( 1 ) % strat => ke_strat
seq( 2 ) % strat => lw_strat
call seq( 1 ) % strat % update()
do i = 1, 2
call seq( i ) % strat % update()
end do
end