[J3] [SC22WG5.6687] WG5 letter ballot 1 on Fortran 2023 interpretations
Malcolm Cohen
malcolm at nag-j.co.jp
Fri May 16 02:26:52 UTC 2025
Hi folks,
Attached is the first WG5 letter ballot on Fortran 2023 interpretations. I
have made it a J3 paper for now, I expect it will be promoted to be a WG5
paper in due course. This is a 30-day letter ballot starting immediately.
For convenience, I reproduce the "action" part of the ballot below.
The following Fortran 2023 interpretations are being balloted:
Yes No Number Title
--- --- F23/003 Conflicting rules for COMMON block names
--- --- F23/004 OUT_OF_RANGE and ROUND argument
--- --- F23/005 Defined assignment/operators and dynamic type
--- --- F23/006 Underflow in IEEE_SCALB
--- --- F23/008 Real argument I in IEEE_SCALB
--- --- F23/009 Coarray subobject of component
--- --- F23/010 MOVE_ALLOC with coarray arguments
--- --- F23/011 NULL and procedure pointers
--- --- F23/012 Coarray correspondence in DEALLOCATE
--- --- F23/013 BOZ literals in interoperable enumerators
--- --- F23/015 Coindexed objects in structure constructors
--- --- F23/016 Segments associated with allocation
--- --- F23/017 CFI_establish nonalloc nonpointer null base address
--- --- F23/018 Correspondence of unallocated coarrays
Please mark the above -Y- in the Yes column for "yes", -C- in the Yes
column for "yes with comment", or -N- in the No column for a "no"
answer {be sure to include your reasons with "no"} and send ONLY the
vote section to
sc22wg5 at open-std.org
by 23:59 UTC on June 15, 2025, in order to be counted.
Thanks,
Malcolm on behalf of Steve Lionel
NB: Be careful not to attach the whole ballot to your email, we just need
the votes as above with any comments/reasons.
Cheers,
--
..............Malcolm Cohen, NAG Oxford/Tokyo.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20250516/c52bb148/attachment-0001.htm>
-------------- next part --------------
To: J3 J3/25-134
From: Malcolm Cohen
Subject: WG5 letter ballot 1 on Fortran 2023 interpretations
Date: 2025-May-16
This J3 paper will be promoted to be a WG5 paper in due course.
This is the first set of draft interpretations for Fortran 2023.
They have all been approved in a J3 letter ballot.
The rules we operate on say:
4. The chair of J3/interp gathers all interp answers that are marked
"passed by J3 letter ballot" and forwards them to the WG5 convenor.
The WG5 convenor holds a ballot of individual members; a no vote
must be accompanied by an explanation of the changes necessary to
change the member's vote to yes. The answers that pass this ballot
become "WG5 approved".
J3/interp reserves the right to recall an interp answer for more
study even if the answer passes.
5. "WG5 approved" answers are processed into a corrigendum document by
taking the edits from the interp answers and putting them in the
format required by ISO. A WG5 vote is made on forwarding the
corrigendum to SC22.
The following Fortran 2023 interpretations are being balloted:
Yes No Number Title
--- --- F23/003 Conflicting rules for COMMON block names
--- --- F23/004 OUT_OF_RANGE and ROUND argument
--- --- F23/005 Defined assignment/operators and dynamic type
--- --- F23/006 Underflow in IEEE_SCALB
--- --- F23/008 Real argument I in IEEE_SCALB
--- --- F23/009 Coarray subobject of component
--- --- F23/010 MOVE_ALLOC with coarray arguments
--- --- F23/011 NULL and procedure pointers
--- --- F23/012 Coarray correspondence in DEALLOCATE
--- --- F23/013 BOZ literals in interoperable enumerators
--- --- F23/015 Coindexed objects in structure constructors
--- --- F23/016 Segments associated with allocation
--- --- F23/017 CFI_establish nonalloc nonpointer null base address
--- --- F23/018 Correspondence of unallocated coarrays
The text of these interpretations appears below.
Each interpretation starts with a row of "-"s.
Please mark the above -Y- in the Yes column for "yes", -C- in the Yes
column for "yes with comment", or -N- in the No column for a "no"
answer {be sure to include your reasons with "no"} and send ONLY the
vote section to
sc22wg5 at open-std.org
by 23:59 UTC on June 15, 2025, in order to be counted.
Thanks,
Malcolm on behalf of Steve Lionel
----------------------------------------------------------------------
NUMBER: F23/003
TITLE: Conflicting rules for COMMON block names
KEYWORDS: COMMON Block, Named Constant, USE association renaming
DEFECT TYPE: Clarification/Erratum
STATUS: Passed by J3 letter ballot
REFERENCES: N2209
QUESTION:
A survey of five compilers finds that three disallow a named constant
from having the same name as a COMMON block in a give scope, while two
compilers permit named constants sharing the same name as a COMMON
block accessible in the same scope.
19.3.1 Classes of local identifiers, paragraph 1 establishes identifiers
of names constants to be class (1) identifiers. Paragraph 2 states:
"Within a scope, a local identifier of an entity of class (1) or
class(4) shall not be the same as a global identifier used in that
scope unless the global identifier
o ...
o is a common block name
o ..."
However, 19.3.2 Local identifiers that are the same as common block
names states:
"A name that identifies a common block in a scoping unit shall not be
used to identify a constant or an intrinsic procedure in that
scoping unit. ..."
which disallows a named constant from having the same name as an
accessible common block.
14.2.2 The USE statement and use association contains Note 4 which
states
"The constraints in 8.10.1, 8.10.2, and 8.9 prohibit the local-name
from appearing in a COMMON statement, and equivalence-object in an
EQUIVALENCE statement, or a namelist-group-name in a NAMELIST state-
ment, respectively. There is no prohibition against the local-name
appearing as a common-block-name or a namelist-group-object."
The last sentence of this note contradicts the restrictions in 19.3.2.
Q. Is the intent to disallow a local identifier that identifies a
named constant from being the same as an accessible common block?
ANSWER:
Yes, the local identifier of a named constant cannot be the same as
that of an accessible common block. This issue goes back to FORTRAN 77
when the PARAMETER statement was introduced. When Fortran 90
introduced MODULEs and USE association, the restriction on common
block names was overlooked when the note was written.
Clarifying edits are provided.
EDITS to N2209:
[299] 14.2.2 The USE statement and use association, NOTE 4, sentence 2
delete
"a common-block-name or"
add at the end of the note
"Restrictions on local-name being the same as a common-block-name
are detailed in 19.3.2."
[528:15] 19.3.1 Classes of local identifiers, p2,
after "is a common block name (19.3.2)"
insert "and the local identifier is not that of a named
constant or intrinsic procedure,"
SUBMITTED BY: Jon Steidel
HISTORY: 23-119 m229 Submitted
23-119r1 m229 Revised edit location/description, approved uc
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/004
TITLE: OUT_OF_RANGE and ROUND argument
KEYWORDS: OUT_OF_RANGE
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
In the description of the intrinsic function
OUT_OF_RANGE (X, MOLD [, ROUND])
it states "ROUND shall be present only if X is of type real and
MOLD is of type integer."
Consider
Program test
Call s(1.5,2.5)
Contains
Subroutine s(x,y,r)
Logical,Optional :: r
Print *,out_of_range(x,y,r) ! Valid?
End Subroutine
End Program
As R is an optional dummy argument, it is present only if the actual
argument is present. In this example, R is not present, and so the
requirement in 16.9.157 is satisfied.
Was it intended that this program be valid?
(Of the two compilers that implement OUT_OF_RANGE that I tested,
both of them rejected the program.)
ANSWER:
No, it was not intended that the example be valid; the requirement
should have stated that the argument shall not appear.
An edit is provided.
EDIT to N2209.
[422] 16.9.157 OUT_OF_RANGE, Arguments paragraph, ROUND argument,
change "shall be present only" to "shall appear only".
SUBMITTED BY: Malcolm Cohen
HISTORY: 23-114 m229 Submitted, approved uc
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/005
TITLE: Defined assignment/operators and dynamic type
KEYWORDS: Defined assignment, defined operations, dynamic type
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
10.2.1.4 Defined assignment statement states that a subroutine
"defines the defined assignment x1 = x2 if
(1) the subroutine is specified with a SUBROUTINE (15.6.2.3) ...
statement that specifies two dummy arguments, d1 and d2,
[and]
(3) the types of d1 and d2 are compatible with the dynamic types
of x1 and x2, respectively,"
Furthermore, 10.2.1.2 Intrinsic assignment statement states
"An intrinsic assignment statement is an assignment statement
that is not a defined assignment statement (10.2.1.4)."
This means that
(i) in the situation where there is no intrinsic assignment, whether
there is a defined assignment (and thus the program is valid)
depends on the dynamic types, not the declared types;
(ii) in the situation where there may be an intrinsic assignment for
a derived type, whether this is overridden by defined assignment
again depends on the dynamic types.
Similar wording appears in in 10.1.6 Defined operations, specifically
in 10.1.6.1 Definitions, paragraph 2, item (3), and paragraph 5 item
(3). Similar conclusions follow.
These consequences are contrary to the principle that generic
resolution is determined statically, that is, at compile time.
Generic resolution is indeed done statically for generic names and
generic type-bound procedures. It would be very surprising for it
not to be done statically for generic assignment and operators.
For example, consider
Module c23_005
Type t
Integer c
End Type
Type,Extends(t) :: t2
Integer d
End Type
Generic :: Assignment(=) => assign_t2_int
Contains
Subroutine assign_t2_int(a,b)
Class(t2),Intent(InOut) :: a
Integer,Intent(In) :: b
a%c = b
a%d = -b
End Subroutine
End Module
Program test
Use c23_005
Class(t),Allocatable :: x
Allocate(x,Source=t2(1,2))
x = 12345 ! (1)
Print *,x%c
End Program
There is no intrinsic assignment at (1), so the program would be
invalid unless generic resolution is done on the dynamic type.
Consider
Module c23_005a
Type t
Integer c
End Type
Type,Extends(t) :: t2
Integer d
End Type
Generic :: Assignment(=) => assign_t2_t
Contains
Subroutine assign_t2_t(a,b)
Class(t2),Intent(InOut) :: a
Type(t),Intent(In) :: b
a%c = b%c**2
a%d = -b%c**2
End Subroutine
Subroutine sho(w)
Class(t),Intent(In) :: w
Select Type (w)
Type Is (t)
Print *,'t:',w
Type Is (t2)
Print *,'t2:',w
End Select
End Subroutine
End Module
Program test
Use c23_005a
Class(t),Allocatable :: x
Allocate(x,Source=t2(1,2))
x = t(9) ! (2)
Call sho(x)
End Program
Intrinsic assignment would be available for the assignment at (2),
but if generic resolution were done on the dynamic type, the defined
assignment would be executed, not the intrinsic assignment. That
affects the result - does the program print "t: 9" or "t2: 81 -81".
It does not have to be the left-hand-side that is polymorphic:
consider
Module c23_005b
Type t
Integer c
End Type
Type,Extends(t) :: t2
Integer d
End Type
Generic :: Assignment(=) => assign_t_t2
Contains
Subroutine assign_t_t2(a,b)
Type(t),Intent(Out) :: a
Class(t2),Intent(In) :: b
a%c = b%c**2 - b%d**2
End Subroutine
End Module
Program test
Use c23_005b
Class(t),Allocatable :: x
Type(t) y
Allocate(x,Source=t2(1,2))
y = x ! (3)
Print *,y
End Program
Here the question is whether the program prints "1" for generic
resolution of the statement at (3) done at compile time (and thus the
intrinsic assignment), or "-3" for generic resolution done at
execution time (and thus the defined assignment).
For defined operations, consider
Module c23_005c
Type t
Integer c
End Type
Type,Extends(t) :: t2
Integer d
End Type
Generic :: Operator(+) => t2_plus_int
Contains
Type(t2) Function t2_plus_int(a,b) Result(r)
Class(t2),Intent(In) :: a
Integer,Intent(In) :: b
r%c = a%c + b
r%d = a%d - b
End Function
End Module
Program test
Use c23_005c
Class(t),Allocatable :: x
Allocate(x,Source=t2(1,2))
Print *,x+10 ! (4)
End Program
This is valid only if the dynamic type is used to resolve the generic
operation at (4) in favour of the defined operation, even though the
compiler has no idea what the declared type might be at runtime.
One final consideration is that type compatibility is between
entities, not between types. Therefore, the quoted words
"the types of d1 and d2 are compatible with the dynamic types
of x1 and x2"
have no meaning, and thus by subclause 4.2 Conformance, paragraph 1,
"A program (5.2.2) is a standard-conforming program ... if the
program has an interpretation according to this document"
all programs which attempt to use defined assignment or operators are
non-conforming.
So the question is, should generic resolution of defined assignment
and defined operators follow the dynamic type, as suggested by the
current wording?
DISCUSSION:
These words come from paper 02-129r2 at meeting 160, which claimed to
be making no technical change. The editor wrote in his report
"These seem more than editorial. Looks like a couple of dynamic
and declared types got switched around for a start. And same
type got changed to compatable type. I'll just assume it is all
correct."
Unfortunately, no-one followed up on the report.
No compilers have been reported as following the implications of the
current wording - they all use the declared types for generic
resolution, just like normal type compatibility.
ANSWER:
No, generic resolution of defined assignment and defined operations
should follow the rules for type compatibility, which uses the
declared type not the dynamic type.
It is noted that the rules for argument association already include
the correct wording; 15.5.2.5 Ordinary dummy variables, p2, states
"The dummy argument shall be type compatible with the actual
argument."
Edits are provided to correct this misstatement.
EDITS to N2209.
[161:6] 10.1.6 Defined operations, 10.1.6.1 Definitions, p2, (3),
Change
"the type of d2 is compatible with the dynamic type of x2,"
to
"d2 is type-compatible with x2,"
[161:23] Same subclause, p5, (3),
Change "the types of d1 and d2 are compatible with the dynamic
types of x1 and x2, respectively,"
to
"d1 and d2 are type-compatible with x1 and x2, respectively,"
[172:13] 10.2.1.4 Defined assignment statement, p2, (3),
Change "the types of d1 and d2 are compatible with the dynamic
types of x1 and x2, respectively,"
to
"d1 and d2 are type-compatible with x1 and x2, respectively,"
{Note the lines in NOTE 8 at the top of the page do not count towards
the line number in the interpretation document.}
SUBMITTED BY: Malcolm Cohen & Jon Steidel
HISTORY: 23-118 m229 Submitted, approved uc
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/006
TITLE: Underflow in IEEE_SCALB
KEYWORDS: Underflow, IEEE_SCALB
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
If X * 2**I is too small to be represented with full accuracy, was it
intended that IEEE_SCALB(X,I) should return the representable number
having a magnitude nearest to ABS(2**I) and the same sign as X? For
example, if X is IEEE binary32 with the value 2E-38, was it
intended that IEEE_SCALB(X,-1) should return the value 0.5?
ANSWER:
No, it was intended that it should return the representable number
having a magnitude nearest to ABS(X*2**I) and the same sign as X.
An edit is supplied.
This error dates back to Fortran 2003. Therefore this is an
incompatibility with Fortran 2003, 2008, and 2018. Edits to the
compatibility subclause are provided.
EDITS to N2218:
[xiii] Introduction, Intrinsic modules bullet, append sentence
"The result of the function IEEE_SCALB from the intrinsic module
IEEE_ARITHMETIC has been corrected to conform to \theIEEEstd."
[33:13+] 4.3.3 Fortran 2018 compatibility, last paragraph, new bullet
"- The result of a reference to the function IEEE_SCALB from the
intrinsic module IEEE_ARITHMETIC has been corrected to return
the representable number having a magnitude nearest to
ABS(X*2**I) with the same sign as X, if X*2**I is too small to
be represented with full accuracy."
[34:17+] 4.3.4 Fortran 2008 compatibility, last paragraph, new bullet
with text identical to preceding edit.
[35:13+] 4.3.5 Fortran 2003 compatibility, last paragraph, new bullet
with text identical to the edit for [33:13+].
[487:15] 17.11.37 IEEE_SCALB, Result Value paragraph, Case (iii),
change "|2^I|" to "|X \times 2^I|".
SUBMITTED BY: John Reid
HISTORY: 23-156 m230 Submitted
23-156r1 m230 Revised edits, approved uc
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/008
TITLE: Real argument I in IEEE_SCALB
KEYWORDS: Real, IEEE_SCALB
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
The first sentence of 17.1 Overview of IEEE arithmetic support, states
"The intrinsic modules IEEE_EXCEPTIONS, IEEE_ARITHMETIC, and
IEEE_FEATURES provide support for the facilities defined by
ISO/IEC 60559:2020."
However, nothing claims to support the IEEE function scaleB. This is
very like IEEE_SCALB (X,I) except that the IEEE standard requires
that the second argument to scaleB be the same type as logB, and that
is Real type whereas IEEE_SCALB only accepts Integer type.
Was it intended to support the IEEE scaleB operation?
If so, is that intended to be provided by IEEE_SCALB?
ANSWER:
Yes, the IEEE scaleB operation should have been supported.
Yes, IEEE_SCALB should provide the scaleB operation.
EDITS to N2218:
[xiv] Introduction, bullet "Changes to the intrinsic module
IEEE_ARITHMETIC for conformance with ISO/IEC 60559:2020",
append sentence
"The function IEEE_SCALB from the intrinsic module
IEEE_ARITHMETIC now performs the scaleB operation."
[470:6-7] 17.9 IEEE arithmetic, p1, bullet list, last item,
After "logB," insert "scaleB,",
After "IEEE_LOGB," insert "IEEE_SCALB".
[487:6] 17.11.37 IEEE_SCALB, Arguments, I, change "integer" to
"integer or of type real with the same kind type parameter as X"
so that the line reads
"I shall be of type integer or of type real with the same kind
type parameter as X.".
[487:9+] Same subclause, Result Value, before "Case (i)", insert
"The value of the result shall conform to the scaleB operation
of \theIEEEstd.".
SUBMITTED BY: John Reid
HISTORY: 23-157 m230 Submitted
23-157r1 m230 Revised
23-157r2 m230 Revised, passed by J3 meeting
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/009
TITLE: Coarray subobject of component
KEYWORDS: coarray, allocatable, array, component
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
The Introduction of Fortran 2023 says
"A data object with a coarray component can be an array or
allocatable."
This appears to be true for named variables, but there is a constraint
that makes it impossible for an array component or an allocatable
component:
"C753 A data component whose type has a coarray potential subobject
component shall be a nonpointer nonallocatable scalar and
shall not be a coarray."
That means that given the type
Type real_coarray
Real,Allocatable :: c[:]
End Type
the statements
Type(real_coarray) x(100)
Type(real_coarray),Allocatable :: y
are acceptable as type declaration statements, but unacceptable as
component definition statements.
Is this irregularity deliberate?
ANSWER:
No, this constraint was accidentally overlooked when extending types
with coarray components to be subobjects of arrays and allocatables.
An edit is provided to correct this mistake.
EDIT to N2218 (Fortran 2023 FDIS):
[79:constraint C753] In subclause
Delete this constraint, which begins
"C753 A data component whose type has a coarray"
[80:After NOTE 1] Insert new NOTE
"NOTE 1.5
A data component whose type has a coarray potential subobject
component cannot be a coarray or a pointer, see constraint C825."
{C825 says "An entity whose type has a coarray potential subobject..."
and components are certainly entities. We specifically wrote "entity"
instead of "named variable" to cover the component case.
I prefer to say it once and refer to it.}
SUBMITTED BY: John Reid & Reinhold Bader
HISTORY: 23-210 m231 Submitted
23-210r1 m231 Revised
23-210r2 m231 Passed as amended by J3 meeting 231.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/010
TITLE: MOVE_ALLOC with coarray arguments
KEYWORDS: MOVE_ALLOC, coarray
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
If the FROM and TO arguments to MOVE_ALLOC are coarrays, are
corresponding invocations of MOVE_ALLOC required to have their FROM
(and TO) arguments be corresponding coarrays?
For example, this program ends up with A and B not having the same
allocation status on all images, which surely cannot be right.
program trouble
real, allocatable :: a[:], b[:]
allocate(a[*],b[*])
if (this_image()>1) then
call sub(a,b)
! Now, A is deallocated and B is allocated
else
call sub(b,a)
! Now, B is deallocated and A is allocated
end if
contains
subroutine sub(s,t)
real, allocatable :: s[:], t[:]
call move_alloc(s,t)
end subroutine
end program
ANSWER:
Yes, those arguments are required to be corresponding coarrays.
An edit is supplied to correct this error.
EDIT to N2218 (Fortran 2023 FDIS):
[423] In 16.9.147 MOVE_ALLOC, Arguments paragraph,
At the end of the FROM argument description append
"If it is a coarray, it shall correspond to the FROM arguments
in all corresponding invocations of MOVE_ALLOC."
At the end of the TO argument description append
"If it is a coarray, it shall correspond to the TO arguments
in all corresponding invocations of MOVE_ALLOC."
SUBMITTED BY: John Reid & Reinhold Bader
HISTORY: 23-170 m230 Submitted
23-220 m231 Revised
23-220r1 m231 Revised, passed by J3 meeting 231.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/011
TITLE: NULL and procedure pointers
KEYWORDS: NULL, procedure pointer
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider the procedure declaration statement
PROCEDURE(), POINTER :: PROCPTR => NULL()
The statement appears to violate the requirements of the standard.
The function reference does not match any of the conditions listed in
Table 16.5.
The closest case is "initialization of an object in a declaration",
but a procedure pointer is not an object (see 3.42).
Therefore, a MOLD argument is required.
However, constraint C813 prohibits a MOLD argument from appearing.
The same does not apply to default initialization of procedure pointer
components in a derived type definition, as component initialization
appears in Table 16.5.
Is this irregularity deliberate?
ANSWER:
No, this is not deliberate. Table 16.5 should be extended to include
initialization in a procedure declaration statement.
An edit is provided.
EDIT to N2218 (Fortran 2023 FDIS):
[428] 16.9.155 NULL, Result Characteristics, Table 16.5
In the entry "initialization for an object..."
change "object" to "entity", twice, making the whole entry read
"initialization for an entity in a declaration | the entity".
{Subtle but effective.}
SUBMITTED BY: Robert Corbett & Malcolm Cohen
HISTORY: 23-233 m231 Submitted
23-233r1 m231 Revised edit, passed by J3 meeting 231.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/012
TITLE: Coarray correspondence in DEALLOCATE
KEYWORDS: DEALLOCATE, coarray
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
In 9.7.3.2 Deallocation of allocatable variables, paragraph 11
requires that coarray dummy arguments on the active images have
ultimate arguments that are corresponding coarrays.
However, there appears to be no such requirement for coarray
components of dummy arguments.
Thus this program appears to be valid (apart from having no
interpretation due to coarray allocation status inconsistency):
Program trouble
Type t
Real,Allocatable :: c(:)[:]
End Type
Type(t) x,y
Allocate(x(1)[*],y(1)[*])
If (This_Image()==1) Then
Call oops(x)
Else
Call oops(y)
End If
Print *,Allocated(x%c),Allocated(y%c)
Sync All
Contains
Subroutine oops(z)
Type(t) :: z
Deallocate(z%c)
End Subroutine
End Program
Should there be a requirement on coarray components of dummy arguments
in DEALLOCATE?
There is also an editorial glitch in paragraph 10 where it says that a
coarray does not "become deallocated on an image unless it is
successfully deallocated on all active images", since "it" exists on
only one image (the others being the corresponding coarrays), and "all
active images" includes the image in question, so is circular. Should
this not be corrected?
ANSWER:
Yes, this requirement should be explicit.
Yes, the wording in the last sentence of paragraph 10 is poor, and
should be improved.
Edits are supplied to address these defects.
As the question noted, the example is not conforming as it violates
the semantics that corresponding coarrays have the same allocation
status, bounds, etc. on all images on which they are established.
EDIT to N2218:
[152] 9.7.3.2 Deallocation of allocatable variables, paragraph 10,
last sentence,
change "it is" to "the corresponding coarrays are",
and insert "other" between "all" and "active",
making that whole sentence read:
"A coarray shall not become deallocated on an image unless the
corresponding coarrays are successfully deallocated on all other
active images in this team."
{Clarify "it" and "all".}
[152] Same subclause, paragraph 11 beginning "If an allocate-object is
a coarray dummy argument", append new sentence
"If an allocate-object is a coarray subcomponent of a dummy
argument, those components of the ultimate arguments on those
images shall be corresponding coarrays."
{Requirement needed to maintain coarray correspondence semantics.
A "subcomponent" is a component that is an immediate component,
of a component of a subobject.}
SUBMITTED BY: John Reid & Reinhold Bader
HISTORY: 23-218 m231 Submitted
23-243 m231 Revised
23-243r1 m231 Passed by J3 meeting 231.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/013
TITLE: BOZ literals in interoperable enumerators
KEYWORDS: BOZ, enumerators
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
For Fortran 2023, work item US-23 expanded the contexts in which
BOZ constants were allowed, to include "as the <initialization>
for a named constant of type INTEGER or REAL,..." (C7119).
19-256r1 had the primary edits, with 21-101 containing additional
edits not relevant to this paper.
19-256r1 contained examples showing use of BOZ constants in
PARAMETER statements, but did not mention interoperable
enumerators, which are "named integer constant[s]" (7.6.1p1).
Consider the following:
ENUMERATOR :: FOO = Z'123'
is this conforming in Fortran 2023? Clearly, the intent of US-23
was that it should be, but the syntax rule for <enumerator> is:
R762 enumerator is named-constant [ = scalar-int-constant-expr ]
Since a BOZ constant has no type (7.7p1), it can't be an integer,
and thus isn't a scalar-int-constant-expr. Was this exclusion
intended? (Note: PARAMETER does not have this issue.)
ANSWER:
No - it was intended to allow BOZ constants as the value for
interoperable enumerators just as they are in the PARAMETER
statement. Edits to correct this are provided.
EDITS to 24-007:
[7.6.1, 95:18+ Interoperable enumerations and enum types]
insert after:
R762 enumerator is named-constant [ = scalar-int-constant-expr ]
" or <named-constant> [ = <boz-literal-constant> ]"
(The Editor is welcome to substitute an alternate expression of this
definition, such as creating a new term for the initializer.)
[7.6.1p6, 96:5-9 Interoperable enumerations and enum types]
In the numbered list following "The enumerator is a scalar named
constant, with the value determined as follows.", make the following
changes.
Insert after (1):
"(1a) if boz-literal-constant appears, the enumerator has the value
specified by INT(boz-literal-constant, C_INT), where C_INT is from
the intrinsic module ISO_C_BINDING."
In the current (2) and (3), replace "If scalar-int-constant-expr does
not appear" with "If neither scalar-int-constant-expr nor
boz-literal-constant appears" such that the new list items read:
(2a) If neither scalar-int-constant-expr nor boz-literal-constant
appears and the enumerator is the first enumerator in enum-def, the
enumerator has the value zero.
(3a) If neither scalar-int-constant-expr nor boz-literal-constant
appears and the enumerator is not the first enumerator in enum-def,
it has the value obtained by adding one to the value of the
enumerator that immediately precedes it in the enum-def.
[7.7,100:30 Binary, octal, and hexadecimal literal constants]
In C7119, after "variable of type integer or real"
insert:
", as the value in an <enumerator>"
SUBMITTED BY: Steve Lionel
HISTORY: 24-101 m232 Submitted
24-101r1 m233 Passed by J3 meeting 233.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/015
TITLE: Coindexed objects in structure constructors
KEYWORDS: Pointer component, coindexed object, structure constructor
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider
TYPE realptrwrap
REAL,POINTER :: p
END TYPE
TYPE t
TYPE(realptrwrap) c
END TYPE
TYPE(realptrwrap) x[*]
TYPE(t) y
REAL,TARGET :: z[*]
x = realptrwrap(z[2]) ! (A) harmful
y%c = realptrwrap(z[2]) ! (B) harmful
x = realptrwrap(z) ! This assignment is valid and harmless.
y = t(x[2]) ! (C) harmful
(Aside: "harmful" means "copies a pointer from one image to another".)
The structure constructors in the statements (A) and (B) are invalid,
by combination of
R758 component-data-source is expr
or data-target
or proc-target
C7109 (R758) A data-target shall correspond to a data pointer
component; ...
R1038 data-target is expr
C1029 (R1038) A data-target shall not be a coindexed object.
However, the statement (C) has the same undesirable effect as (B), but
does not violate those constraints, and thus appears on the face of it
to be a valid statement.
Statement (C) would, however, be prohibited in a pure procedure, even
though it cannot cause side effects, merely undefined pointers.
This appears to be inconsistent. Is this deliberate?
ANSWER:
This apparent inconsistency was inadvertent.
Edits are provided to correct the issue.
EDITS to 24-007:
[93:21+] 7.5.10 Construction of derived-type values,
after the penultimate constraint C7109, insert new
constraint
"C7109a (R758) If <expr> is a coindexed object, it shall not have
a pointer component at any level of component selection."
[93:23-] Same subclause, after NOTE 1, insert new NOTE
"NOTE 1a
Although a coindexed object with a pointer subcomponent is not
the only way for the structure constructor to produce a value
with an undefined pointer subcomponent, copying a pointer from
another image is particularly likely to cause undiagnosed
incorrect results, and thus precluded in this context."
[34:1+] 4.3.3 Fortran 2018 compatibility, after paragraph 4,
insert new paragraph
"Fortran 2018 permitted a <component-data-source> in a structure
constructor to be a coindexed object with a pointer subcomponent.
This document does not permit such usage."
[35:8+] 4.3.4 Fortran 2008 compatibility, after paragraph 14,
insert new paragraph
"Fortran 2008 permitted a <component-data-source> in a structure
constructor to be a coindexed object with a pointer subcomponent.
This document does not permit such usage."
SUBMITTED BY: Malcolm Cohen
HISTORY: 24-149 m233 Submitted
24-149r1 m233 Passed by J3 meeting 233.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
--------------------------------------------------------------------
NUMBER: F23/016
TITLE: Segments associated with allocation
KEYWORDS: segment, allocate, coarray
DEFECT TYPE: Clarification
STATUS: Passed by J3 letter ballot
QUESTION:
Is it possible for a coarray to be allocated on an image in the
current team without there being a corresponding allocated coarray on
another active image in the current team?
For example, consider the program
PROGRAM ALLOCATION
IMPLICIT NONE
INTEGER :: I
REAL, ALLOCATABLE :: A[:]
ALLOCATE (A[*])
A = THIS_IMAGE()
SYNC ALL
DO I = 2,THIS_IMAGE()
IF (A[I]/=I) WRITE(*,*) "Value incorrect on image", I
END DO
DEALLOCATE (A)
END
Is it possible that an execution of the IF statement fails because the
coarray A has already been deallocated on image I?
ANSWER:
No, it is not possible.
For the ALLOCATE statement, the standard says
"execution on the active images of the segment (11.7.2) following
the statement is delayed until all other active images in the
current team have executed the same statement the same number of
times in this team."
That means that after execution of the ALLOCATE statement on an image,
the coarray is allocated on all the images (in the team).
For the DEALLOCATE statement, the standard says
"When a statement that deallocates a coarray or an object with a
coarray potential subobject component is executed, there is an
implicit synchronization of all active images in the current
team."
It then goes on to say
"A coarray shall not become deallocated on an image unless it is
successfully deallocated on all active images in this team."
That means that the DEALLOCATE statement cannot actually deallocate a
coarray on the executing image until all other active images have
reached that DEALLOCATE and confirmed that they can deallocate their
corresponding coarray.
Furthermore,
"execution on the active images of the segment (11.7.2) following
the statement is delayed until all other active images in the
current team have executed the same statement the same number of
times in this team"
means that after the DEALLOCATE statement execution is complete on one
image, the coarray is unallocated on all active images.
EDIT to 24-007.
None.
SUBMITTED BY: Reinhold Bader
HISTORY: 24-145 m233 Submitted
24-145r1 m233 Revised, passed by J3 meeting 233.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/017
TITLE: CFI_establish nonallocatable nonpointer null base address
KEYWORDS: CFI_establish
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
[524:29-31] 18.5.5.5 The CFI_establish function, p3 Description,
states that if CFI_establish is called with the base_addr a null
pointer, and attribute CFI_attribute_other (i.e. not a pointer or
allocatable), it establishes
"a C descriptor that has the attribute CFI_attribute_other but
does not describe a data object".
However, looking at the definition of base_addr in 18.5.3 [518:15-19],
it does not allow this:
"If the object is an unallocated allocatable variable or a pointer that
is disassociated, the value is a null pointer; otherwise... {cases
that are not null pointers}."
Note that CFI_establish is required to follow these rules, as p1
of 18.5.3 states
"The values of these members of a structure of type CFI_cdesc_t
that is produced by the functions and macros specified in this
document... shall have the properties described in this
subclause."
That is a contradiction, which means that when CFI_establish is called
with CFI_attribute_other, and base_addr is a null pointer, the program
is not standard-conforming and so any behaviour (including memory
corruption or program termination) may result.
Either this needs to be permitted in 18.5.3, or forbidden in 18.5.5.5.
Permitting it does not seem useful, as there seems to be little or
nothing one could possibly do with such a C descriptor.
How should this contradiction be resolved?
ANSWER:
This should not be permitted, as it is useless.
Edits are provided to explicitly forbid this.
EDITS to 24-007:
[524:15] 18.5.5.5 The CFI_establish function, p2 Formal Parameters,
attribute parameter,
Append new sentence
"If it is CFI_attribute_other, \cf{base_addr} shall not be a null
pointer."
[524:29-31] Same subclause, p3 Description,
After "for an unallocated allocatable"
change the comma to "or",
After "disassociated pointer"
delete ", or is... data object",
making that sentence read
"If \cf{base_addr} is a null pointer, the established C descriptor
is for an unallocated allocatable or a disassociated pointer."
{J3: The paragraph is a wall of text, so I won't regurgitate it here.}
{J3: The standard is contradictory here, so no compatibility issue.}
SUBMITTED BY: Malcolm Cohen
HISTORY: 24-150 m233 Submitted
24-150r1 m233 Passed by J3 meeting 233.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F23/018
TITLE: Correspondence of unallocated coarrays
KEYWORDS: corresponding, unallocated, coarray
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider
Program example
Real,Allocatable :: a[:]
Call sub(a)
Contains
Subroutine sub(x)
Real,Allocatable :: x[:]
Allocate(x[*])
... do something with A.
End Subroutine
End Program
According to 5.4.7 paragraph 3 corresponding coarrays have to be
"established (5.4.8)" in a team.
According to 5.4.8 paragraph 2,
"An unallocated allocatable coarray is not established."
Therefore the coarray A on image one does not correspond to the
coarray A on any other image.
However, 9.7.1.2 Execution of an ALLOCATE statement, paragraph 4,
requires
"If the coarray is a dummy argument, the ultimate arguments
(15.5.2.4) on those images shall be corresponding coarrays."
The program cannot satisfy that requirement, and thus does not
conform to the standard. That makes it impossible to allocate any
allocatable coarray that is a dummy argument.
Is this intended?
ANSWER:
No, this was not intended.
The definition of correspondence in subclause 5.4.7 is incomplete.
Edits are supplied to make the definition of correspondence complete,
extending it to cover unallocated allocatable coarrays. This let us
simplify and correct the requirements for allocation.
EDITS to 24-007:
[49:26] 5.4.7 Coarray, p3,
Change "For each coarray"
to "For each established coarray".
[49:27] After "in which it is established (5.4.8)."
insert new sentence
"For each unallocated coarray, there exists a
corresponding unallocated coarray with the same declared
type, rank, corank, and non-deferred type parameters on
each active image of the current team."
and then end the paragraph (the rest of paragraph becoming a
new paragraph).
[49:27] Insert a new paragraph in between the above insertion and the
rest of what was paragraph 3:
"For a named coarray that is not a dummy argument, its
corresponding coarrays are the ones with the same name in that
scoping unit. For a coarray that is a component at any level of
component selection, its corresponding coarrays are the same
components of the base object that has the same name in that
scoping unit. If a coarray component is a potential subobject
component of an array element, the array element for its
corresponding coarrays has the same position in array element
order on each image."
{Take the correspondence specification from 9.7.1.2 and put it here
where it belongs. Correspondence is not just for ALLOCATE!}
***ASIDE:
This makes paragraph 3 of 5.4.7 into these three paragraphs:
"For each established coarray on an image, there is a corresponding
coarray with the same type, type parameters, and bounds on every
other image of a team in which it is established (5.4.8). For each
unallocated coarray, there exists a corresponding unallocated
coarray with the same declared type, rank, corank, and non-
deferred type parameters on each active image of the current
team.
For a named coarray that is not a dummy argument, its
corresponding coarrays are the ones with the same name in that
scoping unit. For a coarray that is a component at any level of
component selection, its corresponding coarrays are the same
components of the base object that has the same name in that
scoping unit. If a coarray component is an ultimate component of
an array element, the array element for its corresponding coarrays
has the same position in array element order on each image.
If a coarray is an unsaved local variable of a recursive
procedure, its corresponding coarrays are the ones at the same
depth of recursion of that procedure on each image."
***END ASIDE.
[49:30] Same subclause, paragraph 4,
After "The set of corresponding"
insert "established",
making the whole sentence read
"The set of corresponding established coarrays on all
images in a team is arranged in a rectangular pattern."
{Unallocated coarrays are not arranged in any pattern.}
[148:32-40] In "9.7.1.2 Execution of an ALLOCATE statement", replace
the third sentence "If the coarray is a..." to the end of
the paragraph with
"The coarray shall be corresponding (5.4.7) on those images."
{If we got the definition of correspondence right, that is all we need
to say. It would be inappropriate to define what correspondence means
in the middle of the ALLOCATE statement execution.}
[148:40+] Insert new paragraph
"If an allocation specifies a coarray, the same ALLOCATE statement
shall be executed on every active image of the current team. If
the coarray is an unsaved local variable of a recursive procedure,
the execution of the ALLOCATE statement shall be at the same depth
of recursion of that procedure on those images."
{The first requirement actually follows from the segment rules, but
stating it explicitly means the reader does not have to go off and
prove a theorem. The second requirement is the last sentence of the
existing p4, with slightly simplified wording.}
SUBMITTED BY: John Reid and Reinhold Bader.
HISTORY: 23-219 m231 Submitted
23-219r1 m231 Rejected
24-146 m233 Revised but not processed
24-178 m234 Revised again
24-178r1 m234 Passed by J3 meeting 234.
25-133 m236 Passed by J3 letter ballot #40
----------------------------------------------------------------------
More information about the J3
mailing list