Re: [Patch, fortran] PR37336 finalization

2023-06-03 Thread Thomas Koenig via Gcc-patches

Hi Paul,


I want to get something approaching correct finalization to the
distros, which implies 12-branch at present. Hopefully I can do the
same with associate in a month or two's time.


OK by me then.

(I just wanted to be sure that we had this discussion :-)

Best regards

Thomas


Re: [Patch, fortran] PR37336 finalization

2023-06-03 Thread Harald Anlauf via Gcc-patches

Hi Paul, all,

On 6/3/23 15:16, Paul Richard Thomas via Gcc-patches wrote:

Hi Thomas,

I want to get something approaching correct finalization to the
distros, which implies 12-branch at present. Hopefully I can do the
same with associate in a month or two's time.


IMHO it is not only distros, but also installations at (scientific)
computing centers with a larger user base and a large software stack.
Migrating to a different major version of gcc/gfortran is not a trivial
task for them.

I'd fully support the idea of backporting the finalization fixes, as
IIUC this on the one hand touches a rather isolated part, and on the
other hand already got quite some testing.  It is also already in the
13-branch (or only mostly?).  Given that 12.3 was released recently
and 12.4 is far away, there'd be sufficient time to fix any fallout.

Regarding the associate fixes, we could get as much of those into 13.2,
which we'd normally expect in just a few months.  As long as spare time
to work on gfortran is limited, I'd rather prefer to get as much fixed
for that release.

(This is not a no: I simply expect that real regression testing for the
associate changes may take more time.)


I am dithering about changing the F2003/08 part of finalization since
the default is 2018 compliance. That said, it does need a change since
the suppression of constructor finalization is also suppressing
finalization of function results within the compilers. I'll do that
first, perhaps?


That sounds like a good idea.

Cheers,
Harald


Cheers

Paul



On Sat, 3 Jun 2023 at 06:50, Thomas Koenig  wrote:


Hi Paul,


I propose to backport
r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee to 12-branch very
soon.


Is this something that we usually do?

While finalization was basically broken before, some people still used
working subsets (or subsets that were broken, and they adapted or
wrote their code accordingly).

What is the general opinion on that?  I'm undecided.


Before that, I propose to remove the F2003/2008 finalization of
structure and array constructors in 13- and 14-branches. I can see why
it was removed from the standard in a correction to F2008 and think
that it is likely to cause endless confusion and maintenance
complications. However, finalization of function results within
constructors will be retained.


That, I agree with.  Should it be noted somewhere as an intentional
deviation from the standard?

Best regards

 Thomas




--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein





Re: [Patch, fortran] PR37336 finalization

2023-06-03 Thread Paul Richard Thomas via Gcc-patches
Hi Thomas,

I want to get something approaching correct finalization to the
distros, which implies 12-branch at present. Hopefully I can do the
same with associate in a month or two's time.

I am dithering about changing the F2003/08 part of finalization since
the default is 2018 compliance. That said, it does need a change since
the suppression of constructor finalization is also suppressing
finalization of function results within the compilers. I'll do that
first, perhaps?

Cheers

Paul



On Sat, 3 Jun 2023 at 06:50, Thomas Koenig  wrote:
>
> Hi Paul,
>
> > I propose to backport
> > r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee to 12-branch very
> > soon.
>
> Is this something that we usually do?
>
> While finalization was basically broken before, some people still used
> working subsets (or subsets that were broken, and they adapted or
> wrote their code accordingly).
>
> What is the general opinion on that?  I'm undecided.
>
> > Before that, I propose to remove the F2003/2008 finalization of
> > structure and array constructors in 13- and 14-branches. I can see why
> > it was removed from the standard in a correction to F2008 and think
> > that it is likely to cause endless confusion and maintenance
> > complications. However, finalization of function results within
> > constructors will be retained.
>
> That, I agree with.  Should it be noted somewhere as an intentional
> deviation from the standard?
>
> Best regards
>
> Thomas
>


--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Re: [Patch, fortran] PR37336 finalization

2023-06-03 Thread Steve Kargl via Gcc-patches
On Sat, Jun 03, 2023 at 07:50:19AM +0200, Thomas Koenig via Fortran wrote:
> Hi Paul,
> 
> > I propose to backport
> > r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee to 12-branch very
> > soon.
> 
> Is this something that we usually do?
> 
> While finalization was basically broken before, some people still used
> working subsets (or subsets that were broken, and they adapted or
> wrote their code accordingly).
> 
> What is the general opinion on that?  I'm undecided.
> 

