- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
complex-part-designators are variables (see F2018 R901 and R902.) If Intel Fortran is treating them as expressions, that's a bug.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Running different variations of your last program one gets :
1. Everything normal.
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
3. All reals are initialized on creation to the weird number that some one will tell me is something ZZZZZZZZZZZZZZZ in hexadecimal.
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.
Interesting.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FWIW, this isn't the first time ifort has had problems with complex-part-designators.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This issue has been fixed in the recently released Intel Fortran Compiler, available for download as part of Intel HPC Toolkit 2024.2.1
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page