From dtm@castle.ed.ac.uk Sat Aug 20 12:51:10 1994
Received: from sun2.nsfnet-relay.ac.uk by dkuug.dk with SMTP id AA22034
  (5.65c8/IDA-1.4.4j for <sc22wg5@dkuug.dk>); Sat, 20 Aug 1994 12:51:10 +0200
Via: uk.ac.edinburgh.castle; Sat, 20 Aug 1994 11:50:11 +0100
Date: 20 Aug 94 11:49:58 BST
From: jwagener@amoco.com
Subject: X3J3 letter ballot on three items
To: sc22wg5@dkuug.dk
Sender: dtm@castle.ed.ac.uk
Message-Id: <9408201150.aa01173@uk.ac.ed.castle>
X-Charset: ASCII
X-Char-Esc: 29

This is a formal letter ballot for X3J3 members.  Other WG5 members are
welcome, indeed encouraged, to submit comments also.


======== X 3 J 3   L E T T E R   B A L L O T   ON   3   I T E M S ========
(And see separate email note for additional background concerning this ballot.)

Ballot period is 1 Sep 94 to 15 Sep 94.
Send vote, by email and by 15 Sep 94, to Jerry Wagener, jwagener@amoco.com

At X3J3 meeting 130, three technical items were formally approved for
inclusion in the 009 document with status "approved by X3J3, pending the
results of a two-week X3J3 letter ballot following the meeting".  This is that
letter ballot, which is in three parts below - please vote on each part.

The three items are allocatable derived-type components (94-269r2),
user-defined elemental procedures (94-245r3), and automatic deallocation of
allocatable arrays (94-270r3).  The complete text of all three of these
documents is attached to this letter ballot. 

Part 1 - allocatable derived-type components: 
        __ approve meeting action on 94-269r2, without comments 
        __ approve meeting action on 94-269r2, with comments (attached)
        __ disapprove meeting action on 94-269r2, with reasons (attached)

Part 2 - user-defined elemental procedures: 
        __ approve meeting action on 94-245r3, without comments 
        __ approve meeting action on 94-245r3, with comments (attached) 
        __ disapprove meeting action on 94-245r3, with reasons (attached)

Part 3 - automatic deallocation of allocatable arrays:
        __ approve meeting action on 94-270r3, without comments
        __ approve meeting action on 94-270r3, with comments (attached)
        __ disapprove meeting action on 94-270r3, with reasons (attached)



                                                                   <signed>


============ t e x t    o f    94-269r2    f o l l o w s ==============
                                                                 X3J3/94-269r2


Subject:	Text for X3J3/009 re:  Allocatable Components in Structures (B3)
References:	WG5-N930, Resolutions of the Berchtesgaden WG5 Meeting, B9
		WG5-N931, Requirements for Allowing Allocatable derived-type
                Components

Revision history: 94-269r2, resolve comments
		94-269r1, move most initial status to 94-270, fix object init
                         conflict, editorial fixes
		94-269,  specify initial status, use "ultimate component"
                         classification
		WG5-N1040, revised to resolve received comments
		94-202r2 remove allocatable entities from COMMON, do not
                         specify a storage unit; clarify/simplify constructors
                         (revised post-meeting per meeting 129 comments)
		94-202r1 provide restriction for entity-decls, add constructors
		94-202   original presentation, May 1994 (meeting 129)

Requirement Title: B9/B3 Allocatable derived-type components

Status:	X3J3 consideration in progress

Technical Description:
	Currently, the ALLOCATABLE attribute is limited to local named array
data entities.  One cannot have allocatable components of derived-type
objects, nor allocatable dummy arguments or function return values.  There is
a requirement from WG5 that these restrictions be removed, that ALLOCATABLE be
extended and regularized. 
	In addition, if an ALLOCATABLE object is still allocated when it goes
out of scope, its allocation status becomes undefined.  There is a desire that
the deallocation be provided "automatically" by the processor.  That is
addressed in a separate paper (X3J3/94-270r2). 
	The current paper provides a major step towards ALLOCATABLE arrays as
full, first-class entities.  It provides for them to appear as components of
derived types, as per WG5-N931, "Requirements for Allowing Allocatable
Derived-type Components". 
	Still outstanding from the general request:
		- ALLOCATABLE dummy arguments and function return values
		- ALLOCATABLE strings
		- ALLOCATABLE derived types (needs Parameterized Derived Types)
