https://gcc.gnu.org/g:d2c10df0920856a3ccf62900e2c8736fb0ada736
commit r17-4393-gd2c10df0920856a3ccf62900e2c8736fb0ada736 Author: Paul Thomas <[email protected]> Date: Sun Sep 13 12:32:22 2026 +0100 Fortran: Parameterized derived type component initialization [PR104776] 2026-09-17 Paul Thomas <[email protected]> gcc/fortran PR fortran/104776 * decl.cc (gfc_get_pdt_instance): Simplify the initializers of KIND components in PDT templates since they must be integer constants. Catch any remaining component initializers for parameter substitution, if necessary, and simplification. gcc/testsuite PR fortran/104776 * gfortran.dg/pdt_94.f03: New test. Diff: --- gcc/fortran/decl.cc | 17 +++++++++++++ gcc/testsuite/gfortran.dg/pdt_94.f03 | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 4871737458ef..3eb660a93d47 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -4503,6 +4503,11 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, c2->param_list->next = NULL; } + /* Initializer expressions in PDT templates, such as character_kinds(1), + can end up being mutilated when use associated. Simplify now. */ + if (c1->initializer && c1->initializer->expr_type != EXPR_CONSTANT) + gfc_simplify_expr (c1->initializer, 1); + if (!c2->initializer && c1->initializer) c2->initializer = gfc_copy_expr (c1->initializer); @@ -4655,6 +4660,18 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym, } gfc_simplify_expr (c2->initializer, 1); } + + /* Pick up any remaining initializers that could be simplified. */ + if (c1->initializer) + { + if (!c2->initializer) + c2->initializer = gfc_copy_expr (c1->initializer); + if (gfc_derived_parameter_expr (c2->initializer)) + gfc_insert_parameter_exprs (c2->initializer, type_param_spec_list); + c2->initializer->ts = c2->ts; + if (!!gfc_is_constant_expr (c2->initializer)) + gfc_simplify_expr (c2->initializer, 1); + } } if (alloc_seen) diff --git a/gcc/testsuite/gfortran.dg/pdt_94.f03 b/gcc/testsuite/gfortran.dg/pdt_94.f03 new file mode 100644 index 000000000000..ab0d65e3bc9a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_94.f03 @@ -0,0 +1,49 @@ +! { dg-do run } +! +! Test the fix for PR104776. +! +! Contributed by Amir Shahmoradi <[email protected]> +! +module pdt_mod + + use iso_fortran_env, only: character_kinds + + integer, parameter :: def_kind = selected_char_kind('ascii') + integer, parameter :: unicode_kind = selected_char_kind('ISO_10646') + character(kind=unicode_kind,len=*), parameter :: str = 'abcde' + + type :: BG_type(kind_p) +! This is still failing. + integer , kind :: kind_p = character_kinds(1) +! integer , kind :: kind_p = def_kind + character(5 , kind_p) :: str = achar(97,kind_p)//achar(98,kind_p)// & + achar(99,kind_p)//achar(100,kind_p)//achar(101,kind_p) + end type + +! These declarations worked as expected +! type (BG_type) :: a_m = BG_type (def_kind)("abcde") +! type (BG_type(selected_char_kind('ISO_10646'))) :: b_m = BG_type (selected_char_kind('ISO_10646'))(str) +! Now so do these + type (BG_type) :: a_m + type (BG_type(unicode_kind)) :: b_m + +contains + subroutine print_mod_vars () + if (a_m%str /= 'abcde') stop 1 + if (b_m%str /= str) stop 2 + end +end module + + use pdt_mod + type (BG_type) :: a ! Caused an ICE + type (BG_type(unicode_kind)) :: b + a_m = BG_type (def_kind)("abcde") + b_m = BG_type (unicode_kind)(str) + if (a%str%kind /= def_kind) stop 3 + if (b%str%kind /= unicode_kind) stop 4 + if (a%str /= 'abcde') stop 5 + if (b%str /= str) stop 6 + if (a_m%str /= 'abcde') stop 7 + if (b_m%str /= str) stop 8 + call print_mod_vars () +end