I think a backport that fixes a bug that is a violation
of Fortran standard is always okay.  A backport of anything
else is up to the discretion of the contributor.  If pault
or you or harald or ... want to backport a patch, after all
these years, I think we should trust their judgement.

-- 
Steve


Re: [Patch, fortran] PR37336 finalization

2023-06-02 Thread Thomas Koenig via Gcc-patches

Hi Paul,


I propose to backport
r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee to 12-branch very
soon.


Is this something that we usually do?

While finalization was basically broken before, some people still used
working subsets (or subsets that were broken, and they adapted or
wrote their code accordingly).

What is the general opinion on that?  I'm undecided.


Before that, I propose to remove the F2003/2008 finalization of
structure and array constructors in 13- and 14-branches. I can see why
it was removed from the standard in a correction to F2008 and think
that it is likely to cause endless confusion and maintenance
complications. However, finalization of function results within
constructors will be retained.


That, I agree with.  Should it be noted somewhere as an intentional
deviation from the standard?

Best regards

Thomas



Re: [Patch, fortran] PR37336 finalization

2023-06-02 Thread Paul Richard Thomas via Gcc-patches
Hi All,

I propose to backport
r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee to 12-branch very
soon. Before that, I propose to remove the F2003/2008 finalization of
structure and array constructors in 13- and 14-branches. I can see why
it was removed from the standard in a correction to F2008 and think
that it is likely to cause endless confusion and maintenance
complications. However, finalization of function results within
constructors will be retained.

If there are any objections, please let me know.

Paul


Re: [Patch, fortran] PR37336 finalization

2023-03-07 Thread Steve Kargl via Gcc-patches
On Tue, Mar 07, 2023 at 03:58:32PM +0100, Thomas Koenig via Fortran wrote:
> Paul,
> 
> first of all, thank you very much indeed for the hard work you put into
> this!  This is a great step for gfortran.

Ditto**2

> > I can hurry this along to get the patch
> > into 13-branch or I can wait until 14-branch opens.
> 
> Personally, I think that this fixes so many bugs, and makes
> the compiler so much better, that I would prefer having it
> in gcc-13.  Finalization was only of very limited use before,
> and the risk of meaningful regressions (short of a build
> failure) is therefore very low.
> 

I agree with Thomas.  The main branch is in stage 4,
which is regression and documentation fixing mode.  I
would think the number of bugs fixed by your patch
can be argued as fixing regressions.  I can set aside 
some time on Saturday to help with a review (if required).

-- 
Steve


Re: [Patch, fortran] PR37336 finalization

2023-03-07 Thread Thomas Koenig via Gcc-patches

Paul,

first of all, thank you very much indeed for the hard work you put into
this!  This is a great step for gfortran.


I can hurry this along to get the patch
into 13-branch or I can wait until 14-branch opens.


Personally, I think that this fixes so many bugs, and makes
the compiler so much better, that I would prefer having it
in gcc-13.  Finalization was only of very limited use before,
and the risk of meaningful regressions (short of a build
failure) is therefore very low.

Again, thanks a lot!

Best regards

Thomas





Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-10 Thread Jerry D via Gcc-patches

For what it is worth.

On 2/10/22 11:49 AM, Harald Anlauf via Fortran wrote:

Hi Paul,

Am 10.02.22 um 13:25 schrieb Paul Richard Thomas via Fortran:

Conclusions on ifort:
(i) The agreement between gfortran, with the patch applied, and ifort is
strongest of all the other brands;
(ii) The disagreements are all down to the treatment of the parent
component of arrays of extended types: gfortran finalizes the parent
component as an array, whereas ifort does a scalarization. I have a 
patch

ready to do likewise.

Overall conclusions:
(i) Sort out whether or not derived type constructors are considered 
to be

functions;
(ii) Come to a conclusion about scalarization of parent components of
extended type arrays;
(iii) Check and, if necessary, correct the ordering of finalization in
intrinsic assignment of class arrays.
(iv) Finalization is difficult to graft on to existing pre-F2003 
compilers,

as witnessed by the range of implementations.

I would be really grateful for thoughts on (i) and (ii). My gut 
feeling, as

remarked in the submission, is that we should aim to be as close as
possible, if not identical to, ifort. Happily, that is already the case.


I am really sorry to be such a bother, but before we think we should
do the same as Intel, we need to understand what Intel does and whether
that is actually correct.  Or not inconsistent with the standard.
And I would really like to understand even the most simple, stupid case.

