| ! RUN: %python %S/test_modfile.py %s %flang_fc1 |
| ! Resolution of generic names in expressions. |
| ! Test by using generic function in a specification expression that needs |
| ! to be written to a .mod file. |
| |
| ! Resolve based on number of arguments |
| module m1 |
| interface f |
| pure integer(8) function f1(x) |
| real, intent(in) :: x |
| end |
| pure integer(8) function f2(x, y) |
| real, intent(in) :: x, y |
| end |
| pure integer(8) function f3(x, y, z, w) |
| real, intent(in) :: x, y, z, w |
| optional :: w |
| end |
| end interface |
| contains |
| subroutine s1(x, z) |
| real :: z(f(x)) ! resolves to f1 |
| end |
| subroutine s2(x, y, z) |
| real :: z(f(x, y)) ! resolves to f2 |
| end |
| subroutine s3(x, y, z, w) |
| real :: w(f(x, y, z)) ! resolves to f3 |
| end |
| subroutine s4(x, y, z, w, u) |
| real :: u(f(x, y, z, w)) ! resolves to f3 |
| end |
| end |
| !Expect: m1.mod |
| !module m1 |
| ! interface f |
| ! procedure :: f1 |
| ! procedure :: f2 |
| ! procedure :: f3 |
| ! end interface |
| ! interface |
| ! pure function f1(x) |
| ! real(4), intent(in) :: x |
| ! integer(8) :: f1 |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f2(x, y) |
| ! real(4), intent(in) :: x |
| ! real(4), intent(in) :: y |
| ! integer(8) :: f2 |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f3(x, y, z, w) |
| ! real(4), intent(in) :: x |
| ! real(4), intent(in) :: y |
| ! real(4), intent(in) :: z |
| ! real(4), intent(in), optional :: w |
| ! integer(8) :: f3 |
| ! end |
| ! end interface |
| !contains |
| ! subroutine s1(x, z) |
| ! real(4) :: x |
| ! real(4) :: z(1_8:f1(x)) |
| ! end |
| ! subroutine s2(x, y, z) |
| ! real(4) :: x |
| ! real(4) :: y |
| ! real(4) :: z(1_8:f2(x, y)) |
| ! end |
| ! subroutine s3(x, y, z, w) |
| ! real(4) :: x |
| ! real(4) :: y |
| ! real(4) :: z |
| ! real(4) :: w(1_8:f3(x, y, z)) |
| ! end |
| ! subroutine s4(x, y, z, w, u) |
| ! real(4) :: x |
| ! real(4) :: y |
| ! real(4) :: z |
| ! real(4) :: w |
| ! real(4) :: u(1_8:f3(x, y, z, w)) |
| ! end |
| !end |
| |
| ! Resolve based on type or kind |
| module m2 |
| interface f |
| pure integer(8) function f_real4(x) |
| real(4), intent(in) :: x |
| end |
| pure integer(8) function f_real8(x) |
| real(8), intent(in) :: x |
| end |
| pure integer(8) function f_integer(x) |
| integer, intent(in) :: x |
| end |
| end interface |
| contains |
| subroutine s1(x, y) |
| real(4) :: x |
| real :: y(f(x)) ! resolves to f_real4 |
| end |
| subroutine s2(x, y) |
| real(8) :: x |
| real :: y(f(x)) ! resolves to f_real8 |
| end |
| subroutine s3(x, y) |
| integer :: x |
| real :: y(f(x)) ! resolves to f_integer |
| end |
| end |
| !Expect: m2.mod |
| !module m2 |
| ! interface f |
| ! procedure :: f_real4 |
| ! procedure :: f_real8 |
| ! procedure :: f_integer |
| ! end interface |
| ! interface |
| ! pure function f_real4(x) |
| ! real(4), intent(in) :: x |
| ! integer(8) :: f_real4 |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f_real8(x) |
| ! real(8), intent(in) :: x |
| ! integer(8) :: f_real8 |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f_integer(x) |
| ! integer(4), intent(in) :: x |
| ! integer(8) :: f_integer |
| ! end |
| ! end interface |
| !contains |
| ! subroutine s1(x, y) |
| ! real(4) :: x |
| ! real(4) :: y(1_8:f_real4(x)) |
| ! end |
| ! subroutine s2(x, y) |
| ! real(8) :: x |
| ! real(4) :: y(1_8:f_real8(x)) |
| ! end |
| ! subroutine s3(x, y) |
| ! integer(4) :: x |
| ! real(4) :: y(1_8:f_integer(x)) |
| ! end |
| !end |
| |
| ! Resolve based on rank |
| module m3a |
| interface f |
| procedure :: f_elem |
| procedure :: f_vector |
| end interface |
| contains |
| pure integer(8) elemental function f_elem(x) result(result) |
| real, intent(in) :: x |
| result = 1_8 |
| end |
| pure integer(8) function f_vector(x) result(result) |
| real, intent(in) :: x(:) |
| result = 2_8 |
| end |
| end |
| !Expect: m3a.mod |
| !module m3a |
| ! interface f |
| ! procedure :: f_elem |
| ! procedure :: f_vector |
| ! end interface |
| !contains |
| ! elemental pure function f_elem(x) result(result) |
| ! real(4), intent(in) :: x |
| ! integer(8) :: result |
| ! end |
| ! pure function f_vector(x) result(result) |
| ! real(4), intent(in) :: x(:) |
| ! integer(8) :: result |
| ! end |
| !end |
| |
| module m3b |
| use m3a |
| contains |
| subroutine s1(x, y) |
| real :: x |
| real :: y(f(x)) ! resolves to f_elem |
| end |
| subroutine s2(x, y) |
| real :: x(10) |
| real :: y(f(x)) ! resolves to f_vector (preferred over elemental one) |
| end |
| subroutine s3(x, y) |
| real :: x(10, 10) |
| real :: y(ubound(f(x), 1)) ! resolves to f_elem |
| end |
| end |
| !Expect: m3b.mod |
| !module m3b |
| ! use m3a, only: f |
| ! use m3a, only: f_elem |
| ! use m3a, only: f_vector |
| !contains |
| ! subroutine s1(x, y) |
| ! real(4) :: x |
| ! real(4) :: y(1_8:f_elem(x)) |
| ! end |
| ! subroutine s2(x, y) |
| ! real(4) :: x(1_8:10_8) |
| ! real(4) :: y(1_8:f_vector(x)) |
| ! end |
| ! subroutine s3(x, y) |
| ! real(4) :: x(1_8:10_8, 1_8:10_8) |
| ! real(4) :: y(1_8:10_8) |
| ! end |
| !end |
| |
| ! Resolve defined unary operator based on type |
| module m4 |
| interface operator(.foo.) |
| pure integer(8) function f_real(x) |
| real, intent(in) :: x |
| end |
| pure integer(8) function f_integer(x) |
| integer, intent(in) :: x |
| end |
| end interface |
| contains |
| subroutine s1(x, y) |
| real :: x |
| real :: y(.foo. x) ! resolves to f_real |
| end |
| subroutine s2(x, y) |
| integer :: x |
| real :: y(.foo. x) ! resolves to f_integer |
| end |
| end |
| !Expect: m4.mod |
| !module m4 |
| ! interface operator(.foo.) |
| ! procedure :: f_real |
| ! procedure :: f_integer |
| ! end interface |
| ! interface |
| ! pure function f_real(x) |
| ! real(4), intent(in) :: x |
| ! integer(8) :: f_real |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f_integer(x) |
| ! integer(4), intent(in) :: x |
| ! integer(8) :: f_integer |
| ! end |
| ! end interface |
| !contains |
| ! subroutine s1(x, y) |
| ! real(4) :: x |
| ! real(4) :: y(1_8:f_real(x)) |
| ! end |
| ! subroutine s2(x, y) |
| ! integer(4) :: x |
| ! real(4) :: y(1_8:f_integer(x)) |
| ! end |
| !end |
| |
| ! Resolve defined binary operator based on type |
| module m5 |
| interface operator(.foo.) |
| pure integer(8) function f1(x, y) |
| real, intent(in) :: x |
| real, intent(in) :: y |
| end |
| pure integer(8) function f2(x, y) |
| real, intent(in) :: x |
| complex, intent(in) :: y |
| end |
| end interface |
| contains |
| subroutine s1(x, y) |
| complex :: x |
| real :: y(1.0 .foo. x) ! resolves to f2 |
| end |
| subroutine s2(x, y) |
| real :: x |
| real :: y(1.0 .foo. x) ! resolves to f1 |
| end |
| end |
| !Expect: m5.mod |
| !module m5 |
| ! interface operator(.foo.) |
| ! procedure :: f1 |
| ! procedure :: f2 |
| ! end interface |
| ! interface |
| ! pure function f1(x, y) |
| ! real(4), intent(in) :: x |
| ! real(4), intent(in) :: y |
| ! integer(8) :: f1 |
| ! end |
| ! end interface |
| ! interface |
| ! pure function f2(x, y) |
| ! real(4), intent(in) :: x |
| ! complex(4), intent(in) :: y |
| ! integer(8) :: f2 |
| ! end |
| ! end interface |
| !contains |
| ! subroutine s1(x, y) |
| ! complex(4) :: x |
| ! real(4) :: y(1_8:f2(1._4, x)) |
| ! end |
| ! subroutine s2(x, y) |
| ! real(4) :: x |
| ! real(4) :: y(1_8:f1(1._4, x)) |
| ! end |
| !end |