While these are mostly fairly straightforward, a large number of edits appear
to be required.  Due to the shortage of time, we recommend that this
development be undertaken for Fortran 2000. 
	Per direction from X3J3, this proposal does not provide for allowing
ALLOCATABLE objects, nor derived type objects with ALLOCATABLE components in
COMMON or EQUIVALENCE. 

Motivation:
	ALLOCATABLE provides functionality which shares much with that of the
POINTER features.  Indeed, the underlying implementation is probably nearly
identical, with one important difference.  The address pointer implicit in
ALLOCATABLE objects is not accessible to the user.  ALLOCATABLE objects,
therefore, cannot be aliased with other objects as a result of pointer
assignments.  For this reason, they behave much better than pointers with
respect to optimization. 
	Given the benefits of ALLOCATABLE, it appears advisable to extend the
facility to handle derived type components as well as normal variables.  The
extension introduces little additional complexity into either the language
definition or implementation; in fact, one can argue that the generalization
serves to remove an arbitrary restriction from the language. 
	The duties of the implementor follow directly from current practice. 
If a local object has the ALLOCATABLE attribute, the implementation must
arrange to set the object to non-allocated status at the time that the object
is created.  This duty is now extended to components of derived type objects. 
In addition, if a derived type object with an ALLOCATABLE component is itself
created via an ALLOCATE statement, the component must be set to non-allocated
status as part of the creation. 
	There exists some complication with regards to constructors.  There is
no "null" value for an allocatable object, so the constructor must specify an
actual value set for an allocatable component.  (This will generally be an
array constructor with an implied DO to provide the right number of elements.)
(Note that, even though "assignment semantics" apply, this value cannot be
given as a scalar, as there is no size given in the type definition.)
	The value of the constructor will include the allocatable component in
an "allocated" state with the indicated contents.  Note that the rules of
assignment for allocatable arrays involve copying the contents, not the
implicit pointer.  Thus, if the constructor is used in an assignment
statement, the allocatable components of the target variable must already be
allocated. 
	Lastly, because allocation cannot be done prior to execution,
allocatable components cannot be initialized in DATA statements or with =
initialization. 
	(Note that some of these conditions may be changed slightly if we
approve the proposal for constructors with keyword and optional fields.)

Detailed EDITS:
	{{note: edits are marked with a brief comment about the particular
                subject area being addressed.  In some cases, a subject area
                is relevant but requires no edits; in such cases, a null edit
	        (plus comment) is given. }}

[throughout]	{general nomenclature}
	{no problem.  The Standard references the term "allocatable array"
         throughout.  There is no problem, in general, with this terminology
         applying equitably to either data entities or to components; so no
         pervasive change is required.}

Subclause 4.4
[32:28] {make allocatable components ultimate}
	after: "Ultimately, a derived type is resolved into ultimate
               components that are"
	change:	"either of intrinsic type"
	to:	"of intrinsic type, are allocatable,"

Subclause 4.4.1
[33:20] {definition of component-attr-spec}
	after:	"R427  component-attr-spec        is    POINTER"
	add new line:
		"                                or ALLOCATABLE"

[33:26]
	add a new constraint following the third constraint of R427:
		"Constraint: POINTER and ALLOCATABLE must not both appear in
                             the same component-def-stmt."

[33:26+] {{WG5: Since allocatable components prohibit appearance in
                storage-associated contexts, do not allow sequence types to
                contain allocatable components.}}
	add a new constraint following the above:
		"Constraint: The ALLOCATABLE attribute must not be specified if
                             SEQUENCE is present in the derived-type-def."

[33:31-32] {WG5(reworded):dimension info} in the first constraint of R429,
	change:	"If the POINTER attribute is not specified"
	to: "If neither the POINTER attribute nor the ALLOCATABLE attribute is
             specified"

[33:33] {WG5(reworded):dimension info}
	in the second constraint of R429,
	change: "POINTER attribute" to "POINTER attribute or the ALLOCATABLE
                attribute"

[33:38+] {default initialization, per 94-138}
	after:	"the POINTER attribute must not appear"
	add:	"and the ALLOCATABLE attribute must not appear"

[33:39] {sequence types}
	{{WG5: No changes needed.  A sequence type cannot have allocatable
               components.}}

