Wrong results with ASSOCIATE block

Hi all,

I ran into something strange with ASSOCIATE and the imaginary part selector %im.

here is a small example:


program hello
  use, intrinsic :: iso_fortran_env, only: wp => real64, compiler_version
  implicit none

  real(wp) :: x = 0.0_wp
  real(wp) :: h = 1.0e-50_wp

  print *, "Compiler version:", compiler_version()

  associate (r => f(cmplx(x, h, kind=wp)))
    print *, "kind(r):", kind(r)
    print *, "storage_size(r):", storage_size(r)
    print *, "r = ", r
    print *, 1.0_wp / h * r%im  ! the correct result should be 1.0
    print *, 1.0_wp / h * aimag(r)  ! the correct result should be 1.0
  end associate

contains

  complex(wp) function f(x)
    complex(wp), intent(in) :: x
    f = sin(x)
  end function f

end program hello

With gfortran 14.2.0 I get:

Compiler version:GCC version 14.2.0
kind(r):           4
storage_size(r):          64
r =              (0.00000000,0.00000000)
  0.0000000000000000
  0.0000000000000000

I also tested with the latest version (online compiler https://godbolt.org/) and got the same output:

Compiler version:GCC version 17.0.0 20260502 (experimental)
 kind(r):           4
 storage_size(r):          64
 r =              (0.00000000,0.00000000) 
   0.0000000000000000    ! result should be 1.0 
   0.0000000000000000    ! result should be 1.0

However: if I comment out the line: print *, 1.0_wp / h * r%im the result printed by print *, 1.0_wp / h * aimag(r) becomes correct, i.e., returns 1.0

  associate (r => f(cmplx(x, h, kind=wp)))
    print *, "kind(r):", kind(r)
    print *, "storage_size(r):", storage_size(r)
    print *, "r = ", r
    !print *, 1.0_wp / h * r%im  ! <<<<<< if we comment out this
    print *, 1.0_wp / h * aimag(r)  ! <<< the result is now 1.0
  end associate

Output:

Compiler version:GCC version 17.0.0 20260502 (experimental)
 kind(r):           8
 storage_size(r):         128
 r =          (0.0000000000000000,1.00000000000000001E-050)
   1.0000000000000000 

Is this a gfortran bug, or am I misunderstanding something about ASSOCIATE and complex part selectors?

Update:

With nagfor, the result is correct:

 Compiler version:NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7231
 kind(r): 8
 storage_size(r): 128
 r =  (0.0000000000000000,1.0000000000000000E-50)
   1.0000000000000000
   1.0000000000000000

End of update

Best,

Simo

Hi,

This definitely looks like a bug. You should fill a bug report.

I tried to create a user account to report it, but I am unable to do so:

User account creation has been restricted.
Contact gcc-bugzilla-account-request@gcc.gnu.org to request an account. You should receive a response within 24 hours.

If someone already has an account, I would appreciate it if they could report it.

Thank you.

LFortran gives:

$ lfortran a.f90
Compiler version:LFortran version 0.63.0-219-ge6b1cd9004
kind(r): 8
storage_size(r): 128
r =  (0.0000000000000000,1.0000000000000000E-050)
1.0000000000000000
1.0000000000000000
3 Likes

Did you contact gcc-bugzilla-account-request@gcc.gnu.org ?

1 Like

I contacted them but haven’t heard back yet.

One can also post a bug report to the gfortran mailing list, fortran@gcc.gnu.org .

1 Like

Will try that.
In the meantime, I narrowed the issue down:

module m
  use, intrinsic :: iso_fortran_env, only: wp=>real64
  implicit none(type, external)

  contains
    complex(wp) function myfunc(x)
      complex(wp), intent(in) :: x
      myfunc = sin(x)
    end function myfunc
end module m

program demo
  use, intrinsic :: iso_fortran_env, only: wp=>real64
#if defined(MOD_CONTAINS)
  use m, only: myfunc
#endif
  implicit none(type, external)
  character(len=150) :: fmt1
  complex(wp) :: z

  fmt1='(1X,A10, 2X, F0.12, 5X, A18, 2X, I0)'
  z = (1.0_wp, 2.0_wp)

  associate(k => myfunc(z))
    print fmt1, 'k%re: ',   k%re,     'kind(k%re)', kind(k%re)
    print fmt1, 'k%im: ',   k%im,     'kind(k%im)', kind(k%im)
    print fmt1, 'aimag(k):', aimag(k), 'kind(aimag(k)):', kind(aimag(k))
  end associate

#if defined(PROG_CONTAINS)
  contains
    complex(wp) function myfunc(x)
      complex(wp), intent(in) :: x
      myfunc = sin(x)
    end function myfunc
#endif

end program demo
  • with program contains:
$ gfortran -cpp -DPROG_CONTAINS -o demo main.f90 && ./demo
     k%re:   3.165778398514             kind(k%re)  4
     k%im:   1.959601044655             kind(k%im)  4
  aimag(k):  1.959601044655        kind(aimag(k)):  4
  • with module contains:
$ gfortran -cpp -DMOD_CONTAINS -o demo main.f90 && ./demo
     k%re:   3.165778513216             kind(k%re)  8
     k%im:   1.959601041422             kind(k%im)  8
  aimag(k):  1.959601041422        kind(aimag(k)):  8