https://gcc.gnu.org/g:1d081d6ea6af32c3a30672cb0fd7d585737a53a1

commit r17-5406-g1d081d6ea6af32c3a30672cb0fd7d585737a53a1
Author: Paul Thomas <[email protected]>
Date:   Tue Oct 20 11:16:02 2026 +0100

    Fortran: [PDT] (10/16) Parameterized derived type errors [PR82173]
    
    2026-10-20  Paul Thomas  <[email protected]>
    
    gcc/fortran
            PR fortran/82173
            * match.cc (match_derived_type_spec): Null type_param_spec_list.
            (gfc_match_allocate): Detect deferrable components; ie ordinary
            allocatable arrays with deferred SHAPE and no type parameters,
            so that 'saw_deferrable' and 'deferred_locus' can be set
            appropriately.
    
    gcc/testsuite/
            PR fortran/82173
            * gfortran.dg/pdt_bug14.f90: New test.

Diff:
---
 gcc/fortran/match.cc                    | 16 ++++++++++++----
 gcc/testsuite/gfortran.dg/pdt_bug14.f90 | 17 +++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 264ac84eadd8..14e38b452f79 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -2432,6 +2432,7 @@ match_derived_type_spec (gfc_typespec *ts)
   bool is_pdt_template = false;
 
   old_locus = gfc_current_locus;
+  type_param_spec_list = NULL;
 
   if (gfc_match ("%n", name) != MATCH_YES)
     {
@@ -5346,17 +5347,24 @@ gfc_match_allocate (void)
          goto cleanup;
        }
 
-      if (tail->expr->ts.deferred
-         || (tail->expr->symtree->n.sym->param_list
-             && spec_list_type (tail->expr->symtree->n.sym->param_list)
+      bool deferrable = !(tail->expr->ts.type != BT_UNKNOWN
+                          && tail->expr->ts.type != BT_CHARACTER
+                          && !IS_PDT (tail->expr) && !IS_CLASS_PDT (tail->expr)
+                          && (gfc_expr_attr (tail->expr).allocatable
+                              || gfc_expr_attr (tail->expr).pointer));
+
+      if ((tail->expr->ts.deferred
+          || (tail->expr->symtree->n.sym->param_list
+              && spec_list_type (tail->expr->symtree->n.sym->param_list)
                                 == SPEC_DEFERRED))
+         && deferrable)
        {
          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)
+              && tail->expr->ref && deferrable)
        {
          for (ref = tail->expr->ref; ref; ref = ref->next)
            if (ref->type == REF_COMPONENT
diff --git a/gcc/testsuite/gfortran.dg/pdt_bug14.f90 
b/gcc/testsuite/gfortran.dg/pdt_bug14.f90
new file mode 100644
index 000000000000..a22f5a96ed1d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_bug14.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+! Rejected valid code: `a` has a deferred type parameter, but `a(i)%extra`
+! is an ordinary allocatable INTEGER array with deferred SHAPE and no type
+! parameters at all. Therefore C937 does not apply to it.
+! See attachment to PR82173 comment 10 - 
~/reducers/bug14-bogus-deferred-param-error.f90
+program p
+  type :: t(n)
+    integer, len :: n = 1
+    integer :: v(n)
+    integer, allocatable :: extra(:)
+  end type
+  type(t(:)), allocatable :: a(:)
+  allocate (t(4) :: a(3))
+  allocate (a(1)%extra(2))    ! Error: Allocate-object at (1) with a deferred 
type parameter
+  a(1)%extra = 5              ! requires either a type-spec or SOURCE tag or a 
MOLD tag
+  if (sum (a(1)%extra) /= 10) stop 1
+end program

Reply via email to