Bug 30902 - gfortran produces wrong result with code using generic interface block
Summary: gfortran produces wrong result with code using generic interface block
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-21 06:37 UTC by Deji Akingunola
Modified: 2007-02-21 15:13 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
testcase (669 bytes, text/plain)
2007-02-21 06:38 UTC, Deji Akingunola
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Deji Akingunola 2007-02-21 06:37:16 UTC
The attached test code using a generic interface block produces wrong output when compiled with gfortran, and works fine with pgf90. Tested with gcc trunk and gcc-4.2.0

>>
[deji@agape test4]$ ~/Desktop/gcc-trunk/bin/gfortran --version
GNU Fortran 95 (GCC) 4.3.0 20070220 (experimental)
Copyright (C) 2006 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING

[deji@agape test4]$ ~/Desktop/gcc-trunk/bin/gfortran -static test-interface.f90 -o test1
[deji@agape test4]$ ./test1
   180.0000      1.5000001E-06  1.6066065E+34
   180.0000      1.5000001E-06  4.5916347E-41
   180.0000      1.5000001E-06  1.6066065E+34
   180.0000      1.5000001E-06  4.5916347E-41
   180.0000      1.5000001E-06   0.000000    
   180.0000      1.5000001E-06   0.000000    
   180.0000      1.5000001E-06  5.8780253E-39
   180.0000      1.5000001E-06   0.000000    
   180.0000      1.5000001E-06  1.6066927E+34
   180.0000      1.5000001E-06  4.5916347E-41
   180.0000      1.5000001E-06  0.5104298    
[deji@agape test4]$ pgf90 test-interface.f90 -o test1
[deji@agape test4]$ ./test1
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
    180.0000       1.5000001E-06   0.5104298    
