Re: [Patch, fortran] PR110987 and PR113885 - gimplifier ICEs and wrong results in finalization

2024-03-29 Thread Paul Richard Thomas
Hi Harald,

Thanks for the thumbs-up. Committed as
3c793f0361bc66d2a6bf0b3e1fb3234fc511e2a6.

I will backport to 13-branch in a couple of weeks.

Best regards

Paul


On Thu, 28 Mar 2024 at 22:27, Harald Anlauf  wrote:

> ...snip...
> yes, this looks good here.
>
> ...snip...

The patch looks rather "conservative" (read: safe) and appears to
> fix the regressions very well, so go ahead as planned.
>
> Thanks for the patch!
>
> Harald
>
>


Re: [Patch, fortran] PR110987 and PR113885 - gimplifier ICEs and wrong results in finalization

2024-03-28 Thread Harald Anlauf

Hi Paul,

Am 28.03.24 um 16:39 schrieb Paul Richard Thomas:

Hi All,

The attached patch has two elements:

(i) A fix for gimplifier ICEs with derived type having no components. The
reporter himself suggested (thanks Kirill!):

-  if (derived && derived->attr.zero_comp)
+  if (derived && (derived->components == NULL))

As far as I can tell, this is the correct fix. I tried setting
attr.zero_comp in resolve.cc for all the OK types without components but
this caused all sorts of fallout.

(ii) Final calls were occurring in the wrong place for finalizable
elemental function calls within scalarizer loops. This caused incorrect
results even for derived types with components. This is also fixed.


yes, this looks good here.


It should be noted that finalizer calls from the rhs of an assignment are
occurring at the wrong time, since F2018/24-7.5.6.3 requires:
"If an executable construct references a nonpointer function, the result is
finalized after execution of the innermost executable construct containing
the reference.", while in the present implementation, this happening just
before assignment to the lhs temporary. Fixing this is going to be really
tough and invasive, so I decided that getting the right results and the
correct number of finalization should be sufficient for the 14-branch
release. As it happens, I had been mulling over how to do this for
finalizations hidden in constructors and other contexts than assignment
(eg. write statements or allocation with source). It's a few months away
and will be appropriate for stage 1.

Regtests on x86_64 - OK for mainline and then, after a bit, for backporting
to 13-branch?


The patch looks rather "conservative" (read: safe) and appears to
fix the regressions very well, so go ahead as planned.

Thanks for the patch!

Harald


Regards to all

Paul

Fortran: Fix a gimplifier ICE/wrong result with finalization [PR104555]

2024-03-28  Paul Thomas  

gcc/fortran
PR fortran/36337
PR fortran/110987
PR fortran/113885
* trans-expr.cc (gfc_trans_assignment_1): Place finalization
block before rhs post block for elemental rhs.
* trans.cc (gfc_finalize_tree_expr): Check directly if a type
has no components, rather than the zero components attribute.
Treat elemental zero component expressions in the same way as
scalars.


gcc/testsuite/
PR fortran/113885
* gfortran.dg/finalize_54.f90: New test.
* gfortran.dg/finalize_55.f90: New test.

gcc/testsuite/
PR fortran/110987
* gfortran.dg/finalize_56.f90: New test.





[Patch, fortran] PR110987 and PR113885 - gimplifier ICEs and wrong results in finalization

2024-03-28 Thread Paul Richard Thomas
Hi All,

The attached patch has two elements:

(i) A fix for gimplifier ICEs with derived type having no components. The
reporter himself suggested (thanks Kirill!):

-  if (derived && derived->attr.zero_comp)
+  if (derived && (derived->components == NULL))

As far as I can tell, this is the correct fix. I tried setting
attr.zero_comp in resolve.cc for all the OK types without components but
this caused all sorts of fallout.

(ii) Final calls were occurring in the wrong place for finalizable
elemental function calls within scalarizer loops. This caused incorrect
results even for derived types with components. This is also fixed.