[34:2] {when one needs to have "::" in a component definition}
	change:	"or both"
	to	"the ALLOCATABLE attribute, or any combination thereof"

[35:35+] {edits to object initialization proposal in 94-009.006}
	in paragraph 3 (immediately following the first example in this edit),
	after:	"If a component is of intrinsic type and is not"
	insert:	"allocatable or"
	{{before "a pointer, a default initial value may be specified..."}}
	later in the same paragraph,
	after:	"If the component is of derived type and does not have the"
	replace:	"pointer attribute"
	with:	"ALLOCATABLE attribute or POINTER attribute"

[35:35+] {examples}
	add new paragraphs:
	"A derived type may have a component that is allocatable.  For example:

		TYPE STACK
			INTEGER :: INDEX
			INTEGER, ALLOCATABLE, DIMENSION(:) :: CONTENTS
		END TYPE STACK

	  For each variable of type STACK, the shape of the component CONTENTS
          is determined by execution of an ALLOCATE statement."

Subclause 4.4.4
[37:28] {constructors}{{WG5: Interaction with 94-009.006 in last sentence of
                              this addition}}
	Add, at the end of this subclause, new paragraphs:
	"Where a component of the derived type is an allocatable array, the
corresponding constructor expression must evaluate to an array.  The value of
the constructor will have a component that is allocated (has an allocation
status of allocated), and with contents as given by the constructor
expression.  Note that the allocation status of the allocatable component is
available to the user program if the constructor is associated with a dummy
argument, but generally not for other uses.  Note, also, that when the
constructor value is used in assignment, the corresponding component of the
target must already be allocated. 

Where a derived type contains an ultimate allocatable component, the
constructor must not appear as a data-stmt-constant in a DATA statement
(5.2.9), as an initialization-expr in an entity-decl (5.1), or as an
initialization-expr in a component-initialization (4.4.1)."

Subclause 5.1
[40:5] {=initialization}
	after:	"an allocatable array,"
	add:	"a derived-type object containing an ultimate allocatable
                 component,"

[40:20] {addition to constraint so it is clear they cannot be initialised at
         compile time}
	after:	"allocatable arrays,"
	add: "derived-type objects containing an ultimate allocatable
              component,"

Subclause 5.1.2.3
[44:24+] {edit to interpretation edit, paper 94-274r1}
	change:	"a stat-variable"
	to:	"an allocate-object or stat-variable"

Subclause 5.1.2.4.3
[46:8] {allocatable arrays are no longer necessarily named}
	in the first line of the second paragraph, change: "a named array" to
        "an array"

[46:10] {shape of an allocatable component can also be determined by a
         structure constructor}
	add to end of sentence:
	"or evaluation of a structure constructor for a derived type with an
         allocatable component"

[46:11] {where & how you can declare ALLOCATABLEs}
	after:	"in a type declaration statement"
	add:	", a component definition statement,"

[46:13] {ditto}
	after:	"in a type declaration statement,"
	add:	"a component definition statement,"

[46:15] {ditto}
	after:	"type declaration statement"
	add:	"or a component definition statement"

Subclause 5.1.2.9
[48:24] {storage units, sequence}
	{WG5: This change has been deleted as unnecessary since derived type
              objects containing allocatable components cannot appear in
              COMMON or EQUIVALENCE}. 

Subclause 5.2.9
[52:34] {DATA statement restrictions}
	change:	"or an allocatable array"
	to:     "an allocatable array, or a derived-type object containing an
                 ultimate allocatable component"

Subclause 5.4
[56:11] {WG5: do not allow allocatable components in NAMELIST}
	change:	", or an allocatable array"
	to:	", an allocatable array, or a derived-type object containing
                   an ultimate allocatable component"
Subclause 5.5.1
[57:1] {WG5: do not allow allocatable components in EQUIVALENCE}
	after:	"an allocatable array,"
	add: "a derived-type object containing an ultimate allocatable
              component,"

Subclause 5.5.2
[58:30] {{WG5: allocatable components are not allowed in COMMON since they are
               excluded from sequence types}}

Subclause 5.5.2.3
[59:42+] {Common Association}
	{{no edit needed; not allowed in COMMON}}

Subclause 6.1.2
[63:8] {corresponding restriction to that preventing array ops on pointer
        components}
	after:	"attribute"
	add:	"and must not have the ALLOCATABLE attribute"

Subclause 6.3.1
[67:16] {allocate statement}
	{ok - because POINTER components were allowed}

