Re: [Patch, Fortran, 96418] Fix Test coarray_alloc_comp_4.f08 ICEs

2024-06-14 Thread Andre Vehreschild
Hi all,

I messed up renaming of the coarray_alloc_comp-test. This is fixed in the second
version of the patch. Sorry for the inconvenience.

Additionally I figured that this patch also fixed PR fortran/103112.

Regtests ok on x86_64 Fedora 39. Ok for mainline?

Regards,
Andre

On Tue, 11 Jun 2024 16:12:38 +0200
Andre Vehreschild  wrote:

> Hi all,
>
> attached patch has already been present in 2020, but lost my attention. It
> fixes an ICE in the testsuite. The old mails description is:
>
> attached patch fixes PR96418 where the code in the testsuite when compiled
> with -fcoarray=single  lead to an ICE. The reason was that the coarray object
> was derefed as an array, but it was no array. Introducing the test for the
> descriptor removes the ICE.
>
> Regtests ok on x86_64-linux/Fedora 39. Ok for mainline?
>
> Regards,
>   Andre
> --
> Andre Vehreschild * Email: vehre ad gmx dot de


--
Andre Vehreschild * Email: vehre ad gmx dot de
From 50ed0af756a3eb6b9c95a39c379e1b3f2daf331d Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Tue, 11 Jun 2024 15:24:55 +0200
Subject: [PATCH] Fix ICE when compiling with -fcoarray=single, when derefing a
 non-array.

PR fortran/96418
PR fortran/103112

gcc/fortran/ChangeLog:

* trans.c (gfc_deallocate_with_status): Check that object to deref
is an array, before applying array deref.

gcc/testsuite/ChangeLog:

* gfortran.dg/coarray_alloc_comp_3.f08: Moved to...
* gfortran.dg/coarray/alloc_comp_8.f90: ...here.
Should be tested for both -fcoarray=single and lib, resp.
* gfortran.dg/coarray_alloc_comp_4.f08: Fix program name.
---
 gcc/fortran/trans.cc   | 3 ++-
 .../{coarray_alloc_comp_3.f08 => coarray/alloc_comp_8.f90} | 3 +--
 gcc/testsuite/gfortran.dg/coarray_alloc_comp_4.f08 | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
 rename gcc/testsuite/gfortran.dg/{coarray_alloc_comp_3.f08 => coarray/alloc_comp_8.f90} (95%)

diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index a208afe90ab..1335b8cc48b 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -1838,7 +1838,8 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
 	  else
 	caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
 	}
-  else if (flag_coarray == GFC_FCOARRAY_SINGLE)
+  else if (flag_coarray == GFC_FCOARRAY_SINGLE
+	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
 	pointer = gfc_conv_descriptor_data_get (pointer);
 }
   else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
diff --git a/gcc/testsuite/gfortran.dg/coarray_alloc_comp_3.f08 b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_8.f90
similarity index 95%
rename from gcc/testsuite/gfortran.dg/coarray_alloc_comp_3.f08
rename to gcc/testsuite/gfortran.dg/coarray/alloc_comp_8.f90
index e2037aa5809..8b153925129 100644
--- a/gcc/testsuite/gfortran.dg/coarray_alloc_comp_3.f08
+++ b/gcc/testsuite/gfortran.dg/coarray/alloc_comp_8.f90
@@ -1,12 +1,11 @@
 ! { dg-do run }
-! { dg-options "-fcoarray=lib -lcaf_single" }
 ! { dg-additional-options "-latomic" { target libatomic_available } }
 !
 ! Contributed by Andre Vehreschild
 ! Check that manually freeing components does not lead to a runtime crash,
 ! when the auto-deallocation is taking care.

-program coarray_alloc_comp_3
+program alloc_comp_6
   implicit none

   type dt
diff --git a/gcc/testsuite/gfortran.dg/coarray_alloc_comp_4.f08 b/gcc/testsuite/gfortran.dg/coarray_alloc_comp_4.f08
index 6586ec651dd..4c71a90af8f 100644
--- a/gcc/testsuite/gfortran.dg/coarray_alloc_comp_4.f08
+++ b/gcc/testsuite/gfortran.dg/coarray_alloc_comp_4.f08
@@ -5,7 +5,7 @@
 ! Contributed by Andre Vehreschild
 ! Check that sub-components are caf_deregistered and not freed.

