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