Subclause 6.3.1.1
[68:1+] {allocation of allocatable arrays - initial status}
	{ok, existing text appears to be sufficient}

[68:7+] {{WG5: Specify initial state of allocatable components after ALLOCATE}}
	Add new paragraph at the end of this subclause:
"If an object of derived type is created by an ALLOCATE statement, any
ultimate allocatable components have an allocation status of not currently
allocated."

Subclause 6.3.3.1
[69:8] {deallocation}
	add footnote: "Allocatable array components of derived-type objects
                       with the SAVE attribute also retain their allocation
                       status."
	{{note: similar issue for 69:29, for pointers }}

[69:9] add list items and renumber
	"(2) An allocatable array that is part of the return value of a
             function,
	 (3) An allocatable array that is part of a dummy argument,"

Subclause 7.1.6.1
[77:40] {{remove derived-type constructors with allocatable array components
         from initialization exprs}}
	after: "(3) A structure constructor where each component is an
                    initialization expression"
	add:	"and no component has the ALLOCATABLE attribute"

Subclause  7.5.1.5
[91:20] {interpretation of intrinsic assignment}
	after:	"nonpointer components."

	add: "Note that for allocatable components the component in the
              variable being defined must already be allocated, and the shapes
              of the corresponding allocatable components of the variable
              being defined and the expression must be the same."
  
Subclause 9.4.2
[124:17] {we do not allow derived-types with pointer components in i/o
          statements, neither should we allow ones with allocatable components}
	after:	"If a derived type ultimately contains a pointer component"
	add:	"or allocatable component"

Annex A
[254:12-13] {Fix glossary copy of the definition of an allocatable array}
	change:	"A named"
	to:	"An"
	append to end of definition:
		"An allocatable array may be a named array or a structure
                 component"

[261:21-22] {Fix glossary copy of the definition of ultimate component}
	after:	"a component that is of intrinsic type"
	add:	", has the ALLOCATABLE attribute,"

[261:23]
	after:	"does not have the"
	add:	"ALLOCATABLE attribute or"

add to Rationale Section:
------------------------------
5.1.2.9 ALLOCATABLE attribute

	Allocatable arrays provide a degree of flexibility intermediate
between that of automatic arrays and pointers.  The bounds of an automatic
array can be calculated on non-constant values, but only at scope entry. 
Often, this is not sufficiently powerful; nor does it provide for SAVEd arrays
whose size is not given by a constant expression.  Pointers do provide the
facility to arbitrarily determine the array bounds by execution of an ALLOCATE
statement.  Because of the pointer assignment statement, pointers are a little
less closely controlled than allocatable arrays.  More than one pointer may be
associated with a given object, a condition known as "aliasing" which can
negatively impact optimizing compilers.  Pointers also allow memory leaks if
not properly deallocated. 
	Array variables, and components of derived types, can be specified as
ALLOCATABLE when it is desired to calculate their size as a function of some
value determined during execution. 
	Explicit initialization of allocatable arrays is not permitted for
SAVEd variables, because such initialization may take place prior to
execution, but the ALLOCATE action only occurs during execution. 
	Input/output of derived types containing allocatable components is not
permitted.  This is because the storage of an allocatable component is
typically far removed from that of the other derived type components, so it
would be a non-trivial burden to the implementor for unformatted i/o.  Also,
for derived types containing allocatable components, as for derived types
containing pointer components, the i/o action desired by the user is unlikely
to be that which can be provided automatically.  User-defined i/o of derived
types is not part of this standard but we wish to avoid adding a facility
which will be little used and likely to conflict with the addition of the
proper facility in a later revision of the standard (or as a vendor
extension). 
	Allocatable arrays were not permitted in storage-associated contexts
(NAMELIST, COMMON, EQUIVALENCE) in Fortran 90.  This restriction still holds,
and thus objects of derived type containing allocatable components are also
not permitted in such contexts.  For this reason, and because the primary
purpose of SEQUENCE is to allow derived-type objects to appear in such
contexts, allocatable components are not permitted in sequence derived types. 


============ t e x t    o f    94-245r3    f o l l o w s ==============

                                                               X3J3/94-245r3

Elemental references to pure procedures
Revision of X3J3/94-245

