Search code examples
fortrangfortran

Gfortran type mismatch error despite "-fallow-argument-mismatch" flag


Gfortran 10 added the default behavior to make type mismatches an error instead of a warning. The flag -fallow-argument-mismatch can be used to degrade the errors to warnings. However, within the same fortran file and using gcc 13 with the -fallow-argument-mismatch, gfortran fires a few warnings (as expected) and one error here:

call test(ter,file,0,'legacy')

                                                      
subroutine test(ander,file,mmr,status)                                                                                                                    
  implicit none
  integer(kind=8) :: mmr
                ....                                                                                                                                                                                   

Why is this particular mismatch different in a way that it is not considered a warning?

I could fix this by doing:

call test(ter,file,INT8(0),'legacy')

However, I thought this was the reason of using -fallow-argument-mismatch at compile time. My compilation command is as follow:

gfortran -mfma -O3 -m64 -Ofast -ftree-vectorize -ftree-vectorizer-verbose=0 -fPIC -ffree-form -ffree-line-length-none -fallow-invalid-boz -fallow-argument-mismatch -fbackslash -fno-fast-math -c mem.f90 -o mem.o 

What is expected in mmr is an integer 0,1,>1 or <0.


Solution

  • Type mismatches are a violation of the Fortran standard's restriction on program units. A compiler is not required to be able to detect and report such violations, but may choose to.

    Consider the (non-Fortran) program:

    program broken
      implicit none(external)
      external sub
    
      call sub(1)
      call sub(1.)
    end program
    

    This violates the Fortran standard's (long standing) rules on procedure references and many compilers will tell you that. Starting in GCC 10, gfortran complains about this by default and provides the option -fallow-argument-mismatch to allow the many broken Fortran sources to still be compiled, just like earlier versions of gfortran compiled them.1

    The -fallow-argument-mismatch option is described as:

           -fallow-argument-mismatch
               Some code contains calls to external procedures with
               mismatches between the calls and the procedure
               definition, or with mismatches between different
               calls. Such code is non-conforming, and will usually
               be flagged wi1th an error.  This options degrades the
               error to a warning, which can only be disabled by
               disabling all warnings vial -w.  Only a single
               occurrence per argument is flagged by this warning.
               -fallow-argument-mismatch is implied by -std=legacy.
    

    Note "external".

    The non-Fortran source

    program brokeninternal
      implicit none
    
      call sub(1)
    
    contains
      subroutine sub(x)
        real x
      end subroutine sub
    
    end program brokeninternal
    

    has a type mismatch and no use of -fallow-argument-mismatch is going to let you get away with it. The procedure sub is internal, thus having an explicit interface2; compilers have used explicit interfaces for yonks to check arguments. The type of "yonks" which goes back to when explicit interfaces came to be. There's no legacy of missing diagnostics or illegal-but-useful use to support.


    1 Violation of the Fortran standard or not, such broken Fortran programs are useful. Other Fortran compilers which have complained for ages still let users insist on compiling them.

    2 An external procedure may have an explicit interface, and -fallow-argument-mismatch will not allow such mis-matching. gfortran can (now) detect characteristic mismatches with an implicit interface in some cases, notably when the external procedure is defined in the same file as the place referencing it, and -fallow-argument-mismatch may have an effect.