Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28454 Discussions

Issues with complex part designators

ur
New Contributor II
1,178 Views

A little test program shows two issues I am having with  ifort (IFORT) 2021.3.0 20210609

program testit
implicit none
complex :: z
real,parameter :: y=sin(3.0), x=100.0
! TEST I
write(*,'(a)')repeat('=',80)
! z%re|mi can appear on the left-hand side of an assignment
z%re=100.0
z%im=sin(3.0)
write(*,*)z
write(*,*)'TEST I-a ',merge('PASSED','FAILED',z.eq.(x,y) )
write(*,*)'TEST I-b ',merge('PASSED','FAILED',z.eq.cmplx(100.0,sin(3.0)) )
! TEST II
write(*,'(a)')repeat('=',80)
! it can be passed as a subroutine argument and be changed
call trivial(z%re)
write(*,*)z
write(*,*)'TEST II ',merge('PASSED','FAILED',z.eq.(200.0,y))
contains

subroutine trivial(r)
real :: r
r=r*2
end subroutine trivial

end program testit

! Per a discussion on comp.fortran.lang
!
! https://groups.google.com/g/comp.lang.fortran/c/DXyrTYZbEI4
!
! It appears that z%re and z%im should act as variables and be
! able to be altered by a procedure call,

! if you add INTENT(INOUT) to "R" in TRIVIAL() you get a compile-time error

! real,intent(inout) :: r

! app/nochange.f90(16): error #6638: An actual argument is an expression
! or constant; this is not valid since the associated dummy argument has
! the explicit INTENT(OUT) or INTENT(INOUT) attribute. [REAL]
!
! Per the f2018 standard ...

! 9.1 Designator
!
! R901 designator is object-name
! or array-element
! or array-section
! or coindexed-named-object
! or complex-part-designator
! or structure-component
! or substring
!
! 1 The appearance of a data object designator in a context that requires
! its value is termed a reference.
!
! 9.2 Variable is designator
!
! R902 variable
!
There is nothing in
!
19.6.5 Events that cause variables to become defined
1 Variables become defined by the following events.

the long list that disqualifies a complex-part-designator
from being manipulated through the argument association
with a dummy argument.


And when debug flags are added TEST I indicates an error that does not appear to
be correct ...

forrtl: severe (194): Run-Time Check Failure. The variable 'testit_$Z'
is being used in 'app/nochange.f90(8,4)' without being defined
Image PC Routine Line Source
nochange 00000000004039AD MAIN__ 8 nochange.f90
nochange 00000000004037E2 Unknown Unknown Unknown
libc-2.31.so 00007F6D2E7B8083 __libc_start_main Unknown Unknown
nochange 00000000004036EE Unknown Unknown Unknown

<INFO> COMPILER OPTIONS: -warn all -check all -error-limit 1 -O0 -g -assume byterecl -traceback

0 Kudos
1 Solution
Ron_Green
Moderator
1,024 Views

I have to agree with Steve.  This looks like a bug in the Front End, the parsing of the language.  The runtime issue is falling out from that.  If the Front End does not properly identify a variable reference versus an expression reference then the runtime will misbehave.  

 

I will open (at least 1) bug report.  There may be more work required in other parts of the compiler but for sure I see a front-end issue. 

 

ron

View solution in original post

0 Kudos
13 Replies
jimdempseyatthecove
Honored Contributor III
1,148 Views

RE: INTENT(OUT) causing error. Note, when pasting code, click on toolbar ... then </>, then pull down and select language formatting:

 

subroutine trivial(r)
real, intent(out) :: r
r=r*2 ! *** error, r used as input on this line, requires intent(inout) which is by default
end subroutine trivial

 

RE: the complex uninitialized on write(*,*) z

This is in error, but it may be difficult for the compiler to properly detect. While in your case, where you initialized both components (re and im) of z, consider if you only initialized one. Would z then be considered initialized.

I do believe the compiler could keep track of the known components of a complex number type for runtime checks, extending this to a UDT might be problematic.

 

