On Wed, Mar 11, 2026 at 12:39:15PM +0000, Paul Richard Thomas wrote:
> Hello All,
> 
> The valgrind error in the summary line seems to have gone but deferred
> parameter errors were all missed. This patch fixes them all.
> 
> Since this is verging on obvious, I will leave explanation to the
> change logs and the diff.
> 
> Regtests on FC43/x86_64. OK for mainline?
> 

Ok, but with tiny questions below?  


> diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
> index b2996759c68..79e579f2a8d 100644
> --- a/gcc/fortran/match.cc
> +++ b/gcc/fortran/match.cc
> @@ -4973,6 +4973,22 @@ cleanup:
>  }
>  
>  
> +/* A reduced version of gfc_spec_list_type, which only looks for deferred
> +   type spec list parameters.  */
> +
> +static gfc_param_spec_type
> +spec_list_type (gfc_actual_arglist *param_list)
> +{
> +  gfc_param_spec_type res = SPEC_EXPLICIT;
> +
> +  for (; param_list; param_list = param_list->next)
> +    if (param_list->spec_type == SPEC_DEFERRED)
> +     res = param_list->spec_type;

Can there be more than one spec_type that is deferred?
Do you want/need something like?

It seems that you may be able to break out of the for-loop.

  if (param_list->spec_type == SPEC_DEFERRED)
    {
       res = param_list->spec_type;
       break;
    }


> +
> +  return res;
> +}
> +
> +
>  /* Frees a list of gfc_alloc structures.  */
>  
>  void
> @@ -4998,6 +5014,7 @@ gfc_match_allocate (void)
>    gfc_expr *stat, *errmsg, *tmp, *source, *mold;
>    gfc_typespec ts;
>    gfc_symbol *sym;
> +  gfc_ref *ref;
>    match m;
>    locus old_locus, deferred_locus, assumed_locus;
>    bool saw_stat, saw_errmsg, saw_source, saw_mold, saw_deferred, b1, b2, b3;
> @@ -5057,8 +5074,7 @@ gfc_match_allocate (void)
>           }
>  
>         if (type_param_spec_list
> -           && gfc_spec_list_type (type_param_spec_list, NULL)
> -              == SPEC_DEFERRED)
> +           && spec_list_type (type_param_spec_list) == SPEC_DEFERRED)
>           {
>             gfc_error ("The type parameter spec list in the type-spec at "
>                        "%L cannot contain DEFERRED parameters", &old_locus);
> @@ -5120,11 +5136,28 @@ gfc_match_allocate (void)
>         goto cleanup;
>       }
>  
> -      if (tail->expr->ts.deferred)
> +      if (tail->expr->ts.deferred
> +       || (tail->expr->symtree->n.sym->param_list
> +           && spec_list_type (tail->expr->symtree->n.sym->param_list)
> +                              == SPEC_DEFERRED))
>       {
>         saw_deferred = true;
>         deferred_locus = tail->expr->where;
>       }
> +      else if ((tail->expr->ts.type == BT_DERIVED
> +             || tail->expr->ts.type == BT_CLASS)
> +            && tail->expr->ref)
> +     {
> +       for (ref = tail->expr->ref; ref; ref = ref->next)
> +         if (ref->type == REF_COMPONENT
> +             && ref->u.c.component->param_list
> +             && spec_list_type (ref->u.c.component->param_list)
> +                                == SPEC_DEFERRED)
> +         {
> +           saw_deferred = true;
> +           deferred_locus = tail->expr->where;
> +         }
> +     }
>  
>        if (gfc_find_state (COMP_DO_CONCURRENT)
>         || gfc_find_state (COMP_CRITICAL))
> diff --git a/gcc/testsuite/gfortran.dg/pdt_87.f03 
> b/gcc/testsuite/gfortran.dg/pdt_87.f03
> new file mode 100644
> index 00000000000..68681a5cb6d
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pdt_87.f03
> @@ -0,0 +1,89 @@
> +! { dg-do compile }
> +!
> +! Test the fix for pr115316, in which none of the deferred type PDT errors 
> were caught.
> +! Note the exclusion of the old-style character length at line 62. This 
> compiles OK
> +! but causes an excess errors message in the testsuite.
> +!
> +! Contributed by David Binderman  <[email protected]>
> +!
> +subroutine C933_a(b1, ca3, ca4, cp3, cp3mold, cp4, cp7, cp8, bsrc)
> +! If any allocate-object has a deferred type parameter, is unlimited 
> polymorphic,
> +! or is of abstract type, either type-spec or source-expr shall appear.
> +  type SomeType(k, l1, l2)
> +    integer, kind :: k = 1
> +    integer, len :: l1
> +    integer, len :: l2 = 3
> +    character(len=l2+l1) str
> +  end type
> +
> +  type B(l)
> +    integer, len :: l
> +    character(:), allocatable :: msg
> +    type(SomeType(4, l, :)), pointer :: something
> +  end type
> +  character(len=:), allocatable :: ca1, ca2(:)
> +  character(len=*), allocatable :: ca3, ca4(:)
> +  character(len=2), allocatable :: ca5, ca6(:)
> +  character(len=5) mold
> +
> +  type(SomeType(l1=:,l2=:)), pointer :: cp1, cp2(:)
> +  type(SomeType(l1=3,l2=4)) cp1mold
> +  type(SomeType(1,*,:)), pointer :: cp3, cp4(:)
> +  type(SomeType(1,*,5)) cp3mold
> +  type(SomeType(l1=:)), pointer :: cp5, cp6(:)
> +  type(SomeType(l1=6)) cp5mold
> +  type(SomeType(1,*,*)), pointer :: cp7, cp8(:)
> +  type(SomeType(1, l1=3)), pointer :: cp9, cp10(:)
> +
> +  type(B(*)) b1
> +  type(B(:)), allocatable :: b2
> +  type(B(5)) b3
> +
> +  type(SomeType(4, *, 8)) bsrc
> +
> +  allocate(ca1)          ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(ca2(4))       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp1)          ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp2(2))       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp3)          ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp4(2))       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp5)          ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(cp6(2))       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b1%msg)       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b1%something) ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b2%msg)       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b2%something) ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b3%msg)       ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" }
> +  allocate(b3%something) ! { dg-error "requires either a type-spec or SOURCE 
> tag or a MOLD tag" } 
> +
> +  ! Nominal cases, expecting no errors
> +  allocate(character(len=5):: ca2(4))
> +  allocate(character(len=5):: ca1)
> +!  allocate(character*5:: ca1)
> +  allocate(ca2(4), MOLD = "abcde")
> +  allocate(ca2(2), MOLD = (/"abcde", "fghij"/))
> +  allocate(ca1, MOLD = mold)
> +  allocate(ca2(4), SOURCE = "abcde")
> +  allocate(ca2(2), SOURCE = (/"abcde", "fghij"/))
> +  allocate(ca1, SOURCE = mold)
> +  allocate(SomeType(l1=1, l2=2):: cp1, cp2(2))
> +  allocate(SomeType(1,*,5):: cp3, cp4(2))
> +  allocate(SomeType(l1=1):: cp5, cp6(2))
> +  allocate(cp1, cp2(2), mold = cp1mold)
> +  allocate(cp3, cp4(2), mold = cp3mold)
> +  allocate(cp5, cp6(2), mold = cp5mold)
> +  allocate(cp1, cp2(2), source = cp1mold)
> +  allocate(cp3, cp4(2), source = cp3mold)
> +  allocate(cp5, cp6(2), source = cp5mold)
> +  allocate(character(len=10):: b1%msg, b2%msg, b3%msg)
> +  allocate(SomeType(4, b1%l, 9):: b1%something)
> +  allocate(b2%something, source=bsrc)
> +  allocate(SomeType(4, 5, 8):: b3%something)
> +
> +  ! assumed/explicit length do not need type-spec/mold
> +  allocate(ca3, ca4(4))
> +  allocate(ca5, ca6(4))
> +  allocate(cp7, cp8(2))
> +  allocate(cp9, cp10(2))
> +
> +end subroutine



-- 
Steve

Reply via email to