I plan commit the attached patch from Christopher if
no objections.

The patch was provided in the PR and tested by the
original reporter and myself.

Regression tested on x86_64_linux_gnu.

Regards,

Jerry

Fortran: [PR123949] Fix PDT ICE with large KIND values.

Signed-off-by: Christopher Albert <[email protected]>

    PR fortran/123949
gcc/fortran/ChangeLog:

    * decl.cc (gfc_get_pdt_instance): Use full integer string encoding
    for PDT instance naming rather than 32-bit extraction, which caused
    ICEs for valid large KIND values.

gcc/testsuite/ChangeLog:

    * gfortran.dg/pdt_85.f03: New test.
    * gfortran.dg/pr123949.f90: New test.



commit a83e7d374e784efdd571c45aafa7b01baf393ce9
Author: Jerry DeLisle <[email protected]>
Date:   Thu Feb 19 16:59:16 2026 -0800

    Fortran: [PR123949] Fix PDT ICE with large KIND values.
    
    Signed-off-by: Christopher Albert <[email protected]>
    
            PR fortran/123949
    
    gcc/fortran/ChangeLog:
    
            * decl.cc (gfc_get_pdt_instance): Use full integer string encoding
            for PDT instance naming rather than 32-bit extraction, which caused
            ICEs for valid large KIND values.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/pdt_85.f03: New test.
            * gfortran.dg/pr123949.f90: New test.

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index b5128580548..8b659a3f36a 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -3960,16 +3960,15 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
   /* Pointers to the parameter specification being used.  */
   gfc_actual_arglist *actual_param;
   gfc_actual_arglist *tail = NULL;
-  /* Used to build up the name of the PDT instance. The prefix uses 3
-     characters and each KIND parameter 2 more.  Allow 8 of the latter. */
-  char name[GFC_MAX_SYMBOL_LEN + PDT_PREFIX_LEN + 16];
+  /* Used to build up the name of the PDT instance.  */
+  char *name;
   bool name_seen = (param_list == NULL);
   bool assumed_seen = false;
   bool deferred_seen = false;
   bool spec_error = false;
   bool alloc_seen = false;
   bool ptr_seen = false;
-  int kind_value, i;
+  int i;
   gfc_expr *kind_expr;
   gfc_component *c1, *c2;
   match m;
@@ -3979,7 +3978,6 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
 
   type_param_name_list = pdt->formal;
   actual_param = param_list;
-  sprintf (name, "%s%s", PDT_PREFIX, pdt->name);
 
   /* Prevent a PDT component of the same type as the template from being
      converted into an instance. Doing this results in the component being
@@ -3994,6 +3992,8 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
       return MATCH_YES;
     }
 
+  name = xasprintf ("%s%s", PDT_PREFIX, pdt->name);
+
   /* Run through the parameter name list and pick up the actual
      parameter values or use the default values in the PDT declaration.  */
   for (; type_param_name_list;
@@ -4156,17 +4156,22 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
 	  goto error_return;
 	}
 
-      kind_value = 0;
       /* This can come about during the parsing of nested pdt_templates. An
 	 error arises because the KIND parameter expression has not been
 	 provided. Use the template instead of an incorrect instance.  */
-      if (gfc_extract_int (kind_expr, &kind_value))
+      if (kind_expr->expr_type != EXPR_CONSTANT
+	  || kind_expr->ts.type != BT_INTEGER)
 	{
 	  gfc_free_actual_arglist (type_param_spec_list);
+	  free (name);
 	  return MATCH_YES;
 	}
 
-      sprintf (name + strlen (name), "_%d", kind_value);
+      char *kind_value = mpz_get_str (NULL, 10, kind_expr->value.integer);
+      char *old_name = name;
+      name = xasprintf ("%s_%s", old_name, kind_value);
+      free (old_name);
+      free (kind_value);
 
       if (!name_seen && actual_param)
 	actual_param = actual_param->next;
@@ -4217,6 +4222,7 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
         *ext_param_list = type_param_spec_list;
       *sym = instance;
       gfc_commit_symbols ();
+      free (name);
       return m;
     }
 
@@ -4533,10 +4539,12 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
   if (ext_param_list)
     *ext_param_list = type_param_spec_list;
   *sym = instance;
+  free (name);
   return m;
 
 error_return:
   gfc_free_actual_arglist (type_param_spec_list);
+  free (name);
   return MATCH_ERROR;
 }
 
diff --git a/gcc/testsuite/gfortran.dg/pdt_85.f03 b/gcc/testsuite/gfortran.dg/pdt_85.f03
new file mode 100644
index 00000000000..e22d18be981
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_85.f03
@@ -0,0 +1,35 @@
+! { dg-do compile }
+!
+! Verify that large KIND values create distinct PDT instances.
+!
+module m
+  implicit none
+  integer(8), parameter :: k1 = 2147483648_8 + 100_8
+  integer(8), parameter :: k2 = k1 + 4294967296_8
+
+  type t(k)
+    integer(8), kind :: k
+    integer :: v
+  end type
+
+  interface chk
+    module procedure chk1, chk2
+  end interface
+contains
+  subroutine chk1(x)
+    type(t(k1)), intent(in) :: x
+  end subroutine
+
+  subroutine chk2(x)
+    type(t(k2)), intent(in) :: x
+  end subroutine
+end module
+
+program p
+  use m
+  implicit none
+  type(t(k1)) :: a
+  type(t(k2)) :: b
+  call chk(a)
+  call chk(b)
+end program
diff --git a/gcc/testsuite/gfortran.dg/pr123949.f90 b/gcc/testsuite/gfortran.dg/pr123949.f90
new file mode 100644
index 00000000000..ad4855cff04
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr123949.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+!
+! PR fortran/123949
+! ICE in gfc_match_decl_type_spec with large KIND parameter values.
+!
+module pr123949_mod
+  implicit none
+  integer(8), parameter :: big_k = 2147483647_8 + 12345_8
+
+  type cell(k)
+    integer(8), kind :: k
+    integer(8) :: stamp = -k
+  end type
+
+  type(cell(big_k)) :: base
+contains
+  subroutine make_item(item)
+    type(cell(big_k)), allocatable, intent(out) :: item
+    allocate (cell(big_k) :: item)
+  end subroutine
+end module
+
+program pr123949
+  use pr123949_mod
+  implicit none
+  type(cell(big_k)), allocatable :: dyn
+  call make_item(dyn)
+end program

Reply via email to