The present I/O infrastructure for user-defined derived type I/O subroutines works fine for type-bound I/O generic bindings. It also works for explicit INTERFACE blocks and GENERIC statements that define UDDIO subroutines in the same scope as the definition of the derived type, so long as the specific procedures in those bindings are module procedures or external procedures. For non-type-bound UDDTIO specific procedures that are dummy procedures, thunks of inner procedures, or procedure pointers, or that are defined with interfaces or GENERIC outside the scope of the definition of the derived type, a new runtime I/O API is needed so that lowering can generate a call that supplies the appropriate procedure as well as the defined type instance. This patch specifies and implements this new runtime API and provides utility routines for lowering to use to determine whether it should be called for any particular OutputItem or InputItem in the parse tree. Differential Revision: https://reviews.llvm.org/D146571
38 lines
1.3 KiB
Fortran
38 lines
1.3 KiB
Fortran
! RUN: %python %S/test_errors.py %s %flang_fc1
|
|
! Check for distinguishability of defined I/O procedures defined within
|
|
! and outside their types.
|
|
module m1
|
|
type t1
|
|
integer n
|
|
contains
|
|
procedure :: readt1a, readt1b
|
|
!ERROR: Generic 'read(unformatted)' may not have specific procedures 'readt1a' and 'readt1b' as their interfaces are not distinguishable
|
|
generic :: read(unformatted) => readt1a, readt1b
|
|
end type
|
|
type t2
|
|
integer n
|
|
end type
|
|
type t3
|
|
integer n
|
|
end type
|
|
!ERROR: Generic 'read(unformatted)' may not have specific procedures 'readt2a' and 'readt2b' as their interfaces are not distinguishable
|
|
interface read(unformatted)
|
|
module procedure :: readt1a, readt2a, readt2b, readt3
|
|
end interface
|
|
contains
|
|
#define DEFINE_READU(name, type) \
|
|
subroutine name(dtv, unit, iostat, iomsg); \
|
|
class(type), intent(in out) :: dtv; \
|
|
integer, intent(in) :: unit; \
|
|
integer, intent(out) :: iostat; \
|
|
character(*), intent(in out) :: iomsg; \
|
|
read(unit, iostat=iostat, iomsg=iomsg) dtv%n; \
|
|
end subroutine name
|
|
!ERROR: Derived type 't1' has conflicting type-bound input/output procedure 'read(unformatted)'
|
|
DEFINE_READU(readt1a, t1)
|
|
DEFINE_READU(readt1b, t1)
|
|
DEFINE_READU(readt2a, t2)
|
|
DEFINE_READU(readt2b, t2)
|
|
DEFINE_READU(readt3, t3)
|
|
end module
|