fortran: Fix specification expression check in submodules [PR114475]

The patch fixing PR111781 made the check of specification expressions more
restrictive, disallowing local variables in specification expressions of
dummy arguments.  PR114475 showed an example where that change regressed,
disallowing in submodules expressions that had been allowed in the parent
module.  In submodules indeed, the hierarchy of namespaces inherited from
the parent module is not reproduced so the host-association of symbols
can't be recognized by checking the nesting of namespaces.

This change fixes the problem by allowing in specification expressions
all the symbols in a submodule that are inherited from the parent module.

	PR fortran/111781
	PR fortran/114475

gcc/fortran/ChangeLog:

	* expr.cc (check_restricted): In submodules, allow variables host-
	associated from the parent module.

gcc/testsuite/ChangeLog:

	* gfortran.dg/spec_expr_10.f90: New test.

Co-authored-by: Harald Anlauf <anlauf@gmx.de>
This commit is contained in:
Mikael Morin 2024-03-27 16:30:42 +01:00
parent 7907ff2bcb
commit 7f233feafd
2 changed files with 47 additions and 0 deletions

View file

@ -3517,6 +3517,7 @@ check_restricted (gfc_expr *e)
if (e->error
|| sym->attr.in_common
|| sym->attr.use_assoc
|| sym->attr.used_in_submodule
|| sym->attr.dummy
|| sym->attr.implied_index
|| sym->attr.flavor == FL_PARAMETER

View file

@ -0,0 +1,46 @@
! { dg-do compile }
!
! PR fortran/114475
! The array specification of PP in OL_EVAL used to be rejected in the submodule
! because the compiler was not able to see the host-association of N_EXTERNAL
! there.
!
! Contributed by Jürgen Reuter <juergen.reuter@desy.de>.
module t1
use, intrinsic :: iso_c_binding
implicit none
private
public :: t1_t
integer :: N_EXTERNAL = 0
type :: t1_t
contains
procedure :: set_n_external => t1_set_n_external
end type t1_t
abstract interface
subroutine ol_eval (id, pp, emitter) bind(C)
import
real(kind = c_double), intent(in) :: pp(5 * N_EXTERNAL)
end subroutine ol_eval
end interface
interface
module subroutine t1_set_n_external (object, n)
class(t1_t), intent(inout) :: object
integer, intent(in) :: n
end subroutine t1_set_n_external
end interface
end module t1
submodule (t1) t1_s
implicit none
contains
module subroutine t1_set_n_external (object, n)
class(t1_t), intent(inout) :: object
integer, intent(in) :: n
N_EXTERNAL = n
end subroutine t1_set_n_external
end submodule t1_s