Silverfrost Forums

Welcome to our forums

Perplexing bug in program (or compiler?)

19 Apr 2021 12:01 #27573

Mecej4, I modified your latest reproducer to produce both errors. Compile FTN95 /checkmate /link Run SDBG place breakpoints at lines 22 and 34 and run stop at 22 : looks ok stop at 34 : 1st > X(1) loop k to allow continue; incorrect bounds stop at 34 : 2nd > X(42) no 3rd stop showing integer overflow in call

MODULE mcs
  IMPLICIT NONE
  INTEGER, PARAMETER :: LRCGD1 = 19
  INTEGER :: NRN
  REAL, DIMENSION(:,:), ALLOCATABLE, SAVE :: app
END Module

Program HST3d
USE mcs
IMPLICIT NONE
NRN = 7
allocate(app(NRN,0:5))
CALL gcgris(app)
print *,app(3,0)
end Program

SUBROUTINE gcgris(ap)
  USE mcs
  IMPLICIT NONE
  REAL, DIMENSION(NRN,0:*), INTENT(IN OUT) :: ap
  integer :: L = 0
  CALL abmult( ap(1:NRN,0) )    ! > sdbg reports x(1) ; use do 1,1 to continue
  CALL abmult( ap )             ! > sdbg reports x(42)
  CALL abmult( ap(1,L) )        ! > sdbg reports integer overflow
end subroutine gcgris

SUBROUTINE abmult(x)
  USE mcs
  IMPLICIT NONE
  REAL, DIMENSION(*), INTENT(OUT) :: x
  INTEGER :: irn
  integer :: k = 0
!
  k = k+1
  write (*,*) 'at abmult',k
  DO irn=1,k ! nrn
     x(irn) = 0.1
  END DO
END SUBROUTINE abmult
21 Apr 2021 7:36 #27584

mecej4

Initial reactions.

  1. The code appears to run successfully when /CHECK is not used.

  2. For 32 bits, it fails when using /CHECK with array subscript out of bounds. This appears at first sight to be a false error report.

  3. For 64 bits, it appears to run successfully when /UNDEF is used but hangs completely with /FULL_UNDEF.

  4. I am doubtful about the validity of the Fortran. The use of INTENT means that interfaces are required but then NRN is declared in a module. So I suspect that the interfacing needs to be applied via the module and this would make more sense from a object orienting point of view.

  5. Then there is also the array APP that needs to be considered. It is declared in the module and passed as an argument to gcgris. But gcgris has direct access to APP via the USE statement.

My initial conclusion is that gcgris must be defined in the module and that abmult needs an interface.

21 Apr 2021 10:25 #27585

I don't now if my problem fits under this topic, but I'll give it a try. Using Silverfrost ftn95 for reactivating older Fortran programs which run in the 80s on an IBM 3032 Mainframe generally works fine, when replacing IBM specific commands/conventions. Currently, however, I'm stuck with program calculating matrix elements. What puzzles me is the fact, that the 32Bit-Version delivers different results compared with the results of the 64Bit-Version (I'm using Plato for compilation and SDBG version 8.70.00). Whereas the 32Bit-version produces correct results, the ones calculated with the 64Bit version are obvioulsy wrong. Trying to isolate the problem, kept me busy the last days, but is not so easy due to 20 subroutines and many function calls. Since I didn't succeed to isolate the root cause of the differences between the results of the 32- and 64-Bit versions up to now, I would like to ask the following questions: Did anybody experience similar deviations between results of 32- and 64-Bit versions? Can certain compiler options help to isolate the problem? Please note, that I have no experience with command line use of SDBG, but use the Plato environment. Best regards Theo

21 Apr 2021 10:58 #27586

Theo1002

Can I suggest that you copy this post to a new thread. Then I could make some recommendations. There is nothing to suggest that this is related to the current issue.

21 Apr 2021 12:59 (Edited: 21 Apr 2021 1:34) #27587

Paul,

Thanks for looking into the problem.

Perhaps I can show that it is not the absence of an interface that is causing problems by just modifying the reproducer, instead of invoking sections of the Fortran standard.

The following version contains the subroutines inside module MCS, so an interface is provided, whether or not one is required.

MODULE mcs
  IMPLICIT NONE
  INTEGER, PARAMETER :: LRCGD1 = 19
  INTEGER :: NRN
  REAL, DIMENSION(:,:), ALLOCATABLE, SAVE :: app
CONTAINS

SUBROUTINE gcgris(ap)
  IMPLICIT NONE
  REAL, DIMENSION(NRN,0:*), INTENT(IN OUT) :: ap
  CALL abmult(ap(1:NRN,0))
end subroutine gcgris

SUBROUTINE abmult(x)
  IMPLICIT NONE
  REAL, DIMENSION(*), INTENT(OUT) :: x
  INTEGER :: irn
!
  DO irn=1,nrn
     x(irn) = 0.1
  END DO
END SUBROUTINE abmult

END Module

Program HST3d
USE mcs
IMPLICIT NONE
NRN = 7
allocate(app(NRN,0:5))
CALL gcgris(app)
print *,app(3,0)
end Program

Using FTN95 8.71, latest DLLS80.

The following options lead to a normal run, printing '0.10000'

/debug /64 /debug /check /64 /undef /64

The following options cause the program to end abnormally:

/check : subscript out of bounds (X is incorrectly displayed as having a size of 1 in SDBG)

/full_undef /64: access violation, need to run inside SDBG64 to see details of violation.

Please note the inconsistency in the behaviours with /check /64 (normal) and /check (subscript bounds violation).

P.S. Apologies, I erred in copying and pasting in the code, with the result that the program was incomplete. I have corrected the code (I hope!).

21 Apr 2021 1:31 #27588

mecej4

I must be missing something. abmult is external to gcgris. abmult is called from gcgris and the compiler is not informed that abmult uses INTENT(OUT).

I don't doubt that FTN95 is not coping with this but I think that we need to start with well formed Fortran code.

21 Apr 2021 1:44 #27589

Paul, my apologies -- I had pasted in a piece of the OLD code instead of the complete NEW code. I have corrected the code.

Regarding INTENT, I think that the position taken by the Fortran standard is that keeping the code in conformity with stated INTENT is the programmer's responsibility. However, one of the strengths of FTN95 is its ability to help the errant programmer in such matters, and it is to catch errors of this type that I often turn to FTN95.

In fact many, many old Fortran programs, such as those in Alan Miller's repository (https://wp.csiro.au/alanmiller/), often declare output array arguments as INTENT(OUT), when only a part of the array will be updated in a subprogram. Until a few years ago, when Mr. Ian Hounam of NAG advised me to the contrary, I myself did not know that INTENT(OUT) meant that all elements of the array became undefined as soon as the subprogram was entered.

21 Apr 2021 3:14 #27591

mecej4

I suspect that DIMENSION(*) in abmult is incorrect. It means 'pass by size'.

It should be DIMENSION(:) which means 'pass by shape'.

Anyway this change appears to fix the problem.

I would also remove the * in gcgris and the SAVE.

21 Apr 2021 9:31 #27594

Quoted from PaulLaidler Theo1002

Can I suggest that you copy this post to a new thread. Then I could make some recommendations. There is nothing to suggest that this is related to the current issue.

O.K. Paul, I tried to do so. Unfortunately the source coude was cut off (maybe too long). I will try again tomorrow.

Please login to reply.