Based on discussions at meeting 130, restrictions were added to non-intrinsic
elemental functions that prohibit passing dummy procedures as arguments to
elemental functions, prohibit passing elemental functions as dummy procedures,
prohibit recursive elemental procedures, and added an example to chapter 14.

Rationale
Elemental functions provide the programmer with expressive power and the
processor with additional opportunities for efficient parallelization.

Extending the concept of elemental procedures from intrinsic to both intrinsic
and user-defined procedures is very much analogous to, but simpler than,
extending the concept of generic procedures from intrinsic to both intrinsic
and user-defined procedures.  Generic procedures were introduced to intrinsic
procedures in Fortran 77 and extended to user-defined procedures in Fortran
90.  Elemental procedures were introduced to intrinsic procedures in Fortran
90 and, especially because of their usefulness in parallel processing, it is
quite natural that they be extended in Fortran 95 to user-defined procedures. 

Technical Description
The extension of elemental to user-defined procedures is straightforward.  A
minimal facility is proposed here, that involves a procedure's arguments being
elemental. 

A user-defined elemental procedure must be a pure procedure, having both the
PURE keyword, and the ELEMENTAL keyword.  All dummy arguments must be scalar
and must not be pointers. 

The actual arguments in a reference to an elemental procedure must all be
conformable.  Note that a scalar is conformable to any shape array, and thus
any actual argument may be scalar; an actual argument must be scalar if it is
associated with a dummy argument used in a specification expression in the
procedure definition. 

To be referenced elementally, the procedure must have an explicit interface. 
This allows there to be no change in the rules for how specific procedures
differ and a simple change (addition) to the rules for resolving generic
overloads: if there is no specific match the processor looks for an elemental
match (see section 14.1.2.4.1). 

One way of extending this feature in the future is to specify an ELEMENTAL
attribute for any individual dummy argument(s) in lieu of the ELEMENTAL
procedure keyword; the ELEMENTAL keyword included here may be considered to
automatically give each dummy argument the elemental attribute. 


Detailed Edits
section 7.1.3 - add a fifth paragraph
       A defined elemental operation is a defined operation for which the
       function is elemental (12.yyyy).
section 7.1.5 - change title
       change "intrinsic"  to "elemental"
section 7.1.5 - new first sentence
       An elemental operation is an intrinsic operation or a defined elemental
       operation.
section 7.1.5 - second paragraph
       change "intrinsic" to "elemental"
section 7.1.7 - penultimate paragraph
       change "intrinsic binary" to "elemental binary"
section 7.1.7 - last paragraph
       change "intrinsic unary" to "elemental unary"
section 7.3.1 - in item (5) replace "The" with
       (a) The function is elemental, or
       (b) The

section 7.3.2 - in item (5) replace "The" with
       (a) The function is elemental and x1 and x2 are conformable, or
       (b) The
section 7.5.1.3 - add the following sentence to the paragraph
       A defined elemental assignment statement is a defined assignment
       statement for which the subroutine is elemental (12.yyyy).
section 7.5.1.6 - in item (5) replace "The" with
       (a) The subroutine is elemental and either x1 and x2 have the same
            shape or 
                    x2 is scalar, or
       (b) The
section 7.5.1.6 - add as a last paragraph
       If the defined assignment is an elemental assignment and the variable 
       in the assignment is an array, the defined assignment is performed
       element-by-element, in any order, on corresponding elements of variable
       and expr.  If expr is a scalar it is treated as if it were an array of
       the same shape as variable with every element of the array equal to the
       scalar value of expr.
section 7.5.3.2 - third paragraph
       change "elemental intrinsic operation" to "elemental operation"
section 8.1.1.2 - last sentence
       change "12.4.2, 12.4.3, 12.4.4, 12.4.5" to "12.4.2, 12.4.4, 12.yyyy"
section 12.1.1 - last paragraph
       replace "an intrinsic" with "a",
       and replace the references with "12.yyyy"
section 12.2 - first paragraph (as modified by 94-149r2)
       after "whether or not it is pure," add "whether or not it is
       elemental,"
section 12.3.1.1 - Add to list in part 2
       f) The ELEMENTAL keyword
section 12.4.1.1 - third paragraph
       change "12.4.3, 12.4.5" to "12.yyyy"
section 12.4.1.1 - insert phrase in last sentence of fourth-from-last
       paragraph
       change "procedure is referenced" to "procedure is nonelemental and is
       referenced"
