Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization
Hi Harald, I have taken gcc-patches out of the loop for now :-) 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. > You are not being a bother. I am happy that you are taking an interest. snip > > 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? > > 7.5.6.3 When finalization occurs 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. If the variable is an allocated allocatable variable, or has an allocated allocatable subobject, that would be deallocated by intrinsic assignment, the finalization occurs before the deallocation. Your "stupid questions" are not at all stupid. The finalization of 'variable' that occurs in your testcase demonstrates that the finalization with my patch is occurring at the wrong time. I now see that NAG is correct on this. Please press on with the questions! Regards Paul
Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization
Hi Paul, Am 11.02.22 um 10:08 schrieb Paul Richard Thomas via Fortran: Your "stupid questions" are not at all stupid. The finalization of 'variable' that occurs in your testcase demonstrates that the finalization with my patch is occurring at the wrong time. I now see that NAG is correct on this. Please press on with the questions! Jerry's suggestion to add lots of prints turned out to be really enlightening with regard to observable behavior. I rewrote the testcase again and placed the interesting stuff into a subroutine. This way one can distinguish what actually happens during program start, entering and leaving a subroutine. I encountered the least surprises (= none) with NAG 7.0 here. For reference this is the output: At start of program : 0 Enter sub : 0 After 1st allocation: 0 After 2nd allocation: 0 Checking MyType% ind: 21 Checking MyType2%ind: 22 Deallocate MyType : 0 # Leave desctructor1: 1 21 * MyType deallocated: 1 (kept MyType2 for automatic deallocation on return from sub) Leave sub : 1 # Leave desctructor1: 2 22 After sub : 2 To make it short: the destructor is called only when deallocation occurs, either explicitly or automatically. Intel 2021.5.0: At start of program : 0 Enter sub : 0 # Leave desctructor1: 1 0 After 1st allocation: 1 # Leave desctructor1: 2 0 After 2nd allocation: 2 Checking MyType% ind: 21 Checking MyType2%ind: 22 Deallocate MyType : 2 # Leave desctructor1: 3 21 * MyType deallocated: 3 (kept MyType2 for automatic deallocation on return from sub) Leave sub : 3 # Leave desctructor1: 4 21 # Leave desctructor1: 5 22 # Leave desctructor1: 6 22 After sub : 6 So after entering the subroutine, the destructor is called twice, but for unknown reasons element ind, which I had expected to be either default-initialized to -1, or explicitly to 21 or 22, is 0. The places where this happens seem to be the assignments of MyType and MyType2. Furthermore, variable MyType is finalized on return from sub, although it is already deallocated, and MyType2 appears to get finalized twice automatically. I have no idea how this can get justified... Crayftn 12.0.2: in order to make the output easier to understand, I chose to reset final_count twice. This will become clear soon. # Leave desctructor1: 1, 20 At start of program : 1 +++ Resetting final_count for Cray Fortran : Version 12.0.2 # Leave desctructor1: 1, 21 # Leave desctructor1: 2, 22 Enter sub : 2 +++ Resetting final_count for Cray Fortran : Version 12.0.2 After 1st allocation: 0 After 2nd allocation: 0 Checking MyType% ind: -21 Checking MyType2%ind: 22 Deallocate MyType : 0 # Leave desctructor1: 1, -21 * MyType deallocated: 1 (kept MyType2 for automatic deallocation on return from sub) Leave sub : 1 # Leave desctructor1: 2, 22 After sub : 2 So it appears that Cray is calling the destructor for each declaration where a constructor is involved, or the like. Even if this is a parameter declaration, like in the main. Resetting the counter for the first time. On entering sub, I see now two finalizations before the first print. Resetting the counter for the second time. But then the assignments do not invoke finalization, where Intel did. So this part appears more like NAG, but... ... something is strange here: component ind is wrong after the first assignment. Looks clearly like a really bad bug. Explicit and automatic deallocation seems fine. Nvidia 22.2: At start of program :0 Enter sub :0 After 1st allocation:0 After 2nd allocation:0 Checking MyType% ind: 21 Checking MyType2%ind: 22 Deallocate MyType :0 # Leave desctructor1:1 21 * MyType deallocated:1 (kept MyType2 for automatic deallocation on return from sub) Leave sub :1 # Leave desctructor1:2 1590094384 # Leave desctructor1:3 22 After sub :3 OK, that is really odd. Although valgrind does not report invalid accesses, there is something really fishy here. I have not investigated further. Nvidia is out for now. One of the lessons learned is that it might be hard to write a portable testcase that works for all compilers that rightfully(?) can claim to implement finalization correctly... And I have only scratched the surface so far. Paul: do you think you can enhance your much more comprehensive testcase to ease debugging further? Cheers, Harald module testmode implicit none type :: simple integer :: ind = -1 contains final :: destructor1 end type simple
Re: [Patch, fortran] PR37336 (Finalization) - [F03] Finish derived-type finalization
Hi Harald and Jerry, I am reworking my way through, line by line wit F2018 in hand. Up to test with offset 70, NAG looks to be right. I introduced an assignment with a direct by ref function call, which doesn't finalise at the moment. Class entities are yet to come. I'll report back early next week. Thanks for all the help. I have (re)learned to read the standard very carefully. Best regards Paul On Fri, 11 Feb 2022, 21:08 Harald Anlauf, wrote: > Hi Paul, > > Am 11.02.22 um 10:08 schrieb Paul Richard Thomas via Fortran: > > Your "stupid questions" are not at all stupid. The finalization of > > 'variable' that occurs in your testcase demonstrates that the > finalization > > with my patch is occurring at the wrong time. I now see that NAG is > correct > > on this. > > > > Please press on with the questions! > > Jerry's suggestion to add lots of prints turned out to be really > enlightening with regard to observable behavior. I rewrote the > testcase again and placed the interesting stuff into a subroutine. > This way one can distinguish what actually happens during program > start, entering and leaving a subroutine. > > I encountered the least surprises (= none) with NAG 7.0 here. > For reference this is the output: > > At start of program : 0 > > Enter sub : 0 > After 1st allocation: 0 > After 2nd allocation: 0 > Checking MyType% ind: 21 > Checking MyType2%ind: 22 > Deallocate MyType : 0 > # Leave desctructor1: 1 21 > * MyType deallocated: 1 > (kept MyType2 for automatic deallocation on return from sub) > Leave sub : 1 > # Leave desctructor1: 2 22 > > After sub : 2 > > To make it short: the destructor is called only when deallocation > occurs, either explicitly or automatically. > > > Intel 2021.5.0: > > At start of program : 0 > > Enter sub : 0 > # Leave desctructor1: 1 0 > After 1st allocation: 1 > # Leave desctructor1: 2 0 > After 2nd allocation: 2 > Checking MyType% ind: 21 > Checking MyType2%ind: 22 > Deallocate MyType : 2 > # Leave desctructor1: 3 21 > * MyType deallocated: 3 > (kept MyType2 for automatic deallocation on return from sub) > Leave sub : 3 > # Leave desctructor1: 4 21 > # Leave desctructor1: 5 22 > # Leave desctructor1: 6 22 > > After sub : 6 > > So after entering the subroutine, the destructor is called twice, > but for unknown reasons element ind, which I had expected to be > either default-initialized to -1, or explicitly to 21 or 22, is 0. > The places where this happens seem to be the assignments of > MyType and MyType2. > > Furthermore, variable MyType is finalized on return from sub, > although it is already deallocated, and MyType2 appears to > get finalized twice automatically. > > I have no idea how this can get justified... > > > Crayftn 12.0.2: in order to make the output easier to understand, > I chose to reset final_count twice. This will become clear soon. > > # Leave desctructor1: 1, 20 > > At start of program : 1 > +++ Resetting final_count for Cray Fortran : Version 12.0.2 > > # Leave desctructor1: 1, 21 > # Leave desctructor1: 2, 22 > Enter sub : 2 > +++ Resetting final_count for Cray Fortran : Version 12.0.2 > After 1st allocation: 0 > After 2nd allocation: 0 > Checking MyType% ind: -21 > Checking MyType2%ind: 22 > Deallocate MyType : 0 > # Leave desctructor1: 1, -21 > * MyType deallocated: 1 > (kept MyType2 for automatic deallocation on return from sub) > Leave sub : 1 > # Leave desctructor1: 2, 22 > > After sub : 2 > > So it appears that Cray is calling the destructor for each declaration > where a constructor is involved, or the like. Even if this is a > parameter declaration, like in the main. Resetting the counter for > the first time. > > On entering sub, I see now two finalizations before the first print. > Resetting the counter for the second time. > > But then the assignments do not invoke finalization, where Intel did. > So this part appears more like NAG, but... > > ... something is strange here: component ind is wrong after the > first assignment. Looks clearly like a really bad bug. > > Explicit and automatic deallocation seems fine. > > > Nvidia 22.2: > > At start of program :0 > > Enter sub :0 > After 1st allocation:0 > After 2nd allocation:0 > Checking MyType% ind: 21 > Checking MyType2%ind: 22 > Deallocate MyType :0 > # Leave desctructor1:1 21 > * MyType deallocated:1 > (kept MyType2 for automatic deallocation on return from sub) > Leave sub :1 > # Leave desctructor1