I did reduce testcase finalize_38.f90 to an almost bare minimum,
see attached, and changed the main to

  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)  :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

Note that "ThyType" is now a parameter.


- snip 
Ignore whether Thytype is  a Parameter.  Regardless Mytype and Mytype2 
are allocated upon the assignment.  Now if these are never used 
anywhere, it seems to me the deallocation can be done by the compiler 
anywhere after the last time it is used.  So it can be either after the 
PRINT statement before the end if the program or right after the 
assignment before your PRINT statements that examine the value of 
final_count.  I think the result is arbitrary/undefined in your reduced 
test case


I do not have the Intel compiler yet, so I was going to suggest see what 
it does if your test program prints something from within MyType and 
MyType2 after all your current print statements at the end.  Try this 
variation of the main program.


program test_final
  use testmode
  implicit none
  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)  :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

  print  *, MyType%ind, MyType2%ind, final_count
  deallocate(Mytype)
  print  *, MyType%ind, MyType2%ind, final_count
  deallocate(Mytype2)
  print  *, MyType%ind, MyType2%ind, final_count

end program test_final

I get with trunk:

$ ./a.out
 At start of program:    0
 After 1st allocation:    0
 After 2nd allocation:   0
  21 22   0
   0  22   1
   0  0 2

Which makes sense to me.

Regards,

Jerry


Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-10 Thread Harald Anlauf via Gcc-patches

Hi Paul,

Am 10.02.22 um 13:25 schrieb Paul Richard Thomas via Fortran:

Conclusions on ifort:
(i) The agreement between gfortran, with the patch applied, and ifort is
strongest of all the other brands;
(ii) The disagreements are all down to the treatment of the parent
component of arrays of extended types: gfortran finalizes the parent
component as an array, whereas ifort does a scalarization. I have a patch
ready to do likewise.

Overall conclusions:
(i) Sort out whether or not derived type constructors are considered to be
functions;
(ii) Come to a conclusion about scalarization of parent components of
extended type arrays;
(iii) Check and, if necessary, correct the ordering of finalization in
intrinsic assignment of class arrays.
(iv) Finalization is difficult to graft on to existing pre-F2003 compilers,
as witnessed by the range of implementations.

I would be really grateful for thoughts on (i) and (ii). My gut feeling, as
remarked in the submission, is that we should aim to be as close as
possible, if not identical to, ifort. Happily, that is already the case.


I am really sorry to be such a bother, but before we think we should
do the same as Intel, we need to understand what Intel does and whether
that is actually correct.  Or not inconsistent with the standard.
And I would really like to understand even the most simple, stupid case.

I did reduce testcase finalize_38.f90 to an almost bare minimum,
see attached, and changed the main to

  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)  :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

Note that "ThyType" is now a parameter.

I tested the above and found:

Intel:
 At start of program:0
 After 1st allocation:   1
 After 2nd allocation:   2

NAG 7.0:
 At start of program:  0
 After 1st allocation: 0
 After 2nd allocation: 0

Crayftn 12.0.2:
 At start of program:  2
 After 1st allocation: 2
 After 2nd allocation: 2

Nvidia 22.1:
 At start of program: 0
 After 1st allocation:0
 After 2nd allocation:0

So my stupid questions are:

- is ThyType invoking a constructor?  It is a parameter, after all.
  Should using it in an assignment invoke a destructor?  If so why?

  And why does Intel then increment the final_count?

- is the initialization of ThyType2 invoking a constructor?
  It might, if that is the implementation in the compiler, but
  should there be a finalization?

  Then ThyType2 is used in an intrinsic assignment, basically the
  same as the other one before.  Now what is the difference?

Are all compilers correct, but I do not see it?

Someone please help!


Best regards

Paul



Cheers,
Harald
module testmode
  implicit none

  type :: simple
 integer :: ind
  contains
final :: destructor1
  end type simple

  integer :: final_count = 0

contains

  subroutine destructor1(self)
type(simple), intent(inout) :: self
final_count = final_count + 1
  end subroutine destructor1

end module testmode

program test_final
  use testmode
  implicit none
  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)  :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

end program test_final


Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-10 Thread Paul Richard Thomas via Gcc-patches
Hi Harald,


I have run your modified version of finalize_38.f90, and now I see
> that you can get a bloody head just from scratching too much...
>
> crayftn 12.0.2:
>
>   1,  3,  1
>
 It appears that Cray interpret a derived type constructor as being a