FORTRAN STOP
<<
Comment 1 Deji Akingunola 2007-02-21 06:38:09 UTC
Created attachment 13081 [details]
testcase
Comment 2 Tobias Burnus 2007-02-21 07:33:37 UTC
(In reply to comment #0)
> The attached test code using a generic interface block produces wrong output
> when compiled with gfortran, and works fine with pgf90.

I think both compilers are right; or to be more precise: The program is wrong/undefined.

If one removes the INTERFACE blocks and puts the subroutines into below a CONTAINS in the main program, gfortran gives the following error:


      call adsorb(tsl, gamm, adwat, wsc, dime = ns, mode = 1)
                 1
Error: Type/rank mismatch in argument 'te' at (1)

The actual argument "tsl" is REAL, DIMENSION(10);
the dummy argument "te" is REAL, INTENT(IN)  :: gam, te

Analogously for gam(m) and adwat/adsor.

Thus: The compiler expects in the main program that it has to pass an array, but the routine only accepts a single real.

What happens in your program is now highly platform and compiler dependent:
pgf90 seems to set all values to "0.5104298" (but I wouldn't rely on this happening all the times), gfortran has seemingly "0.5104298" in adwat(10) only. (The rest is uninitialized.) And ifort/g95 have for the whole array adwat(:) uninitialized values.

By the way, NAG f95 detects the interface/procedure mismatch also for the original program as the interface and the subroutines are in the same file. This same-file error detection is also planed for gfortran.
Comment 3 Paul Thomas 2007-02-21 08:51:09 UTC
(In reply to comment #2)
> (In reply to comment #0)

> By the way, NAG f95 detects the interface/procedure mismatch also for the
> original program as the interface and the subroutines are in the same file.
> This same-file error detection is also planed for gfortran.
> 

K'aro Deji,

Or, more succinctly, the array in the interface is assumed shape, dimension (:), whereas you have an automatic array in the subroutine.

Change to

   SUBROUTINE adsorb2(te, gam, adsor, scl, dqdt, dime, mode)

      IMPLICIT NONE

      INTEGER, INTENT(IN) :: mode, dime
      REAL, INTENT(IN), DIMENSION(:)  :: gam, te
      REAL, INTENT(OUT), DIMENSION(:) :: adsor
      REAL, DIMENSION(:), OPTIONAL    :: dqdt, scl
      REAL, DIMENSION(dime) :: kstar, param
      REAL :: rhog, rgasv

and your program will work fine.

As Tobias says, we will be adding the means to diagnose this, just as soon as yours truly gets some time:)

I would strongly recommend that your regroup your subroutiens and the interface into a module, thusly:

module adsorbers
  interface adsorb
    module procedure adsorb, adsorb2
  end interface adsorb
contains

   SUBROUTINE adsorb2(te, gam, adsor, scl, dqdt, dime, mode)

      IMPLICIT NONE

      INTEGER, INTENT(IN) :: mode, dime
      REAL, INTENT(IN), DIMENSION(:)  :: gam, te
      REAL, INTENT(OUT), DIMENSION(:) :: adsor
      REAL, DIMENSION(:), OPTIONAL    :: dqdt, scl
      REAL, DIMENSION(dime) :: kstar, param
      REAL :: rhog, rgasv
      REAL, PARAMETER :: as = 1.7E4, mi = 2.84E-7, ko = 7.54E-9, re = 0.4734

      rhog  = 1650.0
      rgasv = 0.461510E+03

      kstar = ko * exp(2697.2 / te)
      param = kstar * gam * rgasv * te
      adsor = rhog * as * mi * (param / (1.0 + param))**re

      if (mode == 2) return

      scl = re * adsor / ((1.0 + param) * gam)

      if (mode == 1) return

       dqdt = re * adsor * (te-2697.2) / ((1.0 + param)*te*te)

      RETURN
   END SUBROUTINE adsorb2

   SUBROUTINE adsorb(te, gam, adsor, scl, dqdt, dime, mode)

      IMPLICIT NONE

      INTEGER, INTENT(IN) :: mode, dime
      REAL, INTENT(IN)  :: gam, te
      REAL, INTENT(OUT) :: adsor
      REAL, OPTIONAL    :: dqdt, scl
      REAL :: kstar, param
      REAL :: rhog, rgasv
      REAL, PARAMETER :: as = 1.7E4, mi = 2.84E-7, ko = 7.54E-9, re = 0.4734

      rhog  = 1650.0
      rgasv = 0.461510E+03

      kstar = ko * exp(2697.2 / te)
      param = kstar * gam * rgasv * te
      adsor = rhog * as * mi * (param / (1.0 + param))**re

      if (mode == 2) return

      scl = re * adsor / ((1.0 + param) * gam)

      if (mode == 1) return

       dqdt = re * adsor * (te-2697.2) / ((1.0 + param)*te*te)

      RETURN

   END SUBROUTINE adsorb
end module adsorbers

   PROGRAM adsorb_test 
      use adsorbers
      IMPLICIT NONE

      REAL, DIMENSION(10)   :: tsl, gamm, adwat, wsc
      INTEGER :: dime, mode, ns, k
      REAL    :: gams, ts, adwatg

      ns = 10
      do k = 1,ns
         tsl(k)  = 180.0
         gamm(k) = 1.50E-6
      enddo
      gams = gamm(1)
      ts   = tsl(1)

      call adsorb(ts, gams, adwatg, dime = 1, mode = 2)
      call adsorb(tsl, gamm, adwat, wsc, dime = ns, mode = 1)

      do k = 1,ns
         write(*,*) tsl(k), gamm(k), adwat(k)
      enddo
      write (*,*) "---------"
      write(*,*) ts, gams, adwatg

      stop
   END PROGRAM adsorb_test


Odabo

Paul

Comment 4 Deji Akingunola 2007-02-21 15:13:44 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #0)
> 
> > By the way, NAG f95 detects the interface/procedure mismatch also for the
> > original program as the interface and the subroutines are in the same file.
> > This same-file error detection is also planed for gfortran.
> > 
> 
> K'aro Deji,
> 
> Or, more succinctly, the array in the interface is assumed shape, dimension
> (:), whereas you have an automatic array in the subroutine.
> 
> Change to
> 
Effecting the change Paul suggested fixed it for me, Thanks all. The interface and the subroutine are in different files in the original code.

Deji