Originally this bug can be triggered in the following example using OpenMPI:
module provider_m
use iso_c_binding
interface
subroutine callback(userdata)
import
type(c_ptr), intent(in) :: userdata(:)
end
end interface
contains
subroutine go(prec)
procedure(callback) prec
end
end
module consumer_m
use mpi_f08 ! <-- remove this to make the error disappear
use provider_m
contains
subroutine process
call go(op)
end
subroutine op(userdata)
type(c_ptr), intent(in) :: userdata(:)
end
end
This was actually quite hard to reduce, because it doesn’t trigger reliably. The smallest dependency-free example I could make is 164 lines and has five modules. Any little variation to this example, e.g. deleting a seemingly unused variable in one of the modules makes the bug disappear.
Live example on Compiler Explorer
minimal.f90
module mpi_types
type MPI_Status
end type
type MPI_Comm
end type
type MPI_Datatype
integer :: MPI_VAL
end type
type MPI_Errhandler
integer :: MPI_VAL
end type
type MPI_VAL
end type
type MPI_Group
integer :: MPI_VAL
end type
type MPI_Info
integer :: MPI_VAL
end type
type MPI_Message
integer :: MPI_VAL
end type
type MPI_Op
integer :: MPI_VAL
end type
type MPI_Request
end type
type MPI_Session
end type
type MPI_Win
end type
end
module mpi_f08_types
use mpi_types
logical :: MPI_COMM_WORLD(1)
type(MPI_Message) :: MPI_MESSAGE_NO_PROC(1)
type(MPI_Info) :: MPI_INFO_ENV(1)
type(MPI_Op) :: MPI_MAX(1)
type(MPI_Op) :: MPI_MIN(1)
type(MPI_Op) :: MPI_SUM(1)
type(MPI_Op) :: MPI_PROD(1)
type(MPI_Op) :: MPI_LAND(1)
type(MPI_Op) :: MPI_BAND(1)
type(MPI_Op) :: MPI_LOR(1)
type(MPI_Op) :: MPI_BOR(1)
type(MPI_Op) :: MPI_LXOR(1)
type(MPI_Op) :: MPI_BXOR(1)
type(MPI_Op) :: MPI_MAXLOC(1)
type(MPI_Op) :: MPI_COMM_NULL(1)
type(MPI_Datatype) :: MPI_DATATYPE_NULL(1)
type(MPI_Errhandler) :: MPI_ERRHANDLER_NULL(1)
type(MPI_Group) :: MPI_GROUP_NULL(1)
type(MPI_Info) :: MPI_INFO_NULL(1)
type(MPI_Message) :: MPI_MESSAGE_NULL(1)
type(MPI_Op) :: MPI_SESSION_NULL(1)
type(MPI_Datatype) :: MPI_AINT(1)
type(MPI_Datatype) :: MPI_BYTE(1)
type(MPI_Datatype) :: MPI_PACKED(1)
type(MPI_Datatype) :: MPI_UB(1)
type(MPI_Datatype) :: MPI_LB(1)
type(MPI_Datatype) :: MPI_CHAR(1)
type(MPI_Datatype) :: MPI_SIGNED_CHAR(1)
type(MPI_Datatype) :: MPI_UNSIGNED_CHAR(1)
type(MPI_Datatype) :: MPI_WCHAR(1)
type(MPI_Datatype) :: MPI_CHARACTER(1)
type(MPI_Datatype) :: MPI_LOGICAL(1)
type(MPI_Datatype) :: MPI_INT(1)
type(MPI_Datatype) :: MPI_INT16_T(1)
type(MPI_Datatype) :: MPI_INT32_T(1)
type(MPI_Datatype) :: MPI_INT64_T(1)
type(MPI_Datatype) :: MPI_INT8_T(1)
type(MPI_Datatype) :: MPI_UINT16_T(1)
type(MPI_Datatype) :: MPI_UINT32_T(1)
type(MPI_Datatype) :: MPI_UINT64_T(1)
type(MPI_Datatype) :: MPI_UINT8_T(1)
type(MPI_Datatype) :: MPI_SHORT(1)
type(MPI_Datatype) :: MPI_UNSIGNED_SHORT(1)
type(MPI_Datatype) :: MPI_UNSIGNED(1)
type(MPI_Datatype) :: MPI_LONG(1)
type(MPI_Datatype) :: MPI_UNSIGNED_LONG(1)
type(MPI_Datatype) :: MPI_LONG_LONG(1)
type(MPI_Datatype) :: MPI_UNSIGNED_LONG_LONG(1)
type(MPI_Datatype) :: MPI_LONG_LONG_INT(1)
type(MPI_Datatype) :: MPI_INTEGER(1)
type(MPI_Datatype) :: MPI_INTEGER1(1)
type(MPI_Datatype) :: MPI_INTEGER2(1)
type(MPI_Datatype) :: MPI_INTEGER4(1)
type(MPI_Datatype) :: MPI_INTEGER8(1)
type(MPI_Datatype) :: MPI_INTEGER16(1)
type(MPI_Datatype) :: MPI_FLOAT(1)
type(MPI_Datatype) :: MPI_DOUBLE(1)
type(MPI_Datatype) :: MPI_LONG_DOUBLE(1)
type(MPI_Datatype) :: MPI_REAL(1)
type(MPI_Datatype) :: MPI_REAL4(1)
type(MPI_Datatype) :: MPI_REAL8(1)
type(MPI_Datatype) :: MPI_REAL16(1)
type(MPI_Datatype) :: MPI_DOUBLE_PRECISION(1)
type(MPI_Datatype) :: MPI_C_COMPLEX(1)
type(MPI_Datatype) :: MPI_C_FLOAT_COMPLEX(1)
type(MPI_Datatype) :: MPI_C_DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_C_LONG_DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_CXX_COMPLEX(1)
type(MPI_Datatype) :: MPI_CXX_FLOAT_COMPLEX(1)
type(MPI_Datatype) :: MPI_CXX_DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_CXX_LONG_DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_COMPLEX(1)
type(MPI_Datatype) :: MPI_COMPLEX8(1)
type(MPI_Datatype) :: MPI_COMPLEX16(1)
type(MPI_Datatype) :: MPI_COMPLEX32(1)
type(MPI_Datatype) :: MPI_DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_FLOAT_INT(1)
type(MPI_Datatype) :: MPI_DOUBLE_INT(1)
type(MPI_Datatype) :: MPI_2REAL(1)
type(MPI_Datatype) :: MPI_2DOUBLE_PRECISION(1)
type(MPI_Datatype) :: MPI_2INT(1)
type(MPI_Datatype) :: MPI_SHORT_INT(1)
type(MPI_Datatype) :: MPI_LONG_INT(1)
type(MPI_Datatype) :: MPI_LONG_DOUBLE_INT(1)
type(MPI_Datatype) :: MPI_2INTEGER(1)
type(MPI_Datatype) :: MPI_2COMPLEX(1)
type(MPI_Datatype) :: MPI_2DOUBLE_COMPLEX(1)
type(MPI_Datatype) :: MPI_REAL2(1)
type(MPI_Datatype) :: MPI_LOGICAL1(1)
type(MPI_Datatype) :: MPI_LOGICAL2(1)
type(MPI_Datatype) :: MPI_LOGICAL4(1)
type(MPI_Datatype) :: MPI_LOGICAL8(1)
type(MPI_Datatype) :: MPI_C_BOOL(1)
type(MPI_Datatype) :: MPI_CXX_BOOL(1)
type(MPI_Datatype) :: MPI_COUNT(1)
type(MPI_Datatype) :: MPI_OFFSET(1)
type(MPI_Datatype), parameter :: MPI_COMPLEX4 = MPI_Datatype(0)
end
module pmpi_f08_interfaces
interface
subroutine PMPI_Neighbor_alltoallw_init_f08
use mpi_f08_types
use ISO_C_BINDING
end
end interface
end
module provider_m
use iso_c_binding
interface
subroutine callback(userdata)
import
type(c_ptr), intent(in) :: userdata(:)
end
end interface
contains
subroutine go(prec)
procedure(callback) prec
end
end
module consumer_m
use pmpi_f08_interfaces
use provider_m
contains
subroutine process
call go(op)
end
subroutine op(userdata)
type(c_ptr), intent(in) :: userdata(:)
end
end
Since this is so hard to trigger it makes me think that this might have something to do with the internal state of the parser.