Fortran EQUIVALENCE statement with array length from subroutine input

373 Views Asked by At

I'm modernizing some old Fortran code and I cannot get rid of an equivalence statement somewhere (long story short: it's mixed use is so convoluted it'd take too much work to convert everything).

I need the length of the EQUIVALENCEd arrays to depend on some input, like the following code:

program test_equivalence                                                
      implicit none                                                     

      type :: t1                                                        
          integer :: len = 10                                           
      end type t1                                                       

      type(t1) :: o1                                                    


      call eqv_int(o1%len)                                              
      call eqv(o1)                                                      

      return                                                 

      contains                                                          
          subroutine eqv_int(len)                                       
             integer, intent(in) :: len                                 
             integer :: iwork(len*2)                                    
             real(8) :: rwork(len)                                      
             equivalence(iwork,rwork)                                   

             print *, 'LEN = ',len                                      
             print *, 'SIZE(IWORK) = ',size(iwork)                      
             print *, 'SIZE(RWORK) = ',size(rwork)                      
          end subroutine eqv_int                                        

          subroutine eqv(o1)                                            
             type(t1), intent(in) :: o1                                 

             integer :: iwork(o1%len*2)                                 
             real(8) :: rwork(o1%len)                                   
             equivalence(iwork,rwork)                                   

             print *, 'LEN = ',o1%len                                   
             print *, 'SIZE(IWORK) = ',size(iwork)                      
             print *, 'SIZE(RWORK) = ',size(rwork)                      
          end subroutine eqv                                            
end program test_equivalence                                            

This program will create 0-length arrays with gfortran 9.2.0. This is the output:

 LEN =           10
 SIZE(IWORK) =            0
 SIZE(RWORK) =            0

 LEN =           10
 SIZE(IWORK) =            0
 SIZE(RWORK) =            0

The same code will return Array 'rwork' at (1) with non-constant bounds cannot be an EQUIVALENCE object when compiled with gfortran 5.3.0, the warning disappears since gfortran 6.2.0, but the size of the arrays is always 0. So maybe compiler bug?

1

There are 1 best solutions below

11
francescalus On

The source code is indeed not a valid Fortran program. To be specific, it violates the numbered constraint C8106 of Fortran 2018:

An equivalence-object shall not be a designator with a base object that is .. an automatic data object ..

Being a numbered constraint, the compiler must be capable of detecting this violation. If hasn't such a capability this is a deficiency in the compiler (a bug). Being "capable" doesn't mean doing so by default, so please look carefully to see whether there are options which do lead to this detection. Someone familiar with the internals of GCC can give further detail here.

As the source isn't a valid Fortran program, the compiler is allowed to consider the arrays of size zero if it has skipped the violation detection.