Change how generic operators and assignments are checked for distinguishable procedures. Because of how they are invoked, available type-bound generics and normal generics all have to be considered together. This is different from how generic names are checked. Move common part of checking into DistinguishabilityHelper so that it can be used in both cases after the appropriate procedures have been added. Cache result of Procedure::Characterize(Symbol) in a map in CheckHelper so that we don't have to worry about passing the characterized Procedures around or the cost of recomputing them. Add MakeOpName() to construct names for defined operators and assignment for using in error messages. This eliminates the need for different messages in those cases. When the procedures for a defined operator or assignment are undistinguishable, include the type name in the error message, otherwise it may be ambiguous. Add missing check that procedures for defined operators are functions and that their dummy arguments are INTENT(IN) or VALUE. Differential Revision: https://reviews.llvm.org/D87341
61 lines
1.5 KiB
Fortran
61 lines
1.5 KiB
Fortran
! RUN: %S/test_errors.sh %s %t %f18
|
|
module m
|
|
interface foo
|
|
real function s1(x)
|
|
real x
|
|
end
|
|
!ERROR: 's2' is not a module procedure
|
|
module procedure s2
|
|
!ERROR: Procedure 's3' not found
|
|
procedure s3
|
|
!ERROR: Procedure 's1' is already specified in generic 'foo'
|
|
procedure s1
|
|
end interface
|
|
interface
|
|
real function s4(x,y)
|
|
real, intent(in) :: x,y
|
|
end function
|
|
complex function s2(x,y)
|
|
complex, intent(in) :: x,y
|
|
end function
|
|
end interface
|
|
generic :: bar => s4
|
|
generic :: bar => s2
|
|
!ERROR: Procedure 's4' is already specified in generic 'bar'
|
|
generic :: bar => s4
|
|
|
|
generic :: operator(.foo.)=> s4
|
|
generic :: operator(.foo.)=> s2
|
|
!ERROR: Procedure 's4' is already specified in generic 'OPERATOR(.foo.)'
|
|
generic :: operator(.foo.)=> s4
|
|
end module
|
|
|
|
module m2
|
|
interface
|
|
integer function f(x, y)
|
|
logical, intent(in) :: x, y
|
|
end function
|
|
end interface
|
|
generic :: operator(+)=> f
|
|
!ERROR: Procedure 'f' is already specified in generic 'OPERATOR(+)'
|
|
generic :: operator(+)=> f
|
|
end
|
|
|
|
module m3
|
|
interface operator(.ge.)
|
|
procedure f
|
|
end interface
|
|
interface operator(>=)
|
|
!ERROR: Procedure 'f' is already specified in generic 'OPERATOR(.GE.)'
|
|
procedure f
|
|
end interface
|
|
generic :: operator(>) => f
|
|
!ERROR: Procedure 'f' is already specified in generic 'OPERATOR(>)'
|
|
generic :: operator(.gt.) => f
|
|
contains
|
|
logical function f(x, y) result(result)
|
|
logical, intent(in) :: x, y
|
|
result = .true.
|
|
end
|
|
end
|