View previous topic :: View next topic |
Author |
Message |
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue Mar 27, 2018 8:02 pm Post subject: Allocatable arrays and ENTRY not compiled correctly |
|
|
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 have a status of 'not allocated'.
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.
Last edited by mecej4 on Thu Nov 22, 2018 1:10 pm; edited 1 time in total |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Mar 28, 2018 2:56 am Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Wed Mar 28, 2018 3:41 am Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Mar 28, 2018 7:09 am Post subject: Re: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Wed Mar 28, 2018 7:47 am Post subject: |
|
|
I have made a note that this needs investigating. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Wed Mar 28, 2018 3:13 pm Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue May 01, 2018 12:27 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Mon May 25, 2020 12:50 pm Post subject: |
|
|
This bug has now been fixed for the next release of FTN95. |
|
Back to top |
|
|
|