function call and so "6 If a specification expression in a scoping unit
references a function, the result is finalized before execution of the
executable constructs in the scoping unit."
A call to 'test' as the first statement might be useful to diagnose: call
test(2, 0, [0,0], -10)

>   2,  21,  0
>
21 is presumably the value left over from simple(21) but quite why it
should happen in this order is not apparent to me.

>   11,  3,  2
>
I am mystified as to why the finalization of 'var' is not occurring because
"1 When an intrinsic assignment statement is executed (10.2.1.3), if the
variable is not an unallocated allocatable variable, it is finalized after
evaluation of expr and before the definition of the variable." Note the
double negative! 'var' has been allocated and should return 1 to 'scalar'

>   12,  21,  1
>   21,  4,  3
>
This is a residue of earlier differences in the final count.

>   23,  21,  22 | 42,  43
>
The value is inexplicable to me.

  31,  6,  4
>   41,  7,  5
>   51,  9,  7
>   61,  10,  8
>   71,  13,  10
>   101,  2,  1
>
One again, a function 'expr' finalization has been added after intrinsic
assignment; ie. derived type constructor == function.

>   102,  4,  3
>


>   111,  3,  2
>   121,  4,  2
>   122,  0,  4
>   123,  5,  6 | 2*0
>
>From the value of 'array', I would devine that the source in the allocation
is being finalized as an array, whereas I would expect each invocation of
'simple' to generate a scalar final call.

>   131,  5,  2
>   132,  0,  4
>   133,  7,  8 | 2*0
>
The final count has increased by 1, as expected.  The value of 'scalar' is
stuck at 0, so the second line is explicable. The array value is explicable
if the finalization is of 'expr' and that 'var' is not finalized or the
finalization of 'var' is occuring after assignment; ie. wrong order.
***I notice from the code that even with the patch, gfortran is finalizing
before evaluation of 'expr', which is incorrect. It should be after
evaluation of 'expr' and before the assignment.***

  141,  6,  3
>
Final count offset - OK

  151,  10,  5
>
The two extra calls come, I presume from the source in the allocation.
Since the type is extended, we see two finalizations each for the
allocation and the deallocation.

  161,  16,  9
>
 I think that the extra two finalizations come from the evaluation of 'src'
in 'constructor2'.

  171,  18,  11
>
Final count offset - OK

  175,  0.,  20. | 10.,  20.
>
The value of 'rarray' is mystifying.

Conclusions from Cray:
(i) Determine if derived type constructors should be interpreted as
function calls.
(ii) The order of finalization in class array assignment needs to be
checked and fixed if necessary.

>
> nagfor 7.0:
>
>   1 0 1
>
"1 When an intrinsic assignment statement is executed (10.2.1.3), if the
variable is not an unallocated allocatable variable, it is finalized after
evaluation of expr and before the definition of the variable."   So I think
that NAG has this wrong, either because the timing is right and an
unallocatable allocatable is being finalized or because the timing is wrong.

  11 1 2
>   23 21 22 | 42 43
>
It seems that the finalization is occurring after assignment.

  71 9 10
>   72 11 99
>
It seems that the finalization of the function 'expr' after assignment is
not happening.

  131 3 2
>   132 5 4
>
I am not sure that I know where the extra final call is nor where the
scalar value of 5 comes from.

  141 4 3
>   151 6 5
>   161 10 9
>   171 12 11
>
 The above are OK since there is an offset in the final count, starting at
131.

Conclusions from NAG:
(i) Some minor nits but pretty close to my interpretation.


Intel 2021.5.0:
>
>   131   3   2
>   132   0   4
>   133   5   6 |   0   0
>   141   4   3
>   151   7   5
>   152   3   0
>   153   0   0 |   1   3
> forrtl: severe (174): SIGSEGV, segmentation fault occurred
> [...]
>

ifort (IFORT) 2021.1 Beta 20201112 manages to carry on to the end.
 161  13   9
 162  20   0
 163   0   0 |  10  20
 171  14  11

Conclusions on ifort:
(i) The agreement between gfortran, with the patch applied, and ifort is
strongest of all the other brands;
(ii) The disagreements are all down to the treatment of the parent
component of arrays of extended types: gfortran finalizes the parent
component as an array, whereas ifort does a scalarization. I have a patch
ready to do likewise.

Overall conclusions:
(i) Sort out whether or not derived type constructors are 

Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-08 Thread Jerry D via Gcc-patches
Remember the days when reading very old cryptic Fortran code? Remember 
the fixed line lengths and cryptic variable names!


