Hi,
I am trying to use type-bound procedures (TBP) with non-scalar pass-object dummy arguments. Although not valid from the standard (C461: "The passed-object dummy argument shall be a scalar, nonpointer, nonallocatable dummy data object..."), it seems to be supported by ifort version 14.0.4 (the version I'm using here) as shown by the following code:
Module MyModule implicit none Type :: MyType integer :: Val contains procedure :: ScaProc procedure :: VecProc End Type contains Subroutine ScaProc( This, Inp, Out ) class(MyType) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp + This%Val End Subroutine Subroutine VecProc( Those, Inp, Out ) class(MyType) ,dimension(:) ,intent(in) :: Those integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp + sum(Those%Val) End Subroutine End Module Program Main use MyModule ,only: MyType implicit none type(MyType) :: Sca type(MyType) ,dimension(10) :: Vec integer :: i integer ,parameter :: Inp = 1000 integer :: Out write(*,"(/,a)") 'Calling a TBP with a scalar passed-object dummy argument:' Sca = MyType(Val=100) call Sca%ScaProc( Inp, Out ) write(*,"(a,g0)") 'Sca%Val = ', Sca%Val write(*,"(a,g0)") 'Inp = ', Inp write(*,"(a,g0)") 'Out = ', Out write(*,"(/,a)") 'Calling a TBP with a non-scalar passed-object dummy argument:' Vec = [ (MyType(Val=i),i=1,size(Vec)) ] call Vec%VecProc( Inp, Out ) write(*,"(a,*(i3,1x))") 'Vec%Val = ', Vec(:)%Val write(*,"(a,g0)") 'Inp = ', Inp write(*,"(a,g0)") 'Out = ', Out End Program
Using ifort version 14.0.4, I am getting the following output:
$ ifort main.F90; ./a.out Calling a TBP with a scalar passed-object dummy argument: Sca%Val = 100 Inp = 1000 Out = 1100 Calling a TBP with a non-scalar passed-object dummy argument: Vec%Val = 1 2 3 4 5 6 7 8 9 10 Inp = 1000 Out = 1055
while gfortran (version 4.8.3 20140911) do not compile this code:
$ gfortran main.F90 main.F90:10.13: procedure :: VecProc 1 Error: Passed-object dummy argument of 'vecproc' at (1) must be scalar
Note that if I had a generic TBP, I get an ICE.
Module MyModule implicit none Type :: MyType integer :: Val contains generic :: Proc => ScaProc, VecProc procedure :: ScaProc procedure :: VecProc End Type contains Subroutine ScaProc( This, Inp, Out ) class(MyType) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp + This%Val End Subroutine Subroutine VecProc( Those, Inp, Out ) class(MyType) ,dimension(:) ,intent(in) :: Those integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp + sum(Those%Val) End Subroutine End Module Program Main use MyModule ,only: MyType implicit none type(MyType) :: Sca type(MyType) ,dimension(10) :: Vec integer :: i integer ,parameter :: Inp = 1000 integer :: Out write(*,"(/,a)") 'Calling a TBP with a scalar passed-object dummy argument:' Sca = MyType(Val=100) call Sca%Proc( Inp, Out ) write(*,"(a,g0)") 'Sca%Val = ', Sca%Val write(*,"(a,g0)") 'Inp = ', Inp write(*,"(a,g0)") 'Out = ', Out write(*,"(/,a)") 'Calling a TBP with a non-scalar passed-object dummy argument:' Vec = [ (MyType(Val=i),i=1,size(Vec)) ] call Vec%Proc( Inp, Out ) write(*,"(a,*(i3,1x))") 'Vec%Val = ', Vec(:)%Val write(*,"(a,g0)") 'Inp = ', Inp write(*,"(a,g0)") 'Out = ', Out End Program
which produce
main_ICE.F90(44): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error. compilation aborted for main_ICE.F90 (code 1)
So, here are my questions:
- Is the "non-scalar pass-object dummy arguments" capability an non-standard extension from intel or just a bug that somehow passes through the compiler checks and happens to gives the correct results ?
- Is this "scalar pass-object dummy arguments" restriction on TBP is likely to be relaxed in the standard ?
Thanks