forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Using /checkmate does not help catch ASSIGNed GOTO bug

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Sun Jan 09, 2022 2:19 pm    Post subject: Using /checkmate does not help catch ASSIGNed GOTO bug Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Jan 10, 2022 8:45 am    Post subject: Reply with quote

mecej4

Thank you for the feedback. I have logged this for investigation.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jan 13, 2022 6:07 am    Post subject: Reply with quote

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
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Thu Jan 13, 2022 5:37 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Feb 08, 2022 4:46 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Tue Feb 08, 2022 8:09 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Feb 08, 2022 8:15 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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