I fear the Standards committee has achieved history with the Standard 
itself it is so difficult to understand sometimes.


Cheers to Paul and Harald for digging on this.

Jerry

On 2/8/22 11:29 AM, Harald Anlauf via Fortran wrote:

Hi Paul,

Am 08.02.22 um 12:22 schrieb Paul Richard Thomas via Fortran:

Hi Harald,

Thanks for giving the patch a whirl.


the parent components as an array. I strongly suspect that, from 
reading

7.5.6.2 paragraphs 2 and 3 closely, that ifort has it right. However,

this

is another issue to come back to in the future.


Could you specify which version of Intel you tried?



ifort (IFORT) 2021.1 Beta 20201112


ok, that's good to know.



Testcase finalize_38.f90 fails for me with ifort 2021.5.0 with:

131

This test also fails with crayftn 11 & 12 and nagfor 7.0,
but in a different place.



I have run your modified version of finalize_38.f90, and now I see
that you can get a bloody head just from scratching too much...

crayftn 12.0.2:

 1,  3,  1
 2,  21,  0
 11,  3,  2
 12,  21,  1
 21,  4,  3
 23,  21,  22 | 42,  43
 31,  6,  4
 41,  7,  5
 51,  9,  7
 61,  10,  8
 71,  13,  10
 101,  2,  1
 102,  4,  3
 111,  3,  2
 121,  4,  2
 122,  0,  4
 123,  5,  6 | 2*0
 131,  5,  2
 132,  0,  4
 133,  7,  8 | 2*0
 141,  6,  3
 151,  10,  5
 161,  16,  9
 171,  18,  11
 175,  0.,  20. | 10.,  20.

nagfor 7.0:

 1 0 1
 11 1 2
 23 21 22 | 42 43
 71 9 10
 72 11 99
 131 3 2
 132 5 4
 141 4 3
 151 6 5
 161 10 9
 171 12 11

Intel 2021.5.0:

 131   3   2
 132   0   4
 133   5   6 |   0   0
 141   4   3
 151   7   5
 152   3   0
 153   0   0 |   1   3
forrtl: severe (174): SIGSEGV, segmentation fault occurred
[...]


That got me reading 7.5.6.3, where is says in paragraph 1:

"When an intrinsic assignment statement is executed (10.2.1.3), if the
variable is not an unallocated allocatable variable, it is finalized
after evaluation of expr and before the definition of the variable.
..."

Looking at the beginning of the testcase code (abridged):

  type(simple), allocatable :: MyType, MyType2
  type(simple) :: ThyType = simple(21), ThyType2 = simple(22)

! The original PR - one finalization of 'var' before (re)allocation.
  MyType = ThyType
  call test(1, 0, [0,0], 0)


This is an intrinsic assignment.

Naively I would expect MyType to be initially unallocated.

ThyType is not allocatable and non-pointer and cannot become
undefined here and would not play any role in finalization.

I am probably too blind-sighted to see why there should be
a finalization here.  What am I missing?

Could you use the attached version of finalize_38.f90 with crayftn 
and NAG?

All the stop statements are replaced with prints. Ifort gives:
  131   3   2
  132   0   4
  133   5   6 |   0   0
  141   4   3
  151   7   5
  152   3   0
  153   0   0 |   1   3
  161  13   9
  162  20   0
  163   0   0 |  10  20
  171  14  11


I think it is a good idea to have these prints in the testcase
whenever there is a departure from expectations.  So print?

Furthermore, for the sake of health of people reading the testcases
later, I think it would not harm to add more explanations why we
expect a certain behavior... ;-)


Best regards

Paul


Best regards,
Harald




Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-08 Thread Harald Anlauf via Gcc-patches

Hi Paul,

Am 08.02.22 um 12:22 schrieb Paul Richard Thomas via Fortran:

Hi Harald,

Thanks for giving the patch a whirl.



the parent components as an array. I strongly suspect that, from reading

7.5.6.2 paragraphs 2 and 3 closely, that ifort has it right. However,

this

is another issue to come back to in the future.


Could you specify which version of Intel you tried?



ifort (IFORT) 2021.1 Beta 20201112


ok, that's good to know.



Testcase finalize_38.f90 fails for me with ifort 2021.5.0 with:

131

This test also fails with crayftn 11 & 12 and nagfor 7.0,
but in a different place.



I have run your modified version of finalize_38.f90, and now I see
that you can get a bloody head just from scratching too much...

