Hello Jerry, After some thought and a review by Claude, I am resubmitting a rather more elaborate version of bug1.patch. Please find the replacement attached.
The first chunk replaces a call to gfc_pdt_find_component_copy_initializer with one to gfc_simplify_len. This allows the simplification of a far wider range of parameterized string length expressions. The prototype for gfc_simplify_len has to be added to gfortran.h of course. I tried to avoid this by using gfc_build_intrinsic_call and simplifying the call expression. For some reason that I couldn't see, this produced perfectly OK code that did not simplify, resulting in pdt_33.f03 regressing. I will make one last attempt to get this version to work before pushing the attached. Most of the patch tidies up the original code in gfc_simplify_len, making it considerably more comprehensible. The second half is a more hygienic fix for pdt_bug1 in that a result is returned for length expressions, which after parameter replacement, simplify to a constant expression. The patch passes regression testing on FC44/x86_64 - OK for mainline? Paul ---------- Forwarded message --------- From: Jerry D <[email protected]> Date: Thu, 8 Oct 2026 at 20:03 Subject: Re: [Patch, fortran] (1/16) 82173 Parameterized derived type errors comment #10 To: Paul Richard Thomas <[email protected]>, [email protected] <[email protected]>, gcc-patches <[email protected]> On 10/8/26 5:31 AM, Paul Richard Thomas wrote: > bug1-simplify-len-ice.f90 fails in compilation with: > > f951: internal compiler error: Segmentation fault > 0x276485f internal_error(char const*, ...) > ../../gcc/gcc/diagnostic-global-context.cc:787 > 0xfa57cf crash_signal > ../../gcc/gcc/toplev.cc:325 > 0x81decb gfc_simplify_len(gfc_expr*, gfc_expr*) > ../../gcc/gcc/fortran/simplify.cc:5085 > 0x76a949 do_simplify > ../../gcc/gcc/fortran/intrinsic.cc:5002 > > The attached tidies up the appearance of the code around the fix and > punts on null symtrees. > > Passes regtesting on FC44/x86_64. OK for mainline. > > Cheers > > Paul This one looks good to go. Thanks, Jerry
From 8ddbf25a4261fa99f8e51025a821968270a98a67 Mon Sep 17 00:00:00 2001 From: Paul Thomas <[email protected]> Date: Mon, 12 Oct 2026 13:02:47 +0100 Subject: [PATCH] Fortran: [PDT] (1/16) Parameterized derived type errors [PR82173] 2026-10-12 Paul Thomas <[email protected]> gcc/fortran PR fortran/82173 * expr.cc (find_inquiry_ref): Instead of calling gfc_pdt_find_ component_copy_initializer directly, build a KIND expression and call gfc_simplify_len. * gfortran.h : Add prototype for gfc_simplify_len. * simplify.cc (gfc_simplify_len): Simplify the logic for access to the original code by detecting a pdt_string and a variable string length. Reduce the verbosity of the code by storing the variable name. If the pdt_string does not have a length that is a variable, insert the parameter expressions to a copy of the string length. Return if this then simplifies to a constant expression. gcc/testsuite/ PR fortran/82173 * gfortran.dg/pdt_bug1.f90: New test. --- gcc/fortran/expr.cc | 17 ++++++------ gcc/fortran/gfortran.h | 1 + gcc/fortran/simplify.cc | 37 +++++++++++++++++--------- gcc/testsuite/gfortran.dg/pdt_bug1.f90 | 15 +++++++++++ 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pdt_bug1.f90 diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index 68663fe35d1..48711f7fe7a 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -2050,15 +2050,16 @@ find_inquiry_ref (gfc_expr *p, gfc_expr **newp) else if (tmp->expr_type == EXPR_CONSTANT) *newp = gfc_get_int_expr (gfc_default_integer_kind, NULL, tmp->value.character.length); - else if (gfc_init_expr_flag - && tmp->ts.u.cl->length->symtree->n.sym->attr.pdt_len) - *newp = gfc_pdt_find_component_copy_initializer (tmp->symtree->n - .sym, - tmp->ts.u.cl - ->length->symtree - ->n.sym->name); else - goto cleanup; + { + gfc_expr *kind_expr; + kind_expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, + tmp->ts.kind); + *newp = gfc_simplify_len (tmp, kind_expr); + if (*newp) + break; + goto cleanup; + } break; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index a1badd0bde8..5f05ac39670 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -4486,6 +4486,7 @@ gfc_expr *gfc_simplify_ieee_functions (gfc_expr *); bool gfc_is_constant_array_expr (gfc_expr *); bool gfc_is_size_zero_array (gfc_expr *); void gfc_convert_mpz_to_unsigned (mpz_t, int, bool sign = true); +gfc_expr *gfc_simplify_len (gfc_expr *, gfc_expr *); /* trans-array.cc */ diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc index f0b36c06687..bc3931e73ac 100644 --- a/gcc/fortran/simplify.cc +++ b/gcc/fortran/simplify.cc @@ -5060,20 +5060,15 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) component the last _data ref needs to be stripped and a ref to the _len component added. */ return gfc_get_len_component (e->symtree->n.sym->assoc->target, k); - else if (e->symtree->n.sym->ts.type == BT_DERIVED - && e->ref && e->ref->type == REF_COMPONENT - && e->ref->u.c.component->attr.pdt_string - && e->ref->u.c.component->ts.type == BT_CHARACTER - && e->ref->u.c.component->ts.u.cl->length) + else if (gfc_expr_attr (e).pdt_string + && e->ts.u.cl->length->expr_type == EXPR_VARIABLE) { + const char *name = e->ts.u.cl->length->symtree->name; if (gfc_init_expr_flag) { gfc_expr* tmp; tmp = gfc_pdt_find_component_copy_initializer (e->symtree->n.sym, - e->ref->u.c - .component->ts.u.cl - ->length->symtree - ->name); + name); if (tmp) return tmp; } @@ -5082,14 +5077,30 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) gfc_expr *len_expr = gfc_copy_expr (e); gfc_free_ref_list (len_expr->ref); len_expr->ref = NULL; - gfc_find_component (len_expr->symtree->n.sym->ts.u.derived, e->ref - ->u.c.component->ts.u.cl->length->symtree - ->name, - false, true, &len_expr->ref); + gfc_find_component (len_expr->symtree->n.sym->ts.u.derived, + name, false, true, &len_expr->ref); len_expr->ts = len_expr->ref->u.c.component->ts; return len_expr; } } + else if (gfc_expr_attr (e).pdt_string) + { + gfc_actual_arglist *parms; + gfc_expr *len_expr; + + len_expr = gfc_copy_expr (e->ts.u.cl->length); + parms = e->param_list ? e->param_list : + e->symtree->n.sym->param_list; + if (parms) + gfc_insert_parameter_exprs (len_expr, parms); + + if (e->ts.u.cl->length->expr_type != EXPR_VARIABLE + && gfc_simplify_expr (len_expr, 0) + && gfc_is_constant_expr (len_expr)) + return len_expr; + + gfc_free_expr (len_expr); + } } else if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_CHARACTER && e->ts.u.cl diff --git a/gcc/testsuite/gfortran.dg/pdt_bug1.f90 b/gcc/testsuite/gfortran.dg/pdt_bug1.f90 new file mode 100644 index 00000000000..ca9292ed655 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pdt_bug1.f90 @@ -0,0 +1,15 @@ +! { dg-do run } +! Used to ICE at line 10 in simplify.cc(gfc_simplify_len). +! See attachment to PR82173 comment 10 - reproducers/bug1-simplify_len_ice.f90 +program r6 + type :: t(n) + integer, len :: n = 2 + character(len=2*n) :: c1 + character(len=n*n - 1) :: c2 + end type + type(t(3)) :: p + if (len (p%c1) /= 6) stop 1 +! Add a slightly more complicated version and use LEN in a different context. + p%c2 = repeat ('X', len (p%c2)) + if (p%c2 /= 'XXXXXXXX') stop 2 +end program -- 2.56.0