-program coarray_alloc_comp_3
+program coarray_alloc_comp_4
   implicit none

   type dt
--
2.45.1



Re: [Patch, fortran] PR59104

2024-06-14 Thread Andre Vehreschild
Hi Paul,

to me this looks fine. Thanks for the patch. Me having been away for some time
from gfortran, I recommend you wait for Harald's ok, too.

Regards,
Andre

On Thu, 13 Jun 2024 22:43:03 +0100
Paul Richard Thomas  wrote:

> Hi Both,
>
> Thanks for the highly constructive comments. I think that I have
> incorporated them fully in the attached.
>
> OK for mainline and ...?
>
> Paul
>
>
> On Mon, 10 Jun 2024 at 08:19, Andre Vehreschild  wrote:
>
> > Hi Paul,
> >
> > while looking at your patch I see calls to gfc_add_init_cleanup (...,
> > back),
> > while the function signature is gfc_add_init_cleanup (..., bool front).
> > This
> > slightly confuses me. I would at least expect to see
> > gfc_add_init_cleanup(...,
> > !back) calls. Just to get the semantics right.
> >
> > Then I wonder why not doing:
> >
> > diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
> > index bafe8cbc5bc..97ace8c778e 100644
> > --- a/gcc/fortran/dependency.cc
> > +++ b/gcc/fortran/dependency.cc
> > @@ -2497,3 +2497,63 @@ gfc_omp_expr_prefix_same (gfc_expr *lexpr, gfc_expr
> > *rexpr)
> >return true;
> >  }
> > +
> > +
> > +/* gfc_function_dependency returns true for non-dummy symbols with
> > dependencies
> > +   on an old-fashioned function result (ie. proc_name =
> > proc_name->result).
> > +   This is used to ensure that initialization code appears after the
> > function
> > +   result is treated and that any mutual dependencies between these
> > symbols are
> > +   respected.  */
> > +
> > +static bool
> > +dependency_fcn (gfc_expr *e, gfc_symbol *sym,
> > +int *f ATTRIBUTE_UNUSED)
> > +{
> > +  return (e && e->expr_type == EXPR_VARIABLE
> > +  && e->symtree
> > +  && e->symtree->n.sym == sym);
> > +}
> >
> > Instead of the multiple if-statements?
> >
> > +
> > +bool
> > +gfc_function_dependency (gfc_symbol *sym, gfc_symbol *proc_name)
> > +{
> > +  bool front = false;
> > +
> > +  if (proc_name && proc_name->attr.function
> > +  && proc_name == proc_name->result
> > +  && !(sym->attr.dummy || sym->attr.result))
> > +{
> > +  if (sym->as && sym->as->type == AS_EXPLICIT)
> > +   {
> > + for (int dim = 0; dim < sym->as->rank; dim++)
> > +   {
> > + if (sym->as->lower[dim]
> > + && sym->as->lower[dim]->expr_type != EXPR_CONSTANT)
> > +   front = gfc_traverse_expr (sym->as->lower[dim], proc_name,
> > +  dependency_fcn, 0);
> > + if (front)
> > +   break;
> > + if (sym->as->upper[dim]
> > + && sym->as->upper[dim]->expr_type != EXPR_CONSTANT)
> > +   front = gfc_traverse_expr (sym->as->upper[dim], proc_name,
> > +  dependency_fcn, 0);
> > + if (front)
> > +   break;
> > +   }
> > +   }
> > +
> > +  if (sym->ts.type == BT_CHARACTER
> > + && sym->ts.u.cl && sym->ts.u.cl->length
> > + && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
> > +   front = gfc_traverse_expr (sym->ts.u.cl->length, proc_name,
> > +  dependency_fcn, 0);
> >
> > This can overwrite a previous front == true, right? Is this intended?
> >
> > +}
> > +  return front;
> > + }
> >
> > The rest - besides the front-back confusion - looks fine to me. Thanks for
> > the
> > patch.
> >
> > Regards,
> > Andre
> >
> > On Sun, 9 Jun 2024 07:14:39 +0100
> > Paul Richard Thomas  wrote:
> >
> > > Hi All,
> > >
> > > The attached fixes a problem that, judging by the comments, has been
> > looked
> > > at periodically over the last ten years but just looked to be too
> > > fiendishly complicated to fix. This is not in small part because of the
> > > confusing ordering of dummies in the tlink chain and the unintuitive
> > > placement of all deferred initializations to the front of the init chain
> > in
> > > the wrapped block.
> > >
> > > The result of the existing ordering is that the initialization code for
> > > non-dummy variables that depends on the function result occurs before any
> > > initialization code for the function result itself. The fix ensures that:
> > > (i) These variables are placed correctly in the tlink chain, respecting
> > > inter-dependencies; and (ii) The dependent initializations are placed at
> > > the end of the wrapped block init chain.  The details appear in the
> > > comments in the patch. It is entirely possible that a less clunky fix
> > > exists but I failed to find it.
> > >
> > > OK for mainline?
> > >
> > > Regards
> > >
> > > Paul
> >
> >
> > --
> > Andre Vehreschild * Email: vehre ad gmx dot de
> >


--
Andre Vehreschild * Email: vehre ad gmx dot de


Re: [Patch, fortran] PR59104

2024-06-14 Thread Paul Richard Thomas
Hi Andre,

Thanks - I will wait for Harald, if for no other reason than I just don't
have time today to do the commit :-)

