gfc_state_data s;
gfc_symbol *sym;
gfc_component *c, *lock_comp = NULL, *event_comp = NULL;
+ bool pdt_parameters;
accept_statement (ST_DERIVED_DECL);
push_state (&s, COMP_DERIVED, gfc_new_block);
seen_private = 0;
seen_sequence = 0;
seen_component = 0;
+ pdt_parameters = false;
compiling_type = 1;
+
while (compiling_type)
{
st = next_statement ();
case ST_PROCEDURE:
accept_statement (st);
seen_component = 1;
+ /* Type parameters must not have an explicit access specification
+ and must be placed before a PRIVATE statement. If a PRIVATE
+ statement is encountered after type parameters, mark the remaining
+ components as PRIVATE. */
+ for (c = gfc_current_block ()->components; c; c = c->next)
+ if (!c->next && (c->attr.pdt_kind || c->attr.pdt_len))
+ {
+ pdt_parameters = true;
+ if (c->attr.access != ACCESS_UNKNOWN)
+ {
+ gfc_error ("Access specification of a type parameter at "
+ "%C is not allowed");
+ c->attr.access = ACCESS_PUBLIC;
+ break;
+ }
+ if (seen_private)
+ {
+ gfc_error ("The type parameter at %C must come before a "
+ "PRIVATE statement");
+ break;
+ }
+ }
+ else if (pdt_parameters && seen_private
+ && !(c->attr.pdt_kind || c->attr.pdt_len))
+ c->attr.access = ACCESS_PRIVATE;
break;
case ST_FINAL:
break;
}
- if (seen_component)
+ if (seen_component && !pdt_parameters)
{
gfc_error ("PRIVATE statement at %C must precede "
"structure components");
if (seen_private)
gfc_error ("Duplicate PRIVATE statement at %C");
- s.sym->component_access = ACCESS_PRIVATE;
+ if (pdt_parameters)
+ s.sym->component_access = ACCESS_PUBLIC;
+ else
+ s.sym->component_access = ACCESS_PRIVATE;
accept_statement (ST_PRIVATE);
seen_private = 1;
--- /dev/null
+! { dg-do run }
+!
+! Test the fix for pr95541.
+!
+! Contributed by Juergen Reuter <juergen.reuter@desy.de>
+!
+module mykinds
+ use, intrinsic :: iso_fortran_env, only : i4 => int32, r4 => real32, r8 => real64
+ implicit none
+ private
+ public :: i4, r4, r8
+end module mykinds
+
+module matrix
+ use mykinds, only : r4, r8
+ implicit none
+ private
+
+ type, public :: mat_t(k,c,r)
+ !.. type parameters
+ integer, kind :: k = r4
+ integer, len :: c = 1
+ integer, len :: r = 1
+ private
+ !.. private by default
+ !.. type data
+ real(kind=k) :: m_a(c,r)
+ end type mat_t
+
+ interface assignment(=)
+ module procedure geta_r4
+ module procedure seta_r4
+ module procedure geta_r8
+ module procedure seta_r8
+ !.. additional bindings elided
+ end interface assignment(=)
+
+ public :: assignment(=)
+
+contains
+
+ subroutine geta_r4(a_lhs, t_rhs)
+ real(r4), allocatable, intent(out) :: a_lhs(:,:)
+ class(mat_t(k=r4,c=*,r=*)), intent(in) :: t_rhs
+ a_lhs = t_rhs%m_a
+ return
+ end subroutine geta_r4
+
+ subroutine geta_r8(a_lhs, t_rhs)
+ real(r8), allocatable, intent(out) :: a_lhs(:,:)
+ class(mat_t(k=r8,c=*,r=*)), intent(in) :: t_rhs
+ a_lhs = t_rhs%m_a
+ return
+ end subroutine geta_r8
+
+ subroutine seta_r4(t_lhs, a_rhs)
+ class(mat_t(k=r4,c=*,r=*)), intent(inout) :: t_lhs
+ real(r4), intent(in) :: a_rhs(:,:)
+ !.. checks on size elided
+ t_lhs%m_a = a_rhs
+ return
+ end subroutine seta_r4
+
+ subroutine seta_r8(t_lhs, a_rhs)
+ class(mat_t(k=r8,c=*,r=*)), intent(inout) :: t_lhs
+ real(r8), intent(in) :: a_rhs(:,:)
+ !.. checks on size elided
+ t_lhs%m_a = a_rhs
+ return
+ end subroutine seta_r8
+
+end module matrix
+
+program p
+ use mykinds, only : r4, r8
+ use matrix, only : mat_t, assignment(=)
+ implicit none
+ type(mat_t(k=r4,c=:,r=:)), allocatable :: mat_r4
+ type(mat_t(k=r8,c=:,r=:)), allocatable :: mat_r8
+ real(r4), allocatable :: a_r4(:,:)
+ real(r8), allocatable :: a_r8(:,:)
+ integer :: N
+ integer :: M
+ integer :: i
+ integer :: istat
+ N = 2
+ M = 3
+ allocate( mat_t(k=r4,c=N,r=M) :: mat_r4, stat=istat )
+ if ( istat /= 0 ) then
+ print *, " error allocating mat_r4: stat = ", istat
+ stop
+ end if
+ if (mat_r4%k /= r4) stop 1
+ if (mat_r4%c /= N) stop 2
+ if (mat_r4%r /= M) stop 3
+ mat_r4 = reshape( [ (real(i, kind=mat_r4%k), i=1,N*M) ], [ N, M ] )
+ a_r4 = mat_r4
+ if (int (sum (a_r4)) /= 21) stop 4
+ N = 4
+ M = 4
+ allocate( mat_t(k=r8,c=N,r=M) :: mat_r8, stat=istat )
+ if ( istat /= 0 ) then
+ print *, " error allocating mat_r4: stat = ", istat
+ stop
+ end if
+ if (mat_r8%k /= r8) stop 5
+ if (mat_r8%c /= N) stop 6
+ if (mat_r8%r /= M) stop 7
+ mat_r8 = reshape( [ (real(i, kind=mat_r8%k), i=1,N*M) ], [ N, M ] )
+ a_r8 = mat_r8
+ if (int (sum (a_r8)) /= 136) stop 8
+ deallocate( mat_r4, stat=istat )
+ if ( istat /= 0 ) then
+ print *, " error deallocating mat_r4: stat = ", istat
+ stop
+ end if
+ deallocate( mat_r8, stat=istat )
+ if ( istat /= 0 ) then
+ print *, " error deallocating mat_r4: stat = ", istat
+ stop
+ end if
+ stop
+end program p