section 12.4.1.1 - insert phrase in last sentence
       change "dummy argument" to "dummy argument of a nonelemental procedure"
section 12.4.2 - add to the paragraph
       A reference to an elemental function (12.yyyy) is an elemental
       reference if one or more actual arguments are arrays and all array
       arguments have the same shape.
section 12.4.3 - delete entire section
section 12.4.4 - add to the paragraph
       A reference to an elemental subroutine (12.yyyy) is an elemental
       reference if all actual arguments corresponding to INTENT(OUT) and
       INTENT(INOUT) dummy arguments are arrays that have the same shape and
       the remaining actual arguments are conformable with them.
section 12.4.5 - delete entire section
section 12.5.2.2 - add to syntax rule R1217a (as modified by 94-149r2)
                          or  ELEMENTAL
       Constraint:  If ELEMENTAL is present, PURE must be present.
       
       Constraint:  If ELEMENTAL is present, RECURSIVE must not be present.
section 13.1 - first paragraph
       change "elemental function" with "elemental intrinsic function"
section 13.2 - replace sections 13.2.1 and 13.2.2 with
       Elemental intrinsic procedures behave as described in 12.yyyy.
section 14.1.2.4.1 - insert a new rule (2), and renumber accordingly
       (2)   If (1) does not apply, if the reference is consistent with an
             elemental reference to one of the specific interfaces of an
             interface block that has that name and either is contained in the
             scoping unit in which the reference appears or is made accessible
             by a USE statement contained in the scoping unit, the reference
             is to the specific elemental procedure in that interface block
             that provides that interface.  Note that the rules in 14.1.2.3
             ensure that there can be at most one such specific interface.  

[footnote 1]
       
       [footnote 1.  These rules allow specific instances of a generic
       function to be used for specific array ranks and a general elemental
       version to be used for other ranks.  Given an interface block such
       as:
       
             INTERFACE  RANF
       
                    ELEMENTAL  FUNCTION SCALAR_RANF(X)
                    REAL  X
                    END
       
                    FUNCTION VECTOR_RANDOM(X)
                    REAL  X(:)
                    REAL  VECTOR_RANDOM(SIZE(X))
                    END
       
             END  INTERFACE  RANF
       
       and a declaration such as:
       
             REAL  A(10,10), AA(10,10)
       
       then the statement
       
             A = RANF(AA)
       
       is an elemental reference to SCALAR_RANF.  The statement
       
             A(1,1:5) = RANF(AA(6:10,2))
       
       is a non-elemental reference to VECTOR_RANDOM.     ]

section 14.1.2.4.1 - new item (3)
       change ""If (1) does" to "If (1) and (2) do"
section 14.1.2.4.1 - new item (4)
       change ""If (1) and (2) do" to "If (1), (2), and (3) do"
section 14.1.2.4.1 - new item (5)
       change ""If (1), (2), and (3) do" to "If (1), (2), (3), and (4) do"
annex A - elemental
       remove the word "intrinsic"
       and replace the references with "12.yyyy"
