Plugins: Add label-text.h to CPPLIB_H so it will be installed [PR115288]
[official-gcc.git] / gcc / testsuite / gfortran.dg / dynamic_dispatch_10.f03
blob2831b088743e28371e0f4c2c05461f3a89747b2f
1 ! { dg-do run }
3 ! [OOP] Fortran runtime error: internal error: bad hash value in dynamic dispatch
5 ! Contributed by David Car <david.car7@gmail.com>
7 module BaseStrategy
9   type, public, abstract :: Strategy
10    contains
11      procedure(strategy_update), pass( this ), deferred :: update
12      procedure(strategy_pre_update), pass( this ), deferred :: preUpdate
13      procedure(strategy_post_update), pass( this ), deferred :: postUpdate
14   end type Strategy
16   abstract interface
17      subroutine strategy_update( this )
18        import Strategy
19        class (Strategy), target, intent(in) :: this
20      end subroutine strategy_update
21   end interface
23   abstract interface
24      subroutine strategy_pre_update( this )
25        import Strategy
26        class (Strategy), target, intent(in) :: this
27      end subroutine strategy_pre_update
28   end interface
30   abstract interface
31      subroutine strategy_post_update( this )
32        import Strategy
33        class (Strategy), target, intent(in) :: this
34      end subroutine strategy_post_update
35   end interface
36      
37 end module BaseStrategy
39 !==============================================================================
41 module LaxWendroffStrategy
43   use BaseStrategy
45   private :: update, preUpdate, postUpdate
47   type, public, extends( Strategy ) :: LaxWendroff
48      class (Strategy), pointer :: child => null()
49      contains
50        procedure, pass( this ) :: update
51        procedure, pass( this ) :: preUpdate
52        procedure, pass( this ) :: postUpdate
53   end type LaxWendroff
55 contains
57   subroutine update( this )
58     class (LaxWendroff), target, intent(in) :: this
60     print *, 'Calling LaxWendroff update'
61   end subroutine update
63   subroutine preUpdate( this )
64     class (LaxWendroff), target, intent(in) :: this
65     
66     print *, 'Calling LaxWendroff preUpdate'
67   end subroutine preUpdate
69   subroutine postUpdate( this )
70     class (LaxWendroff), target, intent(in) :: this
71     
72     print *, 'Calling LaxWendroff postUpdate'
73   end subroutine postUpdate
74   
75 end module LaxWendroffStrategy
77 !==============================================================================
79 module KEStrategy
81   use BaseStrategy
82   ! Uncomment the line below and it runs fine
83   ! use LaxWendroffStrategy
85   private :: update, preUpdate, postUpdate
87   type, public, extends( Strategy ) :: KE
88      class (Strategy), pointer :: child => null()
89      contains
90        procedure, pass( this ) :: update
91        procedure, pass( this ) :: preUpdate
92        procedure, pass( this ) :: postUpdate
93   end type KE
94   
95 contains
97   subroutine init( this, other )
98     class (KE), intent(inout) :: this
99     class (Strategy), target, intent(in) :: other
101     this % child => other
102   end subroutine init
104   subroutine update( this )
105     class (KE), target, intent(in) :: this
107     if ( associated( this % child ) ) then
108        call this % child % update()
109     end if
111     print *, 'Calling KE update'
112   end subroutine update
114  subroutine preUpdate( this )
115     class (KE), target, intent(in) :: this
116     
117     if ( associated( this % child ) ) then
118        call this % child % preUpdate()
119     end if
121     print *, 'Calling KE preUpdate'
122   end subroutine preUpdate
124   subroutine postUpdate( this )
125     class (KE), target, intent(in) :: this
127     if ( associated( this % child ) ) then
128        call this % child % postUpdate()
129     end if
130     
131     print *, 'Calling KE postUpdate'
132   end subroutine postUpdate
133   
134 end module KEStrategy
136 !==============================================================================
138 program main
140   use LaxWendroffStrategy
141   use KEStrategy
143   type :: StratSeq
144      class (Strategy), pointer :: strat => null()
145   end type StratSeq
147   type (LaxWendroff), target :: lw_strat
148   type (KE), target :: ke_strat
150   type (StratSeq), allocatable, dimension( : ) :: seq
151   
152   allocate( seq(10) )
154   call init( ke_strat, lw_strat )
155   call ke_strat % preUpdate()
156   call ke_strat % update()
157   call ke_strat % postUpdate()
158   ! call lw_strat % update()
160   seq( 1 ) % strat => ke_strat
161   seq( 2 ) % strat => lw_strat
163   call seq( 1 ) % strat % update()
165   do i = 1, 2
166      call seq( i ) % strat % update()
167   end do