! RUN: %python %S/test_modfile.py %s %flang_fc1 -flogical-abbreviations -fxor-operator
! Resolution of user-defined operators in expressions.
! Test by using generic function in a specification expression that needs
! to be written to a .mod file.
! Numeric operators
module m1
type :: t
sequence
logical :: x
end type
interface operator(+)
pure integer(8) function add_ll(x, y)
logical, intent(in) :: x, y
end
pure integer(8) function add_li(x, y)
logical, intent(in) :: x
integer, intent(in) :: y
end
pure integer(8) function add_tt(x, y)
import :: t
type(t), intent(in) :: x, y
end
end interface
interface operator(/)
pure integer(8) function div_tz(x, y)
import :: t
type(t), intent(in) :: x
complex, intent(in) :: y
end
pure integer(8) function div_ct(x, y)
import :: t
character(10), intent(in) :: x
type(t), intent(in) :: y
end
end interface
contains
subroutine s1(x, y, z)
logical :: x, y
real :: z(x + y) ! resolves to add_ll
end
subroutine s2(x, y, z)
logical :: x
integer :: y
real :: z(x + y) ! resolves to add_li
end
subroutine s3(x, y, z)
type(t) :: x
complex :: y
real :: z(x / y) ! resolves to div_tz
end
subroutine s4(x, y, z)
character(10) :: x
type(t) :: y
real :: z(x / y) ! resolves to div_ct
end
end
!Expect: m1.mod
!module m1
! type :: t
! sequence
! logical(4) :: x
! end type
! interface
! pure function add_ll(x, y)
! logical(4), intent(in) :: x
! logical(4), intent(in) :: y
! integer(8) :: add_ll
! end
! end interface
! interface
! pure function add_li(x, y)
! logical(4), intent(in) :: x
! integer(4), intent(in) :: y
! integer(8) :: add_li
! end
! end interface
! interface
! pure function add_tt(x, y)
! import :: t
! type(t), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: add_tt
! end
! end interface
! interface
! pure function div_tz(x, y)
! import :: t
! type(t), intent(in) :: x
! complex(4), intent(in) :: y
! integer(8) :: div_tz
! end
! end interface
! interface
! pure function div_ct(x, y)
! import :: t
! character(10_4, 1), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: div_ct
! end
! end interface
! interface operator(+)
! procedure :: add_ll
! procedure :: add_li
! procedure :: add_tt
! end interface
! interface operator(/)
! procedure :: div_tz
! procedure :: div_ct
! end interface
!contains
! subroutine s1(x, y, z)
! logical(4) :: x
! logical(4) :: y
! real(4) :: z(1_8:add_ll(x, y))
! end
! subroutine s2(x, y, z)
! logical(4) :: x
! integer(4) :: y
! real(4) :: z(1_8:add_li(x, y))
! end
! subroutine s3(x, y, z)
! type(t) :: x
! complex(4) :: y
! real(4) :: z(1_8:div_tz(x, y))
! end
! subroutine s4(x, y, z)
! character(10_4, 1) :: x
! type(t) :: y
! real(4) :: z(1_8:div_ct(x, y))
! end
!end
! Logical operators
module m2
type :: t
sequence
logical :: x
end type
interface operator(.And.)
pure integer(8) function and_ti(x, y)
import :: t
type(t), intent(in) :: x
integer, intent(in) :: y
end
pure integer(8) function and_li(x, y)
logical, intent(in) :: x
integer, intent(in) :: y
end
end interface
! Alternative spelling of .AND.
interface operator(.a.)
pure integer(8) function and_tt(x, y)
import :: t
type(t), intent(in) :: x, y
end
end interface
interface operator(.x.)
pure integer(8) function neqv_tt(x, y)
import :: t
type(t), intent(in) :: x, y
end
end interface
interface operator(.neqv.)
pure integer(8) function neqv_rr(x, y)
real, intent(in) :: x, y
end
end interface
contains
subroutine s1(x, y, z)
type(t) :: x
integer :: y
real :: z(x .and. y) ! resolves to and_ti
end
subroutine s2(x, y, z)
logical :: x
integer :: y
real :: z(x .a. y) ! resolves to and_li
end
subroutine s3(x, y, z)
type(t) :: x, y
real :: z(x .and. y) ! resolves to and_tt
end
subroutine s4(x, y, z)
type(t) :: x, y
real :: z(x .neqv. y) ! resolves to neqv_tt
end
subroutine s5(x, y, z)
real :: x, y
real :: z(x .xor. y) ! resolves to neqv_rr
end
end
!Expect: m2.mod
!module m2
! type :: t
! sequence
! logical(4) :: x
! end type
! interface
! pure function and_ti(x, y)
! import :: t
! type(t), intent(in) :: x
! integer(4), intent(in) :: y
! integer(8) :: and_ti
! end
! end interface
! interface
! pure function and_li(x, y)
! logical(4), intent(in) :: x
! integer(4), intent(in) :: y
! integer(8) :: and_li
! end
! end interface
! interface
! pure function and_tt(x, y)
! import :: t
! type(t), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: and_tt
! end
! end interface
! interface
! pure function neqv_tt(x, y)
! import :: t
! type(t), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: neqv_tt
! end
! end interface
! interface
! pure function neqv_rr(x, y)
! real(4), intent(in) :: x
! real(4), intent(in) :: y
! integer(8) :: neqv_rr
! end
! end interface
! interface operator( .and.)
! procedure :: and_ti
! procedure :: and_li
! procedure :: and_tt
! end interface
! interface operator(.x.)
! procedure :: neqv_tt
! procedure :: neqv_rr
! end interface
!contains
! subroutine s1(x, y, z)
! type(t) :: x
! integer(4) :: y
! real(4) :: z(1_8:and_ti(x, y))
! end
! subroutine s2(x, y, z)
! logical(4) :: x
! integer(4) :: y
! real(4) :: z(1_8:and_li(x, y))
! end
! subroutine s3(x, y, z)
! type(t) :: x
! type(t) :: y
! real(4) :: z(1_8:and_tt(x, y))
! end
! subroutine s4(x, y, z)
! type(t) :: x
! type(t) :: y
! real(4) :: z(1_8:neqv_tt(x, y))
! end
! subroutine s5(x, y, z)
! real(4) :: x
! real(4) :: y
! real(4) :: z(1_8:neqv_rr(x, y))
! end
!end
! Relational operators
module m3
type :: t
sequence
logical :: x
end type
interface operator(<>)
pure integer(8) function ne_it(x, y)
import :: t
integer, intent(in) :: x
type(t), intent(in) :: y
end
end interface
interface operator(/=)
pure integer(8) function ne_tt(x, y)
import :: t
type(t), intent(in) :: x, y
end
end interface
interface operator(.ne.)
pure integer(8) function ne_ci(x, y)
character(len=*), intent(in) :: x
integer, intent(in) :: y
end
end interface
contains
subroutine s1(x, y, z)
integer :: x
type(t) :: y
real :: z(x /= y) ! resolves to ne_it
end
subroutine s2(x, y, z)
type(t) :: x
type(t) :: y
real :: z(x .ne. y) ! resolves to ne_tt
end
subroutine s3(x, y, z)
character(len=*) :: x
integer :: y
real :: z(x <> y) ! resolves to ne_ci
end
end
!Expect: m3.mod
!module m3
! type :: t
! sequence
! logical(4) :: x
! end type
! interface
! pure function ne_it(x, y)
! import :: t
! integer(4), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: ne_it
! end
! end interface
! interface
! pure function ne_tt(x, y)
! import :: t
! type(t), intent(in) :: x
! type(t), intent(in) :: y
! integer(8) :: ne_tt
! end
! end interface
! interface
! pure function ne_ci(x, y)
! character(*, 1), intent(in) :: x
! integer(4), intent(in) :: y
! integer(8) :: ne_ci
! end
! end interface
! interface operator(<>)
! procedure :: ne_it
! procedure :: ne_tt
! procedure :: ne_ci
! end interface
!contains
! subroutine s1(x, y, z)
! integer(4) :: x
! type(t) :: y
! real(4) :: z(1_8:ne_it(x, y))
! end
! subroutine s2(x, y, z)
! type(t) :: x
! type(t) :: y
! real(4) :: z(1_8:ne_tt(x, y))
! end
! subroutine s3(x, y, z)
! character(*, 1) :: x
! integer(4) :: y
! real(4) :: z(1_8:ne_ci(x, y))
! end
!end
! Concatenation
module m4
type :: t
sequence
logical :: x
end type
interface operator(//)
pure integer(8) function concat_12(x, y)
character(len=*,kind=1), intent(in) :: x
character(len=*,kind=2), intent(in) :: y
end
pure integer(8) function concat_int_real(x, y)
integer, intent(in) :: x
real, intent(in) :: y
end
end interface
contains
subroutine s1(x, y, z)
character(len=*,kind=1) :: x
character(len=*,kind=2) :: y
real :: z(x // y) ! resolves to concat_12
end
subroutine s2(x, y, z)
integer :: x
real :: y
real :: z(x // y) ! resolves to concat_int_real
end
end
!Expect: m4.mod
!module m4
! type :: t
! sequence
! logical(4) :: x
! end type
! interface
! pure function concat_12(x, y)
! character(*, 1), intent(in) :: x
! character(*, 2), intent(in) :: y
! integer(8) :: concat_12
! end
! end interface
! interface
! pure function concat_int_real(x, y)
! integer(4), intent(in) :: x
! real(4), intent(in) :: y
! integer(8) :: concat_int_real
! end
! end interface
! interface operator(//)
! procedure :: concat_12
! procedure :: concat_int_real
! end interface
!contains
! subroutine s1(x, y, z)
! character(*, 1) :: x
! character(*, 2) :: y
! real(4) :: z(1_8:concat_12(x, y))
! end
! subroutine s2(x, y, z)
! integer(4) :: x
! real(4) :: y
! real(4) :: z(1_8:concat_int_real(x, y))
! end
!end
! Unary operators
module m5
type :: t
end type
interface operator(+)
pure integer(8) function plus_l(x)
logical, intent(in) :: x
end
end interface
interface operator(-)
pure integer(8) function minus_t(x)
import :: t
type(t), intent(in) :: x
end
end interface
interface operator(.not.)
pure integer(8) function not_t(x)
import :: t
type(t), intent(in) :: x
end
pure integer(8) function not_real(x)
real, intent(in) :: x
end
end interface
contains
subroutine s1(x, y)
logical :: x
real :: y(+x) ! resolves_to plus_l
end
subroutine s2(x, y)
type(t) :: x
real :: y(-x) ! resolves_to minus_t
end
subroutine s3(x, y)
type(t) :: x
real :: y(.not. x) ! resolves to not_t
end
subroutine s4(x, y)
real :: y(.not. x) ! resolves to not_real
end
end
!Expect: m5.mod
!module m5
! type :: t
! end type
! interface
! pure function plus_l(x)
! logical(4), intent(in) :: x
! integer(8) :: plus_l
! end
! end interface
! interface
! pure function minus_t(x)
! import :: t
! type(t), intent(in) :: x
! integer(8) :: minus_t
! end
! end interface
! interface
! pure function not_t(x)
! import :: t
! type(t), intent(in) :: x
! integer(8) :: not_t
! end
! end interface
! interface
! pure function not_real(x)
! real(4), intent(in) :: x
! integer(8) :: not_real
! end
! end interface
! interface operator(+)
! procedure :: plus_l
! end interface
! interface operator(-)
! procedure :: minus_t
! end interface
! interface operator( .not.)
! procedure :: not_t
! procedure :: not_real
! end interface
!contains
! subroutine s1(x, y)
! logical(4) :: x
! real(4) :: y(1_8:plus_l(x))
! end
! subroutine s2(x, y)
! type(t) :: x
! real(4) :: y(1_8:minus_t(x))
! end
! subroutine s3(x, y)
! type(t) :: x
! real(4) :: y(1_8:not_t(x))
! end
! subroutine s4(x, y)
! real(4) :: x
! real(4) :: y(1_8:not_real(x))
! end
!end
! Resolved based on shape
module m6
interface operator(+)
pure integer(8) function add(x, y)
real, intent(in) :: x(:, :)
real, intent(in) :: y(:, :, :)
end
end interface
contains
subroutine s1(n, x, y, z, a, b)
integer(8) :: n
real :: x
real :: y(4, n)
real :: z(2, 2, 2)
real :: a(size(x+y)) ! intrinsic +
real :: b(y+z) ! resolves to add
end
end
!Expect: m6.mod
!module m6
! interface
! pure function add(x, y)
! real(4), intent(in) :: x(:, :)
! real(4), intent(in) :: y(:, :, :)
! integer(8) :: add
! end
! end interface
! interface operator(+)
! procedure :: add
! end interface
!contains
! subroutine s1(n, x, y, z, a, b)
! integer(8) :: n
! real(4) :: x
! real(4) :: y(1_8:4_8, 1_8:n)
! real(4) :: z(1_8:2_8, 1_8:2_8, 1_8:2_8)
! real(4) :: a(1_8:int(int(4_8*size(y,dim=2,kind=8),kind=4),kind=8))
! real(4) :: b(1_8:add(y, z))
! end
!end
! Parameterized derived type
module m7
type :: t(k)
integer, kind :: k
real(k) :: a
end type
interface operator(+)
pure integer(8) function f1(x, y)
import :: t
type(t(4)), intent(in) :: x, y
end
pure integer(8) function f2(x, y)
import :: t
type(t(8)), intent(in) :: x, y
end
end interface
contains
subroutine s1(x, y, z)
type(t(4)) :: x, y
real :: z(x + y) ! resolves to f1
end
subroutine s2(x, y, z)
type(t(8)) :: x, y
real :: z(x + y) ! resolves to f2
end
end
!Expect: m7.mod
!module m7
! type :: t(k)
! integer(4), kind :: k
! real(int(int(k,kind=4),kind=8))::a
! end type
! interface
! pure function f1(x, y)
! import :: t
! type(t(k=4_4)), intent(in) :: x
! type(t(k=4_4)), intent(in) :: y
! integer(8) :: f1
! end
! end interface
! interface
! pure function f2(x, y)
! import :: t
! type(t(k=8_4)), intent(in) :: x
! type(t(k=8_4)), intent(in) :: y
! integer(8) :: f2
! end
! end interface
! interface operator(+)
! procedure :: f1
! procedure :: f2
! end interface
!contains
! subroutine s1(x, y, z)
! type(t(k=4_4)) :: x
! type(t(k=4_4)) :: y
! real(4) :: z(1_8:f1(x, y))
! end
! subroutine s2(x, y, z)
! type(t(k=8_4)) :: x
! type(t(k=8_4)) :: y
! real(4) :: z(1_8:f2(x, y))
! end
!end