The following code compiles fine but produces a runtime error when trying to perform a dynamic dispatch: !================================================================ 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 allocate( seq(10) ) call init( ke_strat, lw_strat ) call ke_strat % preUpdate() call ke_strat % update() call ke_strat % postUpdate() end program main The specific runtime error is: At line 111 of file test.f90 Fortran runtime error: internal error: bad hash value in dynamic dispatch Line 111 above is the line: call this % child % preUpdate() If I uncomment the line the comment "! Uncomment the line below and it runs fine" the code builds and runs without an error.
Created attachment 21136 [details] test case described in post
Can you update to GCC 4.6? I get the same error with 4.5, but with 4.6 I get the same result as with NAG or Intel. The reason is that gfortran now uses a proper vtable. Or in the words of http://gcc.gnu.org/gcc-4.6/changes.html : * Improved support for polymorphism between libraries and programs and for complicated inheritance patterns (cf. http://gcc.gnu.org/wiki/OOP) Newer binaries can be found at http://gcc.gnu.org/wiki/GFortranBinaries
Closing as fixed.
Subject: Bug 44863 Author: janus Date: Sat Aug 21 14:50:57 2010 New Revision: 163445 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163445 Log: 2010-08-21 Janus Weil <janus@gcc.gnu.org> PR fortran/45271 PR fortran/45290 * class.c (add_proc_comp): Add static initializer for PPCs. (add_procs_to_declared_vtab): Modified comment. * module.c (mio_component): Add argument 'vtype'. Don't read/write the initializer if the component is part of a vtype. (mio_component_list): Add argument 'vtype', pass it on to 'mio_component'. (mio_symbol): Modified call to 'mio_component_list'. * trans.h (gfc_conv_initializer): Modified prototype. (gfc_trans_assign_vtab_procs): Removed. * trans-common.c (create_common): Modified call to 'gfc_conv_initializer'. * trans-decl.c (gfc_get_symbol_decl,get_proc_pointer_decl, gfc_emit_parameter_debug_info): Modified call to 'gfc_conv_initializer'. (build_function_decl): Remove assertion. * trans-expr.c (gfc_conv_derived_to_class,gfc_trans_class_assign): Removed call to 'gfc_trans_assign_vtab_procs'. (gfc_conv_initializer): Add argument 'procptr'. (gfc_conv_structure): Modified call to 'gfc_conv_initializer'. (gfc_trans_assign_vtab_procs): Removed. * trans-stmt.c (gfc_trans_allocate): Removed call to 'gfc_trans_assign_vtab_procs'. 2010-08-21 Janus Weil <janus@gcc.gnu.org> PR fortran/44863 PR fortran/45271 PR fortran/45290 * gfortran.dg/dynamic_dispatch_10.f03: New (PR 44863 comment #1). * gfortran.dg/pointer_init_5.f90: New (PR 45290 comment #6). * gfortran.dg/typebound_call_18.f03: New (PR 45271 comment #3). Added: trunk/gcc/testsuite/gfortran.dg/dynamic_dispatch_10.f03 trunk/gcc/testsuite/gfortran.dg/pointer_init_5.f90 trunk/gcc/testsuite/gfortran.dg/typebound_call_18.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/class.c trunk/gcc/fortran/module.c trunk/gcc/fortran/trans-common.c trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/fortran/trans.h trunk/gcc/testsuite/ChangeLog
r163445 adds comment #1 to the testsuite, because it uncovered a regression in my recent patch for PR 45271 (thanks to Dominique for noticing).