crayftn 12.0.2:

 1,  3,  1
 2,  21,  0
 11,  3,  2
 12,  21,  1
 21,  4,  3
 23,  21,  22 | 42,  43
 31,  6,  4
 41,  7,  5
 51,  9,  7
 61,  10,  8
 71,  13,  10
 101,  2,  1
 102,  4,  3
 111,  3,  2
 121,  4,  2
 122,  0,  4
 123,  5,  6 | 2*0
 131,  5,  2
 132,  0,  4
 133,  7,  8 | 2*0
 141,  6,  3
 151,  10,  5
 161,  16,  9
 171,  18,  11
 175,  0.,  20. | 10.,  20.

nagfor 7.0:

 1 0 1
 11 1 2
 23 21 22 | 42 43
 71 9 10
 72 11 99
 131 3 2
 132 5 4
 141 4 3
 151 6 5
 161 10 9
 171 12 11

Intel 2021.5.0:

 131   3   2
 132   0   4
 133   5   6 |   0   0
 141   4   3
 151   7   5
 152   3   0
 153   0   0 |   1   3
forrtl: severe (174): SIGSEGV, segmentation fault occurred
[...]


That got me reading 7.5.6.3, where is says in paragraph 1:

"When an intrinsic assignment statement is executed (10.2.1.3), if the
variable is not an unallocated allocatable variable, it is finalized
after evaluation of expr and before the definition of the variable.
..."

Looking at the beginning of the testcase code (abridged):

  type(simple), allocatable :: MyType, MyType2
  type(simple) :: ThyType = simple(21), ThyType2 = simple(22)

! The original PR - one finalization of 'var' before (re)allocation.
  MyType = ThyType
  call test(1, 0, [0,0], 0)


This is an intrinsic assignment.

Naively I would expect MyType to be initially unallocated.

ThyType is not allocatable and non-pointer and cannot become
undefined here and would not play any role in finalization.

I am probably too blind-sighted to see why there should be
a finalization here.  What am I missing?


Could you use the attached version of finalize_38.f90 with crayftn and NAG?
All the stop statements are replaced with prints. Ifort gives:
  131   3   2
  132   0   4
  133   5   6 |   0   0
  141   4   3
  151   7   5
  152   3   0
  153   0   0 |   1   3
  161  13   9
  162  20   0
  163   0   0 |  10  20
  171  14  11


I think it is a good idea to have these prints in the testcase
whenever there is a departure from expectations.  So print?

Furthermore, for the sake of health of people reading the testcases
later, I think it would not harm to add more explanations why we
expect a certain behavior... ;-)


Best regards

Paul


Best regards,
Harald


Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-08 Thread Paul Richard Thomas via Gcc-patches
Hi Harald,

Thanks for giving the patch a whirl.


> the parent components as an array. I strongly suspect that, from reading
> > 7.5.6.2 paragraphs 2 and 3 closely, that ifort has it right. However,
> this
> > is another issue to come back to in the future.
>
> Could you specify which version of Intel you tried?
>

ifort (IFORT) 2021.1 Beta 20201112

>
> Testcase finalize_38.f90 fails for me with ifort 2021.5.0 with:
>
> 131
>

That's the point where the interpretation of the standard diverges. Ifort
uses the scalar finalization for the parent component, whereas gfortran
uses the rank 1. Thus the final count is different by one. I have a version
of the patch, where gfortran behaves in the same way as ifort.


> This test also fails with crayftn 11 & 12 and nagfor 7.0,
> but in a different place.
>



>
> (Also finalize_45.f90 fails with that version with something that
> looks like memory corruption, but that might be just a compiler bug.)
>

I take it 'that version' is of ifort? Mine does the same. I suspect that it
is one of the perils of using pointer components in such circumstances! You
will notice that I had to nullify pointer components when doing the copy.

>
> Thanks,
> Harald
>

Could you use the attached version of finalize_38.f90 with crayftn and NAG?
All the stop statements are replaced with prints. Ifort gives:
 131   3   2
 132   0   4
 133   5   6 |   0   0
 141   4   3
 151   7   5
 152   3   0
 153   0   0 |   1   3
 161  13   9
 162  20   0
 163   0   0 |  10  20
 171  14  11

Best regards

Paul
! { dg-do run }
!
! Test finalization on intrinsic assignment (F2018 (7.5.6.3))
!
module testmode
  implicit none

  type :: simple
integer :: ind
  contains
final :: destructor1, destructor2
  end type simple

  type, extends(simple) :: complicated
