Description
Hi,
Sorry for the confusing name of the issue, I tried to be a bit precise, so I hope the testcase below is clearer.
module test
implicit none
integer, parameter :: my_kind = 4
end module test
module moo
use test, only : my_kind
implicit none
interface
integer(my_kind) function foo(a)
import :: my_kind !! flang considers this as not accessible
!! probably due to the earlier occurrence of my_kind
implicit none
integer(kind=my_kind) :: a
end function foo
end interface
contains
end module moo
This is rejected by flang:
error: Semantic errors in prefix-import.f90
./prefix-import.f90:10:13: error: Must be a constant value
integer(my_kind) function foo(a)
^^^^^^^
./prefix-import.f90:11:18: error: 'my_kind' from host is not accessible
import :: my_kind !! flang considers this as not accessible
^^^^^^^
./prefix-import.f90:10:13: 'my_kind' is hidden by this entity
integer(my_kind) function foo(a)
^^^^^^^
./prefix-import.f90:14:21: error: Must be a constant value
integer(kind=my_kind) :: a
^^^^^^^
I am aware this is a Fortran 2003 feature.
A similar problem happens with use-association.
module test
implicit none
integer, parameter :: my_kind = 4
end module test
module moo
implicit none
interface
integer(my_kind) function foo(a)
use test, only : my_kind ! use-association
implicit none
integer(kind=my_kind) :: a
end function foo
end interface
contains
end module moo
error: Semantic errors in prefix-use.f90
./prefix-use.f90:9:13: error: Must be a constant value
integer(my_kind) function foo(a)
^^^^^^^
./prefix-use.f90:10:25: error: Cannot use-associate 'my_kind'; it is already declared in this scope
use test, only : my_kind ! use-association
^^^^^^^
./prefix-use.f90:9:13: Previous declaration of 'my_kind'
integer(my_kind) function foo(a)
^^^^^^^
I admit I'm not 100% sure about the validity of this (but all compilers I could test on https://fortran.godbolt.org were OK with this code).
My reading of the spec is such that this should be accepted.
According to my draft of Fortran 2018, the constraints associated to the type-param-value
of a declaration-type-spec
(such like the one appearing in the prefix
of a function-stmt
) (R703) forces them to be specification-expr
.
A variable in a specification expression shall have its type and type parameters, if any, specified by a previous declaration in the same scoping unit, by the implicit typing rules in effect for the scoping unit, or by host or use association.
(I understand here "previous" binds to the "declaration in the same scoping" and not the following cases: implicit, host, use).
As a workaround, the code can be rewritten to use a result(r)
and then declare integer(my_kind) :: r
, like below
module moo
use test, only : my_kind
implicit none
interface
function foo() result(r)
import :: my_kind
implicit none
integer(kind=my_kind) :: r, a
end function foo
end interface
contains
end module moo