BTW Note the commented out lines in the testcase. They fail in the front
end for reasons that I am not sure are correct. Interestingly, nagfor does
the same. Ifort fails on many of the lines that the patched gfortran and
nagfor accept. Any insights from anybody? The declaration order looks OK to
me and, I would have thought, they could be fixed up in resolution.

Cheers

Paul


On Fri, 14 Jun 2024 at 08:48, Andre Vehreschild  wrote:

> Hi Paul,
>
> to me this looks fine. Thanks for the patch. Me having been away for some
> time
> from gfortran, I recommend you wait for Harald's ok, too.
>
> Regards,
> Andre
>
> On Thu, 13 Jun 2024 22:43:03 +0100
> Paul Richard Thomas  wrote:
>
> > Hi Both,
> >
> > Thanks for the highly constructive comments. I think that I have
> > incorporated them fully in the attached.
> >
> > OK for mainline and ...?
> >
> > Paul
> >
> >
> > On Mon, 10 Jun 2024 at 08:19, Andre Vehreschild  wrote:
> >
> > > Hi Paul,
> > >
> > > while looking at your patch I see calls to gfc_add_init_cleanup (...,
> > > back),
> > > while the function signature is gfc_add_init_cleanup (..., bool front).
> > > This
> > > slightly confuses me. I would at least expect to see
> > > gfc_add_init_cleanup(...,
> > > !back) calls. Just to get the semantics right.
> > >
> > > Then I wonder why not doing:
> > >
> > > diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
> > > index bafe8cbc5bc..97ace8c778e 100644
> > > --- a/gcc/fortran/dependency.cc
> > > +++ b/gcc/fortran/dependency.cc
> > > @@ -2497,3 +2497,63 @@ gfc_omp_expr_prefix_same (gfc_expr *lexpr,
> gfc_expr
> > > *rexpr)
> > >return true;
> > >  }
> > > +
> > > +
> > > +/* gfc_function_dependency returns true for non-dummy symbols with
> > > dependencies
> > > +   on an old-fashioned function result (ie. proc_name =
> > > proc_name->result).
> > > +   This is used to ensure that initialization code appears after the
> > > function
> > > +   result is treated and that any mutual dependencies between these
> > > symbols are
> > > +   respected.  */
> > > +
> > > +static bool
> > > +dependency_fcn (gfc_expr *e, gfc_symbol *sym,
> > > +int *f ATTRIBUTE_UNUSED)
> > > +{
> > > +  return (e && e->expr_type == EXPR_VARIABLE
> > > +  && e->symtree
> > > +  && e->symtree->n.sym == sym);
> > > +}
> > >
> > > Instead of the multiple if-statements?
> > >
> > > +
> > > +bool
> > > +gfc_function_dependency (gfc_symbol *sym, gfc_symbol *proc_name)
> > > +{
> > > +  bool front = false;
> > > +
> > > +  if (proc_name && proc_name->attr.function
> > > +  && proc_name == proc_name->result
> > > +  && !(sym->attr.dummy || sym->attr.result))
> > > +{
> > > +  if (sym->as && sym->as->type == AS_EXPLICIT)
> > > +   {
> > > + for (int dim = 0; dim < sym->as->rank; dim++)
> > > +   {
> > > + if (sym->as->lower[dim]
> > > + && sym->as->lower[dim]->expr_type != EXPR_CONSTANT)
> > > +   front = gfc_traverse_expr (sym->as->lower[dim],
> proc_name,
> > > +  dependency_fcn, 0);
> > > + if (front)
> > > +   break;
> > > + if (sym->as->upper[dim]
> > > + && sym->as->upper[dim]->expr_type != EXPR_CONSTANT)
> > > +   front = gfc_traverse_expr (sym->as->upper[dim],
> proc_name,
> > > +  dependency_fcn, 0);
> > > + if (front)
> > > +   break;
> > > +   }
> > > +   }
> > > +
> > > +  if (sym->ts.type == BT_CHARACTER
> > > + && sym->ts.u.cl && sym->ts.u.cl->length
> > > + && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
> > > +   front = gfc_traverse_expr (sym->ts.u.cl->length, proc_name,
> > > +  dependency_fcn, 0);
> > >
> > > This can overwrite a previous front == true, right? Is this intended?
> > >
> > > +}
> > > +  return front;
> > > + }
> > >
> > > The rest - besides the front-back confusion - looks fine to me. Thanks
> for
> > > the
> > > patch.
> > >
> > > Regards,
> > > Andre
> > >
> > > On Sun, 9 Jun 2024 07:14:39 +0100
> > > Paul Richard Thomas  wrote:
> > >
> > > > Hi All,
> > > >
> > > > The attached fixes a problem that, judging by the comments, has been
> > > looked
> > > > at periodically over the last ten years but just looked to be too
> > > > fiendishly complicated to fix. This is not in small part because of
> the
> > > > confusing ordering of dummies in the tlink chain and the unintuitive
> > > > placement of all deferred initializations to the front of the init
> chain
> > > in
> > > > the wrapped block.
> > > >
> > > > The result of the existing ordering is that the initialization code
> for
> > > > non-dummy variables that depends on the function result occurs
> before any
> 

[Fortran, Patch, PR 96992] Fix Class arrays of different ranks are rejected as storage association argument

2024-06-14 Thread Andre Vehreschild
Hi all,

I somehow got assigned to this PR so I fixed it. GFortran was ICEing because of
the ASSUME_RANK in a derived to class conversion. After fixing this, storage
association was producing segfaults. The "shape conversion" of the class array
as dummy argument was not initializing the dim 0 stride and with that grabbing
into the memory somewhere. This is now fixed and

regtests fine on x86_64 Fedora 39. Ok for mainline?

I assume this patch could be fixing some other PRs with class array's parameter
passing, too. If that sounds familiar, feel free to point me to them.

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 86ac3179e1314ca1c41f52025c5a156ad7346dc1 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Fri, 14 Jun 2024 16:54:37 +0200
Subject: [PATCH] Fortran: [PR96992] Fix rejecting class arrays of different
 ranks as storage association argument.

Removing the assert in trans-expr, lead to initial strides not set
which is not fixed.

	PR fortran/96992

gcc/fortran/ChangeLog:

	* trans-array.cc (gfc_trans_array_bounds): Set a starting
	stride, when descriptor expects a variable for the stride.
	(gfc_trans_dummy_array_bias): Allow storage association for
	dummy class arrays, when they are not elemental.
	* trans-expr.cc (gfc_conv_derived_to_class): Remove assert to
	allow converting derived to class type arrays with assumend
	rank.

gcc/testsuite/ChangeLog:

	* gfortran.dg/pr96992.f90: New test.
---
 gcc/fortran/trans-array.cc|  7 ++-
 gcc/fortran/trans-expr.cc |  2 -
 gcc/testsuite/gfortran.dg/pr96992.f90 | 61 +++
 3 files changed, 67 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pr96992.f90

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b3088a892c8..9fa8bad2f35 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -6798,6 +6798,9 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,

   size = gfc_index_one_node;
   offset = gfc_index_zero_node;
+  stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
+  if (stride && VAR_P (stride))
+gfc_add_modify (pblock, stride, gfc_index_one_node);
   for (dim = 0; dim < as->rank; dim++)
 {
   /* Evaluate non-constant array bound expressions.
@@ -7134,7 +7137,9 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
   || (is_classarray && CLASS_DATA (sym)->attr.allocatable))
 return;

-  if (!is_classarray && sym->attr.dummy && gfc_is_nodesc_array (sym))
+  if ((!is_classarray
+   || (is_classarray && CLASS_DATA (sym)->as->type == AS_EXPLICIT))
+  && sym->attr.dummy && !sym->attr.elemental && gfc_is_nodesc_array (sym))
 {
   gfc_trans_g77_array (sym, block);
   return;
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 0796fb75505..4bb62cfb1ad 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -903,8 +903,6 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,

 	  if (e->rank != class_ts.u.derived->components->as->rank)
 	{
-	  gcc_assert (class_ts.u.derived->components->as->type
-			  == AS_ASSUMED_RANK);
 	  if (derived_array
 		  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
 		{
diff --git a/gcc/testsuite/gfortran.dg/pr96992.f90 b/gcc/testsuite/gfortran.dg/pr96992.f90
new file mode 100644
index 000..c56ed80f394
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr96992.f90
@@ -0,0 +1,61 @@
+! { dg-do run }
+
+! PR fortran/96992
+
+! Contributed by Thomas Koenig  
+
+! From the standard:
+! An actual argument that represents an element sequence and
+! corresponds to a dummy argument that is an array is sequence
+! associated with the dummy argument. The rank and shape of the
+! actual argument need not agree with the rank and shape of the
+! dummy argument, but the number of elements in the dummy argument
+! shall not exceed the number of elements in the element sequence
+! of the actual argument. If the dummy argument is assumed-size,
+! the number of elements in the dummy argument is exactly
+! the number of elements in the element sequence.
+
+! Check that walking the sequence starts with an initialized stride
+! for dim == 0.
+
+module foo_mod
+  implicit none
+  type foo
+ integer :: i
+  end type foo
+contains
+  subroutine d1(x,n)
+integer, intent(in) :: n
+integer :: i
+class (foo), intent(out), dimension(n) :: x
+select type(x)
+class is(foo)
+   x(:)%i = (/ (42 + i, i = 1, n ) /)
+class default
+   stop 1
+end select
+  end subroutine d1
+  subroutine d2(x,n)
+integer, intent(in) :: n
+integer :: i
+class (foo), intent(in), dimension(n,n,n) :: x
+select type (x)
+class is (foo)
+   print *,x%i
+   if ( any( x%i /= reshape((/ (42 + i, i = 1, n ** 3 ) /), [n, n, n] ))) stop 2
+class default
+   stop 3
+end select
+  end subroutine d2
+end module foo_mod
+program main
+  use foo_mod
+  i

Re: [Patch, Fortran, 96418] Fix Test coarray_alloc_comp_4.f08 ICEs

2024-06-14 Thread Harald Anlauf

Hi Andre,

the patch looks fairly simple and obvious, so OK from my side.

***

Regarding the testsuite: since you renamed one of the testcases
gfortran.dg/coarray_alloc_comp_* and moved it to gfortran.dg/coarray/,
I checked and noticed that there are other similar runtime tests for
coarrays (while some are compile-time only tests).

Do we plan to "clean" this up and move more/all related runtime
tests to the coarray/ subdirectory?  What is the general opinion on
this?

***

Thanks for the patch!

Harald


Am 14.06.24 um 09:22 schrieb Andre Vehreschild:

Hi all,

I messed up renaming of the coarray_alloc_comp-test. This is fixed in the second
version of the patch. Sorry for the inconvenience.

Additionally I figured that this patch also fixed PR fortran/103112.

Regtests ok on x86_64 Fedora 39. Ok for mainline?

Regards,
Andre

On Tue, 11 Jun 2024 16:12:38 +0200
Andre Vehreschild  wrote:


Hi all,

attached patch has already been present in 2020, but lost my attention. It
fixes an ICE in the testsuite. The old mails description is:

attached patch fixes PR96418 where the code in the testsuite when compiled
with -fcoarray=single  lead to an ICE. The reason was that the coarray object
was derefed as an array, but it was no array. Introducing the test for the
descriptor removes the ICE.

Regtests ok on x86_64-linux/Fedora 39. Ok for mainline?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de



--
Andre Vehreschild * Email: vehre ad gmx dot de




Re: [Patch, fortran] PR59104

2024-06-14 Thread Harald Anlauf

Hi Paul,

this looks good to me and is OK for mainline.  When it has survived a
week or two, backporting at least to 14-branch (ideally before 14.2
release) would be a good thing!

Regarding the following excerpt of the testcase:

+! Commented out lines give implicit type warnings with gfortran and nagfor
+!character(len = len (d)) :: line4 (len (line3))
+character(len = len (line3)) :: line4 (len (line3))
+!character(len = size(len4, 1)) :: line5

I guess the last commented line should have referred to size(line4, 1),
right?  The lexical distance of len4 and line4 can be small after
long coding...

The first commented line gives no warning here, but is simply
inconsistent with a test later on, since len (d) < len (line3).
What exactly was the issue?

***

A minor nit: while you were fixing whitespace issues in the source,
you missed an indent with spaces here:

@@ -857,12 +873,26 @@ gfc_defer_symbol_init (gfc_symbol * sym)
   /* Find the first dummy arg seen after us, or the first
non-dummy arg.
  This is a circular list, so don't go past the head.  */
   while (p != head
- && (!p->attr.dummy || p->dummy_order > sym->dummy_order))
+ && (!p->attr.dummy || decl_order (p, sym)))
 {

At least on my side there is no tab...
(It is fine in a similar code later on.)

***

Finally a big thanks for the patch!

Harald


Am 13.06.24 um 23:43 schrieb Paul Richard Thomas:

Hi Both,

Thanks for the highly constructive comments. I think that I have
incorporated them fully in the attached.

OK for mainline and ...?

Paul


On Mon, 10 Jun 2024 at 08:19, Andre Vehreschild  wrote:


Hi Paul,

while looking at your patch I see calls to gfc_add_init_cleanup (...,
back),
while the function signature is gfc_add_init_cleanup (..., bool front).
This
slightly confuses me. I would at least expect to see
gfc_add_init_cleanup(...,
!back) calls. Just to get the semantics right.

Then I wonder why not doing:

diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index bafe8cbc5bc..97ace8c778e 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -2497,3 +2497,63 @@ gfc_omp_expr_prefix_same (gfc_expr *lexpr, gfc_expr
*rexpr)
return true;
  }
+
+
+/* gfc_function_dependency returns true for non-dummy symbols with
dependencies
+   on an old-fashioned function result (ie. proc_name =
proc_name->result).
+   This is used to ensure that initialization code appears after the
function
+   result is treated and that any mutual dependencies between these
symbols are
+   respected.  */
+
+static bool
+dependency_fcn (gfc_expr *e, gfc_symbol *sym,
+int *f ATTRIBUTE_UNUSED)
+{
+  return (e && e->expr_type == EXPR_VARIABLE
+  && e->symtree
+  && e->symtree->n.sym == sym);
+}

Instead of the multiple if-statements?

+
+bool
+gfc_function_dependency (gfc_symbol *sym, gfc_symbol *proc_name)
+{
+  bool front = false;
+
+  if (proc_name && proc_name->attr.function
+  && proc_name == proc_name->result
+  && !(sym->attr.dummy || sym->attr.result))
+{
+  if (sym->as && sym->as->type == AS_EXPLICIT)
+   {
+ for (int dim = 0; dim < sym->as->rank; dim++)
+   {
+ if (sym->as->lower[dim]
+ && sym->as->lower[dim]->expr_type != EXPR_CONSTANT)
+   front = gfc_traverse_expr (sym->as->lower[dim], proc_name,
+  dependency_fcn, 0);
+ if (front)
+   break;
+ if (sym->as->upper[dim]
+ && sym->as->upper[dim]->expr_type != EXPR_CONSTANT)
+   front = gfc_traverse_expr (sym->as->upper[dim], proc_name,
+  dependency_fcn, 0);
+ if (front)
+   break;
+   }
+   }
+
+  if (sym->ts.type == BT_CHARACTER
+ && sym->ts.u.cl && sym->ts.u.cl->length
+ && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
+   front = gfc_traverse_expr (sym->ts.u.cl->length, proc_name,
+  dependency_fcn, 0);

This can overwrite a previous front == true, right? Is this intended?

+}
+  return front;
+ }

The rest - besides the front-back confusion - looks fine to me. Thanks for
the
patch.

Regards,
 Andre

On Sun, 9 Jun 2024 07:14:39 +0100
Paul Richard Thomas  wrote:


Hi All,

The attached fixes a problem that, judging by the comments, has been

looked

at periodically over the last ten years but just looked to be too
fiendishly complicated to fix. This is not in small part because of the
confusing ordering of dummies in the tlink chain and the unintuitive
placement of all deferred initializations to the front of the init chain

in

the wrapped block.

The result of the existing ordering is that the initialization code for
non-dummy variables that depends on the function result occurs before any
initialization code for the function result itself. The fix ens