section 12.yyyy - immediately after 12.xxxx (Pure procedures)
       12.yyyy  Elemental procedures
       
       12.yyyy.1  Elemental procedure declaration and interface
       
       An elemental procedure is an elemental intrinsic procedure or  a
       procedure that is defined with the prefix-spec  ELEMENTAL.
       
       Procedures defined with the keyword ELEMENTAL must satisfy the
       additional constraints:
       
       Constraint:  All dummy arguments must be scalar and must not have the 
                    POINTER attribute.
       
       Constraint:  For a function, the result must be scalar and must not
                    have the POINTER attribute.
       
       Constraint:  A dummy-arg must not be *.
       
       Constraint:  A dummy-arg must not be a dummy procedure.
       
       Constraint:  A procedure with the elemental keyword must not be used
                    as an actual argument.
       
       Note that an elemental procedure is a pure procedure and all of the
       constraints for pure procedures also apply.
       
       12.yyyy.2  Elemental function arguments and results
       
       <this paragraph is largely taken from what was originally section
       13.2.1>
       If a generic name or a specific name is used to reference an elemental
       function, the shape of the result is the same as the shape of the
       argument with the greatest rank.  If the arguments are all scalar, the
       result is scalar.  For those elemental functions that have more than 
       one argument, all arguments must be conformable.  In the array-valued
       case, the values of the elements, if any, of the result are the same
       as would have been obtained if the scalar-valued function had been
       applied separately, in  any order, to corresponding elements of each
       argument. For an intrinsic function, an argument called KIND must be
       specified as a scalar integer initialization expression and must
       specify a representation method for the function result that exists on
       the processor.  For a non-intrinsic function, an actual argument must
       be scalar if it is associated with a dummy argument that is used in a
       specification expression.
       
       <this example was in the original section 12.4.3>
       An example of an elemental reference to the intrinsic function MAX:
       if X and Y are arrays of shape (m,  n), 
       MAX  (X,  0.0,  Y) 
       is an array expression of shape (m,  n) whose elements have values  
       MAX (X (i, j), 0.0, Y (i, j)), i = 1, 2, ..., m, j = 1, 2, ..., n
       
       12.yyyy.3  Elemental subroutine arguments
       
       <this paragraph was originally section 13.2.1, with "intrinsic"
       deleted>
       An elemental subroutine is one that is specified for scalar arguments,
       but in a generic  reference may be applied to array arguments.  In a
       reference to an elemental subroutine, either all actual arguments must
       be scalar, or all  INTENT  (OUT)  and INTENT  (INOUT)  arguments must
       be arrays of the same shape and the remaining arguments must be
       conformable with them.  In the case that the INTENT (OUT) and INTENT
       (INOUT) arguments are arrays, the values of the elements, if any, of
       the results are the same as would be obtained if the subroutine with
       scalar arguments were applied separately, in any order, to
       corresponding elements of each argument.

============ t e x t    o f    94-270r3    f o l l o w s ==============
                                                                X3J3/94-270r3


Subject:     Automatic deallocation of ALLOCATABLE objects
References:  WG5-N930, Resolutions of the Berchtesgaden WG5 Meeting, B9
             WG5-N931, Requirements for Allowing Allocatable derived-type
             Components

Revision History:   94-270r1, examples added, initial status text moved here
                              from 94-269
                    94-270, specific edits added
                    94-211, original presentation, May 1994 (meeting 129)

Requirement Title: B9/B3 Allocatable derived-type components

Status:             For consideration

Technical Description:
       Require automatic deallocation of  unSAVEd allocatable objects on scope
       exit.

Motivation:
       Currently, the standard does not provide for automatic deallocation of
allocatable objects, even when they are local non-static variables.  When such
objects go out of scope a memory leak can occur.
       The general handling of ALLOCATABLE is being regularised; removing
surprises is part of the task.  Further, the general thrust of the Fortran
committee is to work to eliminate memory leakage opportunities. 
       The main reason for the current situation appears to be a concern about
performance.  The addition of automatic (i.e.  managed by the processor rather
than the user) deallocation will not have a major performance impact.  The
actual deallocation is what takes time, and that must occur in any event if a
memory leak is to be avoided.  The proposed change merely adds a check on
whether the deallocation is required -- a few instructions at most, compared
with dozens of instructions for the actual deallocation. 
       Note further that we have already accepted the "overhead" of explicit
"initialisation" of the allocation state of allocatable variables.  This
initialisation was necessary to bring a semblance of order into the allocation
status.  By adding automatic deallocation, we not only remove a source of user
annoyance and surprise, but also simplify the language definition.  Currently,
there must be a third ("undefined") allocation state for allocatable objects
and fairly confusing words about the consequences of going out of scope with a
non- deallocated object. 
       Finally, as the language currently stands it is impossible to create
opaque data types which need a variable amount of storage without the
possibility of leaking memory.  In conjunction with the allocatable component
proposal (94- 269r2) automatic deallocation of allocatable objects provides
the user with this capability in a form which is safe to use. 

Detailed EDITS:

Subclause 6.3.3.1
[69:12-15] {allocation status} {{the third and fourth paragraphs of 6.3.3.1}}
       {{specify we lose the old allocatable array on each new instantiation
       if not SAVEd}}
       replace with:
       "Any other allocated allocatable array that is a local variable of a
       procedure, is not a subobject of a pointer, is not accessed by use
       association, is not part of a dummy argument, is not part of a
       function return value, and is not a variable accessed from the host
       scoping unit is deallocated (as if by a DEALLOCATE statement)."

