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

Reply via email to