Restricting access of contained procedure to variables in host

A CONTAINed procedure has access to all the variables in the host. Could the language be modified to allow access to only specified variables, as is the case when USEing a module? I’d like syntax like this to work:

subroutine foo(x1,x2)
real, intent(in) :: x1,x2
subroutine bar()
use foo, only: x1 ! contained subroutine has access to x1 but not x2 
end subroutine bar
end subroutine foo
1 Like

Fortran 2018 enhances IMPORT facility which helps precisely with situations mentioned here. The document proxy (18-007r1, section 8.8) for the standard provides details: Here’s an excerpt:

1 8.8 IMPORT statement
2 R867 import-stmt is IMPORT [[ :: ] import-name-list ]
3 or IMPORT, ONLY : import-name-list
6 C896 (R867) An IMPORT statement shall not appear in the scoping unit of a main-program, external
7 subprogram, module, or block-data.

Here’s a check with Intel oneAPI IFORT classic compiler (available to everyone for download) that works as expected:

module m
   implicit none
   subroutine sub1( x1, x2 )
      real, intent(in) :: x1, x2
      call sub2()
      subroutine sub2()
         import, only : x1 !<-- only x1 is imported from containing scope
         print *, "x1 = ", x1, "; expected is 123.0"
         print *, "x2 = ", x2  !<-- error because x2 not imported nor declared 
      end subroutine 
   end subroutine 
end module
   use m, only : sub1
   real :: a, b
   a = 123.0 ; b = -1.0
   call sub1( a, b )

C:\Temp>ifort /c /standard-semantics /warn:all /stand:f18 p.f90
Intel® Fortran Intel® 64 Compiler Classic for applications running on Intel® 64, Version 2021.1 Build 20201112_000000
Copyright © 1985-2020 Intel Corporation. All rights reserved.

p.f90(11): error #6404: This name does not have a type, and must have an explicit type. [X2]
print *, "x2 = ", x2 !<-- error because x2 not imported nor declared


Thanks. Does the latest gfortran have this feature? Compiling your code above with GNU Fortran (GCC) 11.0.0 20200927 from, excluding the “error line”, I get


    9 |          import, only : x1 !<-- only x1 is imported from containing scope
      |                1
Error: IMPORT statement at (1) only permitted in an INTERFACE body

   15 |    use m, only : sub1
      |        1
Fatal Error: Cannot open module file 'm.mod' for reading at (1): No such file or directory
compilation terminated.

I may end up learning Fortran beyond F95 by asking for feature X and being told that it’s already in Fortran 2018. But now I do see section “5.20 Control of host association” in The new features of Fortran 2018 and will reread that document.

If you declare a local variable in a contained procedure that has the same name as one in the host, access to the host variable is blocked.