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 

Allocatable arrays and ENTRY not compiled correctly

 
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: 941

PostPosted: Tue Mar 27, 2018 8:02 pm    Post subject: Allocatable arrays and ENTRY not compiled correctly Reply with quote

The following test program displays a bug in the way that FTN95 compiles a subroutine that contains a local (unsaved) allocatable array and an ENTRY statement in a subroutine. This bug caused a failure in one of the UKRMOL codes ( https://ccpforge.cse.rl.ac.uk/gf/project/ukrmol-in/ ).

Code:
program probe
call subb()
end program

subroutine suba()
real, allocatable :: x(:)
real :: y
!
allocate (x(4))
call random_number(x)
return
!
ENTRY subb
if(allocated(x))then
   y=sum(x)
   print *,y
end if
return
end subroutine


Since SUBA was never called, the array X is never allocated and so SUBB should return without doing anything. Even if SUBA had been called, according to the Fortran standard X would have been automatically deallocated when RETURN was executed. Therefore, when SUBB is entered, X should always be deallocated.

Compiled with /check, the program executes the PRINT statement (it should not have done so) and exhibits an access violation in a call to __DEALLOCATE from line-18. Similar errors occur with combinations of /check, /checkmate and /64.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1972
Location: Sydney

PostPosted: Wed Mar 28, 2018 2:56 am    Post subject: Reply with quote

There have been (probably earlier Ver5 to 7 ) problems using ALLOCATE and /CHECK where DEALLOCATE did not release the memory, but I thought with recent versions that memory management in /CHECK had changed.

I have now tried the following change to see what was happening:

Code:
! probe.f90
program probe
call subb()
end program

subroutine suba()
real, allocatable :: x(:)
real :: y
logical :: al
!
allocate (x(4))
call random_number(x)
return
!
ENTRY subb
al = allocated (x)
if(allocated(x))then
   y=sum(x)
   print *,y
end if
return
end subroutine


When compiled and run using:
ftn95 probe /debug /link
sdbg probe with a few F7's

This shows that variable al is .false. and the program runs ok
Without "al= allocated(x)", there is a compiler bug in the way the if(...) is managed.
Not sure what the problem is but using "al =allocated(x)" shifted the problem ?

It is a strange routine

John
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 941

PostPosted: Wed Mar 28, 2018 3:41 am    Post subject: Reply with quote

I observed that the crashes occurred at the RETURN statement. Your test indicates that there is something else afoot. Perhaps, there are two out-of-sync lists of allocatable variables and their status?

Did you build with the new 8.3 compiler?

It is rather odd to see allocated variables and ENTRY statements in the same subprogram. The UKRMOL code shows signs of having been ported from old Fortran (comments in the code that indicate that conversion to F90 was performed with the help of SPAG).
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1972
Location: Sydney

PostPosted: Wed Mar 28, 2018 7:09 am    Post subject: Re: Reply with quote

mecej4 wrote:
Did you build with the new 8.3 compiler?

No, I am still using Ver 8.20.

I switched to Ver 8.10 and the code with logical al. This appears to work ok.

I then commented out the line :
!al = allocated (x)
this appears to work ok

I then also commented out the line :
!logical :: al
this FAILS.

There must be a strange address pointer for the ENTRY for this case.

UKRMOL code must be F90 code and not F95. I wonder what else is in store ?

Hope this helps
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Wed Mar 28, 2018 7:47 am    Post subject: Reply with quote

I have made a note that this needs investigating.
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 941

PostPosted: Wed Mar 28, 2018 3:13 pm    Post subject: Reply with quote

Another clue regarding what the compiler does is the following. When the code in the first post is compiled with /checkmate and run, the EXE crashes with "reference to undefined variable, array element or function result" on Line-13. That is a bit odd, since Line-13 contains only the ENTRY statement. I suspect that the reported line number is off, and that it is the next line that caused the "undefined" error message.

If we take Line-14 as the actual line on which the error was detected, we have another puzzle. The message seems to indicate that the compiler thinks that the array x should be allocated and its elements defined in order to evaluate the logical expression ALLOCATED(x).
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 941

PostPosted: Tue May 01, 2018 12:27 pm    Post subject: Reply with quote

Further analysis shows exactly how the bug gets created. Here is a simplified test code. The subroutine may be invoked by either the subroutine name, "SUB" or the entry name, "SUBA". Since the ENTRY statement comes immediately after the declarations and there are no subroutine arguments, there should be no difference in behavior when either SUB or SUBA gets called. In particular, when the subroutine is entered, the array x(:) is unallocated.
Code:
program probe
call suba()
end program

subroutine sub()
real, allocatable :: x(:)
real :: y
!
ENTRY suba
if(allocated(x))then
   y=sum(x)
   print *,y
end if
return
end subroutine

The bug is seen clearly in the assembly code. The crucial initialisation of the address of X to 00000000 is performed only if SUB is called, and goes missing when SUBA is called.
Code:
   0005   subroutine sub()                                                                       AT 0
 ; Start of SUBROUTINE SUB
      00000000(21/1/8)           push      ebp
      00000001(22/1/8)           mov       ebp,esp
      00000003(23/1/8)           push      ebx
      00000004(24/1/8)           push      esi
      00000005(25/1/8)           push      edi
      00000006(26/1/8)           push      eax
      00000007(27/1/8)           sub       esp,=32           ; Adjusted later if temporaries allocated
   0006   real, allocatable :: x(:)                                                              AT d
WARNING - Variable X has been used without being given an initial value
      0000000d(28/4/19)          mov       X,=0   ; <<<<<<=======
   0007   real :: y                                                                              AT 14
   0008   !                                                                                      AT 14
   0009   ENTRY suba                                                                             AT 14
      00000014(29/4/20)          jmp       __N3
                                                             ; Start of ENTRY SUBA
      00000019(31/4/20)          push      ebp
      0000001a(32/4/20)          mov       ebp,esp
      0000001c(33/4/20)          push      ebx
      0000001d(34/4/20)          push      esi
      0000001e(35/4/20)          push      edi
      0000001f(36/4/20)          push      eax               ; To align ESP on 8 bytes
      00000020(37/4/20)          sub       esp,=32           ; Adjusted later if temporaries allocated
      00000026(38/4/20)       Label     __N3
   0010   if(allocated(x))then                                                                   AT 26
      00000026(39/5/30)          test      X,=-1

As a result of the failure to set the address of X, the allocation status of the allocatable variable is undefined if the entry SUBA is called. This is in violation of the Fortran 95 and later standards.

The warning (regarding X being used without being given an initial value) is, strictly speaking, incorrect.

The same kind of behavior also occurs when /64 is used.
Back to top
View user's profile Send private message
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