It should be noted that finalizer calls from the rhs of an assignment are
occurring at the wrong time, since F2018/24-7.5.6.3 requires:
"If an executable construct references a nonpointer function, the result is
finalized after execution of the innermost executable construct containing
the reference.", while in the present implementation, this happening just
before assignment to the lhs temporary. Fixing this is going to be really
tough and invasive, so I decided that getting the right results and the
correct number of finalization should be sufficient for the 14-branch
release. As it happens, I had been mulling over how to do this for
finalizations hidden in constructors and other contexts than assignment
(eg. write statements or allocation with source). It's a few months away
and will be appropriate for stage 1.

Regtests on x86_64 - OK for mainline and then, after a bit, for backporting
to 13-branch?

Regards to all

Paul

Fortran: Fix a gimplifier ICE/wrong result with finalization [PR104555]

2024-03-28  Paul Thomas  

gcc/fortran
PR fortran/36337
PR fortran/110987
PR fortran/113885
* trans-expr.cc (gfc_trans_assignment_1): Place finalization
block before rhs post block for elemental rhs.
* trans.cc (gfc_finalize_tree_expr): Check directly if a type
has no components, rather than the zero components attribute.
Treat elemental zero component expressions in the same way as
scalars.


gcc/testsuite/
PR fortran/113885
* gfortran.dg/finalize_54.f90: New test.
* gfortran.dg/finalize_55.f90: New test.

gcc/testsuite/
PR fortran/110987
* gfortran.dg/finalize_56.f90: New test.
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 76bed9830c4..079ac93aa8a 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -12511,11 +12511,14 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
   gfc_add_block_to_block (, );
   gfc_add_expr_to_block (, tmp);

-  /* Add the post blocks to the body.  */
-  if (!l_is_temp)
+  /* Add the post blocks to the body.  Scalar finalization must appear before
+ the post block in case any dellocations are done.  */
+  if (rse.finalblock.head
+  && (!l_is_temp || (expr2->expr_type == EXPR_FUNCTION
+			 && gfc_expr_attr (expr2).elemental)))
 {
-  gfc_add_block_to_block (, );
   gfc_add_block_to_block (, );
+  gfc_add_block_to_block (, );
 }
   else
 gfc_add_block_to_block (, );
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 7f50b16aee9..badad6ae892 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -1624,7 +1624,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
 }
   else if (derived && gfc_is_finalizable (derived, NULL))
 {
-  if (derived->attr.zero_comp && !rank)
+  if (!derived->components && (!rank || attr.elemental))
 	{
 	  /* Any attempt to assign zero length entities, causes the gimplifier
 	 all manner of problems. Instead, a variable is created to act as
@@ -1675,7 +1675,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
 	  final_fndecl);
   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
 {
-  if (is_class)
+  if (is_class || attr.elemental)
 	desc = gfc_conv_scalar_to_descriptor (se, desc, attr);
   else
 	{
@@ -1685,7 +1685,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
 	}
 }

-  if (derived && derived->attr.zero_comp)
+  if (derived && !derived->components)
 {
   /* All the conditions below break down for zero length derived types.  */
   tmp = build_call_expr_loc (input_location, final_fndecl, 3,
diff --git a/gcc/testsuite/gfortran.dg/finalize_54.f90 b/gcc/testsuite/gfortran.dg/finalize_54.f90
new file mode 100644
index 000..73d32b1b333
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_54.f90
@@ -0,0 +1,47 @@
+! { dg-do compile }
+! Test the fix for PR113885, where not only was there a gimplifier ICE
+! for a derived type 't' with no components but, with a component, gfortran
+! gave wrong results.
+! Contributed by David Binderman  
+!
+module types
+  type t
+   contains
+ final :: finalize
+  end type t
+contains
+  pure subroutine finalize(x)
+type(t), intent(inout) :: x
+  end subroutine finalize
+end module types
+
+subroutine test1(x)
+  use types
+  interface
+ elemental function elem(x)
+