2020-05-12 02:38:53 +08:00
|
|
|
! RUN: %S/test_errors.sh %s %t %f18
|
2018-07-21 01:46:11 +08:00
|
|
|
module m
|
|
|
|
interface foo
|
|
|
|
subroutine 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
|
2019-03-19 02:48:02 +08:00
|
|
|
subroutine s4(x,y)
|
|
|
|
real x,y
|
2018-07-21 01:46:11 +08:00
|
|
|
end subroutine
|
2019-03-19 02:48:02 +08:00
|
|
|
subroutine s2(x,y)
|
|
|
|
complex x,y
|
2018-07-21 01:46:11 +08:00
|
|
|
end subroutine
|
|
|
|
end interface
|
|
|
|
generic :: bar => s4
|
|
|
|
generic :: bar => s2
|
|
|
|
!ERROR: Procedure 's4' is already specified in generic 'bar'
|
|
|
|
generic :: bar => s4
|
2019-03-19 02:48:02 +08:00
|
|
|
|
|
|
|
generic :: operator(.foo.)=> s4
|
|
|
|
generic :: operator(.foo.)=> s2
|
|
|
|
!ERROR: Procedure 's4' is already specified in generic operator '.foo.'
|
|
|
|
generic :: operator(.foo.)=> s4
|
2018-07-21 01:46:11 +08:00
|
|
|
end module
|
2019-03-19 02:48:02 +08:00
|
|
|
|
|
|
|
module m2
|
|
|
|
interface
|
|
|
|
integer function f(x, y)
|
2019-12-03 00:55:44 +08:00
|
|
|
logical, intent(in) :: x, y
|
2019-03-19 02:48:02 +08:00
|
|
|
end function
|
|
|
|
end interface
|
|
|
|
generic :: operator(+)=> f
|
|
|
|
!ERROR: Procedure 'f' is already specified in generic 'operator(+)'
|
|
|
|
generic :: operator(+)=> f
|
|
|
|
end
|
[flang] Handle alternative names for relational operators
10.1.6.2 says:
> The operators <, <=, >, >=, ==, and /= always have the same interpretations
> as the operators .LT., .LE., .GT., .GE., .EQ., and .NE., respectively.
That means we have to treat `operator(<)` like `operator(.lt.)`,
for example. `<>` is a third alias for `.NE.`.
We can't just choose always to use one form (e.g. replacing `operator(.lt.)`
with `operator(<)`). This is because all symbols names are `CharBlock`s
referring to the cooked character stream so that they have proper source
provenance. Also, if a user prefers one style and uses it consistently,
that's the form they should see in messages.
So the fix is to use whatever form is found in the source, but also to
look up symbols by the other names when necessary. To assist this, add
`GenericSpecInfo::GetAllNames()` to return all of the names of a generic
spec. Each place a generic spec can occur we have to use these to look
for the symbol.
Also reorganize the `AddUse()` overloads to work with this change.
Fixes flang-compiler/f18#746.
Original-commit: flang-compiler/f18@7f06f175d5033f0728f67b1be25ecd53df1f8de5
Reviewed-on: https://github.com/flang-compiler/f18/pull/752
2019-09-18 07:57:09 +08:00
|
|
|
|
|
|
|
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
|