[69:13+] {allocation status}
       {{allow modules to always SAVE their allocatable arrays, or to always
       initialise them (e.g. if they are implemented via overlay segments),
       but do not penalise the user by forbidding subsequent access}}
       add a new paragraph:
       "The allocation status of any other allocatable array that is a local
       variable of a module is processor-defined; the ALLOCATED intrinsic may
       be used to determine whether the array is still currently allocated or
       has been deallocated."

[69:15+] {deallocation action}
       {{Here we define deallocation of an object containing allocatable
       components to deallocate any of these which happen to be allocated. 
       Since this is described recursively, a nested tree of allocatable
       components will be deallocated bottom-up.  Note that a system which
       stores allocatable objects on a stack or which performs automatic
       garbage collection already satisfies this definition.}}
       insert new paragraph:
       "When a derived-type object is deallocated, any ultimate allocatable
       components that are currently allocated are deallocated.

[Footnote: in the following example:

    MODULE USER
        TYPE, PRIVATE :: VARYING_STRING
            CHARACTER,ALLOCATABLE :: VALUE(:)
        END TYPE
        TYPE USER
            PRIVATE
            TYPE(VARYING_STRING) NAME
            TYPE(VARYING_STRING),POINTER :: DETAILS(:)
        END TYPE
        ...
    END MODULE
    SUBROUTINE PROCESS_ONE_USER
        USE USER
        TYPE(USER) X
         CALL READ_USER(X)    ! Read user details into X
        ...                  ! Process the user
    END SUBROUTINE

on return from PROCESS_ONE_USER, X does not have the SAVE attribute and so
X%NAME%VALUE is deallocated.  However, X%DETAILS has the POINTER attribute and
so its target and any of the target~s components are not automatically
deallocated.]

Subclause 14.8
[252:37-253:4] {{remove undefined allocation status from the possibilities, to
                 avoid never-never land}}
       replace existing text with:
"(1)   Not currently allocated.  An allocatable object with this status must
       not be referenced, defined, or deallocated; it may be allocated with
       the ALLOCATE statement.  The ALLOCATED intrinsic returns .FALSE.  for
       such an object. 
 (2)   Currently allocated.  An allocatable object with this status may be
       referenced, defined, or deallocated; it must not be allocated.  The
       ALLOCATED intrinsic returns .TRUE.  for such an object. 

An allocatable array with the SAVE attribute has an initial status of not
currently allocated.  An ALLOCATE statement changes this status to currently
allocated; it then remains currently allocated until execution of a DEALLOCATE
statement. 

An allocatable array component of a derived-type variable that has the POINTER
attribute, or is a subobject of a pointer component, has no initial allocation
status, because it does not exist until brought into existence by the ALLOCATE
statement (or referred to by the pointer assignment statement). 

Any other allocatable array without the SAVE attribute that is a local
variable of a procedure, is not accessed by use association, is not part of a
dummy argument, and is not a variable accessed from the host scoping unit has
a status of not currently allocated at the beginning of each invocation of the
procedure.  During execution of the procedure its status may be changed by
execution of ALLOCATE and DEALLOCATE statements.  On exit from the procedure
by execution of a RETURN or END statement, if such an allocatable array is not
part of a function return value and has the status of currently allocated, it
is deallocated (as if by a DEALLOCATE statement). 

Any other allocatable array without the SAVE attribute that is a local
variable of a module has an initial status of not currently allocated.  If the
array has an allocation status of currently allocated on execution of a RETURN
or END statement resulting in no executing scoping unit having access to the
module it is processor-defined whether the array~s allocation status remains
currently allocated or the array is deallocated (6.3.3.1) as if by a
DEALLOCATE statement."

add to Rationale Section:
-------------------------
6.3.3.1 Deallocation of allocatable arrays
       Automatic deallocation of allocatable arrays (including allocatable
array components) provides the user with a safe method of creating opaque data
types of variable size which do not leak memory.  It also removes the burden
of manual storage deallocation both for simple allocatable arrays and for
allocatable components of non-opaque types. 
       The "undefined" allocation status of Fortran 90 meant that an
allocatable array could easily get into a state where it could not be further
used in any way whatsoever, it could not be allocated, deallocated,
referenced, defined, or even used as the argument to the ALLOCATED function. 
Removal of this status provides the user with a safe way of handling
allocatable arrays which he does not desire to be SAVEd, permitting use of the
ALLOCATED intrinsic function to discover the current allocation status of the
array at any time. 
==========================end of texts for ballots============================