For now, to work around the error message, insert

  z = 0.0

somewhere near the beginning of the procedure.

Or, in this specific case use

  z = (x, y)

or

 z = cmplx(100.0,sin(3.0))

 

! **** Intel development, using an older ifort 2020.0.166, the following produces a compilation error:

 

  z = (100.0, sin(3.0))

error #6213: A constant or named constant is required in this context. [SIN]

 

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor II
1,139 Views

Jim, Intel Support Team members, 

As you may be able to decipher,  OP intends to raise a basic question regarding Intel Fortran implementation of the Fortran 2008 feature that introduced %RE and %IM complex-part-designators.  This is related to the ongoing discussion thread at comp.lang.fortran.  But the posted example in the original post attempts to get into additional detail which might be confusing to some readers and which is not pertinent to main question re: the latest Intel Fortran compilers, whether it be IFORT or IFX.

The standard ostensibly supports both these designators to appear in all variable definition contexts whereas Intel Fortran fails to conform to the standard in the context of an actual argument.  Intel members, will it be possible for you to follow-up with Intel Fortran compiler team on this and open a compiler defect ticket as needed?  Here's an additional example showing the issue:

 

contains
   subroutine s1
      complex :: c
      c = ( 0.0, 0.0 )
      call s2( c%re )
   end subroutine
   subroutine s2( x )
      real, intent(out) :: x  !<-- also look at intent(inout)
      x = 0.0
   end subroutine
end 
C:\temp>ifort /c /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

p.f90(5): error #6638: An actual argument is an expression or constant; this is not valid since the associated dummy argument has the explicit INTENT(OUT) or INTENT(INOUT) attribute.   [REAL]
      call s2( c%re )
^
compilation aborted for p.f90 (code 1)
C:\temp>ifx /c /standard-semantics p.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2022.2.0 Build 20220730
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.

p.f90(5): error #6638: An actual argument is an expression or constant; this is not valid since the associated dummy argument has the explicit INTENT(OUT) or INTENT(INOUT) attribute.   [REAL]
      call s2( c%re )
^
compilation aborted for p.f90 (code 1)

 

ur
New Contributor II
1,131 Views

 

The second issue is that the "-check all" switch causes a run-time failure of standard-conforming code.


program testit
use, intrinsic :: iso_fortran_env, only : dp=>real64
implicit none
complex(kind=dp) :: z
   z%re=100.0_dp
   z%im=200.0_dp
   write(*,*)z
end program testit

There is nothing I can see in the standard that says a complex variable
must be initialized before a LHS complex-part-designator is allowed,
so this would be conformant Fortran but is flagged with a fatal error, not
just a warning, when "-check all" is used. This makes employing the
check on otherwise correct code problematic. Perhaps a restriction in the

standard requiring initialization would have been prudent, but I see no such requirement.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,127 Views

I suspect (the error message infers) that the initialization of c in subroutine s1 with a literal expressions in effect makes c appear as if it were a literal.

*** However, upon further testing, this is not the case

c = ( 0.0, 0.0 ) ! fails

c = cmplx( 0.0, 0.0 ) ! fails

and commenting out c = ... fails with call using c%re as actual argument (and dummy with intent(out))

intent(inout) also failed

but no intent declaration succeeds

 

Definitely a bug

 

Jim Dempsey

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,126 Views

>>There is nothing I can see in the standard that says a complex variable must be initialized before a LHS complex-part-designator is allowed

 

That was not the point. The error is the complex variable z

reports runtime error of variable used without initialization on write(*,*)z

when member variables %re and/or %im are initialized.

 

Initializing z itself (as opposed to individual parts) solves the erronious? runtime error message.

 

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
1,120 Views

 

