llvm-project/flang/test/Semantics/modfile32.f90

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

325 lines
6.5 KiB
Fortran
Raw Normal View History

! RUN: %S/test_modfile.sh %s %t %f18
! 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
[flang] Resolve defined operators to specifics Most of these changes involve moving code around so that it case be used for `DefinedUnary` and `DefinedBinary`. The functional changes are in the `Analyze` member functions for those cases where the arguments are now analyzed, the generic is resolved, and a `FunctionRef` is created. Add `ArgumentAnalyzer` to handling building of the `ActualArguments` of a call. This allows the code to be shared with the defined unary and defined binary cases. Move `AnalyzeActualArgument` and `AnalyzeActualArgument` into that class (renaming both to `Analyze`). Create an overload of `GetCalleeAndArguments` for the `Name` case so it can be used for defined ops where we don't have a `ProcedureDesignator`. Move `IsGenericDefinedOp` to `tools.h` to make it available to the new code. We were using `semantics::CheckExplicitInterface` to resolve a generic interface to a specific procedure based on actual arguments. The problem with that is that it performs too many checks. We just want to get the right specific; there may be errors reported later during call analysis. To fix this, add a new function, `CheckInterfaceForGeneric`, to perform this check. It shares code with `CheckExplicitInterface`, but it passes in a null scope to indicate that the full set of checks aren't necessary in `CheckExplicitInterfaceArg`. Instead we lift the call to `TypeAndShape::IsCompatibleWith` out of `CheckExplicitDataArg`, and skip the latter when there is no scope. Original-commit: flang-compiler/f18@fff2d1580f26719e0c384c66576aa6620d04faff Reviewed-on: https://github.com/flang-compiler/f18/pull/786
2019-10-23 00:31:33 +08:00
! 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