|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Sun Jan 09, 2022 2:19 pm Post subject: Using /checkmate does not help catch ASSIGNed GOTO bug |
|
|
The Assigned GOTO feature was deleted in Fortran 95, but FTN95 still supports that Fortran feature, and there are occasional old Fortran codes that we encounter in which it was used.
The Assigned GOTO is governed by some peculiar rules (see 7.1.1.3 of the Fortran 66 standard, https://wg5-fortran.org/ARCHIVE/Fortran66.pdf ). A variable of type integer may be assigned a statement number (including a Format statement number). That integer variable may no longer be used in contexts where an integer arithmetical value is expected. However, assigning a new integer value to it restores the status of the variable to that of a normal integer variable, and the variable may no longer be used in Assigned GOTO statements until it is set equal to a new statement number with an ASSIGN statement.
The following short code encapsulates a situation where FTN95 used with /CHECK or /CHECKMATE does not help to catch the bug.
Code: | program wicked
implicit none
integer pqr
data pqr/789/
!
10 print *,'pqr = ',pqr
if(pqr .gt. 10)then ! invalid comparison when PQR is a stmt.no.
assign 10 to pqr ! now the integer value of PQR is undefined
goto pqr
else
pqr = 1 ! now the stmt.no. value of PQR is undefined
endif
print *,pqr
end |
The resulting EXE, when run, loops until it is terminated with a ^C.
Using a single name (PQR) for an integer variable and a statement label was surely an invitation for trouble, and having the compiler issue a suitable warning would help in detecting and fixing bugs of this type -- such as:
Code: | PQR - both a numeric value and label assigned to this variable. |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Mon Jan 10, 2022 8:45 am Post subject: |
|
|
mecej4
Thank you for the feedback. I have logged this for investigation. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Jan 13, 2022 6:07 am Post subject: |
|
|
The following extended code demonstrates that ASSIGN allocates a memory address using FTN95 /32, pqr_10 = 4198492, pqr = 789 then 4198492
FTN95 /64 updates pqr with a value = 5614, associated with assign 10 to pqr. Not sure what 5612 is ?
pqr_10 = 5614, pqr = 789 then 5614
looks like "integer pqr" and "assign pqr" are the same variable.
Using gFortran (x64) in PLATO, the value of PQR does not appear to change, which could imply that "integer pqr" and "assign pqr" might be different, although pqr_10 does have a value ?
pqr_10 = 11, pqr = 789 and are unchanged for print, *
My recollection of use with other F77 compilers, you can't use "goto pqr" until "assign xx to pqr" has been performed. I am sure there would have been variability with this.
Code: | program wicked
implicit none
integer pqr, pqr_orig, pqr_10, pqr_1, num
data pqr, pqr_10 /789, 11 /
!
!z assign 798 to pqr
pqr_orig = pqr
assign 10 to pqr_10
!z assign 1 to pqr_1
num = 0
!
10 print *,'pqr = ',pqr, pqr_orig, pqr_10, num
num = num+1
if (pqr .gt. 10)then ! invalid comparison when PQR is a stmt.no.
assign 10 to pqr ! now the integer value of PQR is undefined
if ( num < 11 ) goto pqr
else
pqr = 1 ! now the stmt.no. value of PQR is undefined
endif
789 print *,pqr
end |
|
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Thu Jan 13, 2022 5:37 pm Post subject: |
|
|
Quote: | My recollection of use with other F77 compilers, you can't use "goto pqr" until "assign xx to pqr" has been performed. |
Agree. Similarly, one can't use "pqr = pqr+1", etc., when pqr is holding a statement label.
The code that I posted is in error. The problem is that the compiler seems unable to catch and flag the error.
As you surmised, the memory location assigned to PQR contains the address of a label, or an integer value. Here are pieces of the 32-bit assembly code.
Code: | 0006 10 print *,'pqr = ',pqr AT 20
00000020(16/3/9) Label __L10
...
0008 assign 10 to pqr ! now the integer value of PQR is undefined AT 8c
0000008c(46/5/34) lea eax,address of __L10
00000092(47/5/34) mov PQR,eax
0009 goto pqr AT 98
00000098(48/5/38) jmp *PQR
|
There appears to be no record kept as to whether the current value is an address or an integer.
The 64 bit version does things a bit differently. Instead of storing the address, which is 8 bytes long and too big to store in the 4 byte integer PQR, it subtracts the RBP register from the address, obtaining a 4 byte offset, which it stores in PQR. When the corresponding assigned GOTO is executed, it fetches the value from PQR, adds back RBP, and jumps to the resulting 8 byte address. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Tue Feb 08, 2022 4:46 pm Post subject: |
|
|
mecej4
This issue turns out to be rather tricky. I can make the sample program fault at the assignment "pqr = 1" but to get it to fault for the other invalid usage would be non-trivial.
However, this simple change causes our test suite to fail for 4 programs. Two are programming errors that are easily corrected but in the other two the variable is used consistently in different localities (in one part of the program the variable is used as a simple integer whilst in another independent part it is used as a label).
So there is a risk of breaking working legacy code. We can't make use of /ISO because ASSIGN is deleted and fails anyway. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue Feb 08, 2022 8:09 pm Post subject: |
|
|
Paul, we can live with being unable to catch ASSIGN related errors at run time, since it is a deleted feature of the language.
I looked at the cross-reference list generated for this program with /xref, hoping to see signs of the dual role played by the variable PQR, but that listing does not reveal that PQR has any relation to statement labels. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Tue Feb 08, 2022 8:15 pm Post subject: |
|
|
On further reflection I can provide a warning not an error then the user can upgrade it to an error if preferred. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|