program testit
implicit none
complex :: z
real,parameter :: y=sin(3.0), x=100.0
! TEST I
write(*,'(a)')repeat('=',80)
! z%re|mi can appear on the left-hand side of an assignment
z%re=100.0
z%im=sin(3.0)
write(*,*)z
write(*,*)'TEST I-a ',merge('PASSED','FAILED',z.eq.(x,y) )
write(*,*)'TEST I-b ',merge('PASSED','FAILED',z.eq.cmplx(100.0,sin(3.0)) )
! TEST II
write(*,'(a)')repeat('=',80)
! it can be passed as a subroutine argument and be changed
call trivial(z%re)
write(*,*)z
write(*,*)'TEST II ',merge('PASSED','FAILED',z.eq.(200.0,y))
contains

subroutine trivial(r)
real :: r
r=r*2
end subroutine trivial

end program testit

Much neater to create a cmplx in one line than two lines.  

 

 

0 Kudos
ur
New Contributor II
1,119 Views
program testit
use, intrinsic :: iso_fortran_env, only : dp=>real64
implicit none
complex(kind=dp) :: z !=(0.0,0.0)
real(kind=dp) :: x
   z%re=3.0_dp  ! <= The error occurs here, not in write
   z%im=4.0_dp
   x=abs(z)
   write(*,*)x
end program testit

I know how to work around it; the WRITE() just keeps the lines from being optimized away easily;  the error occurs on line 6 and is definitely erroneous per the standard; and works with full debug options on with three other compilers with no warning at all; although some warn if line 7 is removed when line 8 is encountered, that is OK. Good, actually.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,074 Views

FWIW this error does not occur with a UDT

module mod_udt
    use, intrinsic :: iso_fortran_env, only : dp=>real64
    type udt_t
        real(kind=dp) :: re
        real(kind=dp) :: im
    end type udt_t
end module mod_udt
program testit
    use mod_udt
    implicit none
    complex(kind=dp) :: z !=(0.0,0.0)
    real(kind=dp) :: x
    type(udt_t) :: udt
    udt%re=3.0_dp ! <= no error here
    udt%im=4.0_dp
    z%re=3.0_dp  ! <= The error occurs here, not in write
    z%im=4.0_dp
    x=abs(z)
    write(*,*)x
end program testit

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
1,101 Views

complex-part-designators are variables (see F2018 R901 and R902.) If Intel Fortran is treating them as expressions, that's a bug.

0 Kudos
JohnNichols
Valued Contributor III
1,089 Views

Running different variations of your last program one gets :

1. Everything normal. 

 Screenshot_20221112_033159.png

2. IN debug mode you get the standard weird number that is constantly used applied to the real part. when you do not set Z real

 

 

Screenshot_20221112_033254.png

 

3. All reals are initialized on creation to the weird number that some one will tell me is something ZZZZZZZZZZZZZZZ in hexadecimal. 

 

Screenshot_20221112_033337.png

4.  In release mode with all the warnings I can find turned then z real is set to zero -- debug and release should not be different.  

 

No idea what the standard says about what value uninitialized variables take, but it is always a bad idea,  if I test the last picture for X < 0 by mistake it is true in 3. and not true in 4.  Fortran is the same.  

 

Screenshot_20221112_033805.png

 

Interesting. 

0 Kudos
Ron_Green
Moderator
1,025 Views

I have to agree with Steve.  This looks like a bug in the Front End, the parsing of the language.  The runtime issue is falling out from that.  If the Front End does not properly identify a variable reference versus an expression reference then the runtime will misbehave.  

 

I will open (at least 1) bug report.  There may be more work required in other parts of the compiler but for sure I see a front-end issue. 

 

ron

0 Kudos
Steve_Lionel
Honored Contributor III
1,021 Views

FWIW, this isn't the first time ifort has had problems with complex-part-designators.

0 Kudos
Ron_Green
Moderator
966 Views

I opened 2 bug reports on this

CMLRLLVM-41931 for passing z%re to a subroutine that updates the value of the arg, but actual arg is unchanged after return.

CMLRIL0-35035 for the -check uninit that erroneously flags the assignment as illegal use of uninit variable.  

 

 

Reply