real :: rind
  contains
final :: destructor3, destructor4
  end type complicated

  integer :: check_scalar
  integer :: check_array(4)
  real :: check_real
  real :: check_rarray(4)
  integer :: final_count = 0

contains

  subroutine destructor1(self)
type(simple), intent(inout) :: self
check_scalar = self%ind
check_array = 0
final_count = final_count + 1
  end subroutine destructor1

  subroutine destructor2(self)
type(simple), intent(inout) :: self(:)
check_scalar = 0
check_array(1:size(self, 1)) = self%ind
final_count = final_count + 1
  end subroutine destructor2

  subroutine destructor3(self)
type(complicated), intent(inout) :: self
check_real = self%rind
check_array = 0.0
final_count = final_count + 1
  end subroutine destructor3

  subroutine destructor4(self)
type(complicated), intent(inout) :: self(:)
check_real = 0.0
check_rarray(1:size(self, 1)) = self%rind
final_count = final_count + 1
  end subroutine destructor4

  function constructor1(ind) result(res)
type(simple), allocatable :: res
integer, intent(in) :: ind
allocate (res, source = simple (ind))
  end function constructor1

  function constructor2(ind, rind) result(res)
class(simple), allocatable :: res(:)
integer, intent(in) :: ind(:)
real, intent(in), optional :: rind(:)
type(complicated), allocatable :: src(:)
integer :: sz
integer :: i
if (present (rind)) then
  sz = min (size (ind, 1), size (rind, 1))
  src  = [(complicated (ind(i), rind(i)), i = 1, sz)]
  allocate (res, source = src)
else
  sz = size (ind, 1)
  allocate (res, source = [(simple (ind(i)), i = 1, sz)])
end if
  end function constructor2

  subroutine test (cnt, scalar, array, off, rind, rarray)
integer :: cnt
integer :: scalar
integer :: array(:)
integer :: off
real, optional :: rind
real, optional :: rarray(:)
if (final_count .ne. cnt)  print *, 1 + off, final_count, cnt
if (check_scalar .ne. scalar) print *, 2 + off, check_scalar, scalar
if (any (check_array(1:size (array, 1)) .ne. array)) print *,  3 + off, &
   check_array(1:size (array, 1)), "|", array
if (present (rind)) then
  if (check_real .ne. rind)  print *,  4+off, check_real, rind
end if
if (present (rarray)) then
  if (any (check_rarray(1:size (rarray, 1)) .ne. rarray)) print *,  5 + off, &
   check_rarray(1:size (rarray, 1)), "|", rarray
end if
  end subroutine test

end module testmode

program test_final
  use testmode
  implicit none

  type(simple), allocatable :: MyType, MyType2
  type(simple), allocatable :: MyTypeArray(:)
  type(simple) :: ThyType = simple(21), ThyType2 = simple(22)
  class(simple), allocatable :: MyClass
  class(simple), allocatable :: 

Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-07 Thread Harald Anlauf via Gcc-patches

Hi Paul,

thanks for attacking this.

I haven't looked at the actual patch, only tried to check the new
testcases with other compilers.

Am 03.02.22 um 18:14 schrieb Paul Richard Thomas via Fortran:

I have tried to interpret F2018 7.5.6.2 and 7.5.6.3 as well as possible.
This is not always straightforward and has involved a lot of head
scratching! I have used the Intel compiler as a litmus test for the
outcomes. This was largely motivated by the observation that, in the user
survey conducted by Steve Lionel, gfortran and ifort are often used
together . Therefore, quite aside from wishing to comply with the standard
as far as possible, it is more than reasonable that the two compilers
comply. On application of this patch, only exception to this is the
treatment of finalization of arrays of extended types, where the Intel
takes "If the entity is of extended type and the parent type is
finalizable, the parent component is finalized" such that the parent
component is finalized one element at a time, whereas gfortran finalises
the parent components as an array. I strongly suspect that, from reading
7.5.6.2 paragraphs 2 and 3 closely, that ifort has it right. However, this
is another issue to come back to in the future.


Could you specify which version of Intel you tried?

Testcase finalize_38.f90 fails for me with ifort 2021.5.0 with:

131

This test also fails with crayftn 11 & 12 and nagfor 7.0,
but in a different place.

(Also finalize_45.f90 fails with that version with something that
looks like memory corruption, but that might be just a compiler bug.)

Thanks,
Harald


[Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization

2022-02-03 Thread Paul Richard Thomas via Gcc-patches
This patch has been an excessively long time in coming. Please accept my
apologies for that.

All but two of the PR37336 dependencies are fixed, The two exceptions are
PRs 59694 and 65347. The former involves lack of finalization of an
unreferenced entity declared in a block, which I am sure is trivial but I
cannot see where the missing trigger is, and the latter involves
finalization of function results within an array constructor, for which I
will submit an additional patch shortly.  PR104272 also remains, in which
finalization is occurring during allocation. I fixed this in one place but
it seems to have crept out in another :-)

Beyond this patch and ones for the three lagging PRs above, a thorough tidy
up and unification of finalization is needed. However, I will concentrate
on functionality in the first instance.

I have tried to interpret F2018 7.5.6.2 and 7.5.6.3 as well as possible.
This is not always straightforward and has involved a lot of head
scratching! I have used the Intel compiler as a litmus test for the
outcomes. This was largely motivated by the observation that, in the user
survey conducted by Steve Lionel, gfortran and ifort are often used
together . Therefore, quite aside from wishing to comply with the standard
as far as possible, it is more than reasonable that the two compilers
comply. On application of this patch, only exception to this is the
treatment of finalization of arrays of extended types, where the Intel
takes "If the entity is of extended type and the parent type is
finalizable, the parent component is finalized" such that the parent
component is finalized one element at a time, whereas gfortran finalises
the parent components as an array. I strongly suspect that, from reading
7.5.6.2 paragraphs 2 and 3 closely, that ifort has it right. However, this
is another issue to come back to in the future.

The work centred on three areas:
(i) Finalization on assignment:
This was required because finalization of the lhs was occurring at the
wrong time relative to evaluation of the rhs expression and was taking the
finalization of entities with finalizable components in the wrong order.
The changes in trans-array.cc (structure_alloc_comps) allow
gfc_deallocate_alloc_comp_no_caf to occur without finalization so that it
can be preceded by calls to the finalization wrapper. The other key change
in this area is the addition of trans-expr.cc
(gfc_assignment_finalizer_call), which manages the ordering of finalization
and deallocation.

(ii) Finalization of derived type function results.
Previously, finalization was not occuring at all for derived type results
but it did for class results. The former is now implemented in
trans-expr.cc (finalize_function_result), into which the treatment of class
finalization has been included. In order to handled complex expressions
correctly, an extra block has been included in gfc_se and is initialized in
gfc_init_se. This block accumulates the finalizations so that they can be
added at the right time. It is the way in which I will fix PR65347 (I have
already tested the principle).

(iii) Minor fixes
These include the changes in class.cc and the exclusion of artificial
entities from finalization.

There are some missing testcases (sorry Andrew and Sandro!), which might
not be necessary because the broken/missing features are already fixed. The
fact that the work correctly now is a strong indication that this is the
case.

Regtests OK on FC33/x86_64 - OK for mainline (and 11-branch)?

Best regards

Paul

Fortran:Implement missing finalization features [PR37336]

2022-02-02  Paul Thomas  

gcc/fortran
PR fortran/103854
* class.cc (has_finalizer_component): Do not return true for
procedure pointer components.

PR fortran/96122
* class.cc (finalize_component): Include the missing arguments
in the call to the component's finalizer wrapper.

PR fortran/37336
* class.cc (finalizer_insert_packed_call): Remove the redundant
argument in the call to the final subroutine.
* resolve.cc (resolve_where, gfc_resolve_where_code_in_forall,
gfc_resolve_forall_body, gfc_resolve_code): Check that the op
code is still EXEC_ASSIGN. If it is set lhs to must finalize.
* trans-array.cc (structure_alloc_comps): Add boolean argument
to suppress finalization and use it for calls from
gfc_deallocate_alloc_comp_no_caf. Otherwise it defaults to
false. Add a second, additional boolean argument to nullify
pointer components and use it in gfc_copy_alloc_comp_del_ptrs.
(gfc_alloc_allocatable_for_assignment): Suppress finalization
by setting new arg in call to gfc_deallocate_alloc_comp_no_caf.
(gfc_copy_alloc_comp_del_ptrs): New function.
* trans-array.h : Add the new boolean argument to the prototype
of gfc_deallocate_alloc_comp_no_caf with a default of false.
Add prototype for gfc_copy_alloc_comp_del_ptrs.
* trans-expr.cc (gfc_init_se): Initialize finalblock.
(finalize_function_result): New function that finalizes
function results in the correct order.
(gfc_conv_procedure_call): Use