CVS difference for ais/ai-00162.txt

Differences between 1.3 and version 1.4
Log of other versions for file ais/ai-00162.txt

--- ais/ai-00162.txt	2003/11/27 02:01:11	1.3
+++ ais/ai-00162.txt	2003/12/07 05:00:29	1.4
@@ -1,4 +1,4 @@
-!standard 03.10.02 (13)                               98-10-02  AI95-00162/02
+!standard 03.10.02 (13)                               03-12-01  AI95-00162/03
 !class binding interpretation 96-09-10
 !status work item 98-10-02
 !status received 96-09-10
@@ -7,23 +7,19 @@
 !subject Anonymous access types and tasks termination/controlled type finalization
 
 
-!summary 98-10-02
+!summary
 
-A new master is defined which is associated with the completion of one or
-more subprogram calls, in a statement or a declaration, that have at least
-one formal access parameter whose actual parameter is an allocator.  This
-new master is responsible for one or more controlled objects or task
-objects created by anonymous allocators which are assigned to formal access
-parameters of one or more subprogram calls in the statement or declaration.
- Such a statement or declaration may execute one or more such masters.  An
-implementation is permitted to determine how many such masters such a
-statement or declaration will execute.
+A new kind of master is defined for objects associated with the evaluation of
+an allocator of an anonymous type, a function call, or an aggregate. The
+enclosing statement or declaration is the master of these anonymous objects.
+Finalization, task dependence, accessibility levels, and lifetimes for these
+objects are all defined in terms of this master.
 
-!question 98-10-02
+!question
 
 When an anonymous allocator, which is assigned to a formal access
 parameter, creates a task or creates a controlled object, who is the master
-of these things?  More specifically, which construct is responsible for
+of these things? More specifically, which construct is responsible for
 waiting for the task to terminate and for finalizing the task or the
 controlled object?
 
@@ -69,193 +65,298 @@
 Is the master of the anonymous allocator in either statement (2a or 2b)
 [new T or new CT]:
 -  the innermost enclosing (normal) master (1),
--  some construct associated with the innermost enclosing statement (2a or
-2b)
+-  some construct associated with the innermost enclosing statement (2a or 2b)
    [as described by 7.6.1(13)] or
 -  the called subprogram's body (3a or 3b)?
 
-!recommendation 98-10-02
+!recommendation
 
 (See summary.)
 
-!wording 98-10-02
+!wording
 
-There are three wording changes proposed.  The first wording change is to
-the second sentence of 7.6.1(3) to introduce the new master:
+In 3.10.2(3) replace the first two sentences with
+    "The accessibility rules, which prevent dangling references, are written
+     in terms of *accessibility levels*, which reflect the run-time nesting
+     of *masters* (see 7.6.1).
 
-"Leaving an execution happens immediately after its completion, except in
-the case of a master:  the execution of a task body, a subprogram_body, an
-entry_body and certain statements and the elaboration of certain
-declarations.  The execution of a statement is the execution of a master if
-the statement is a block_statement or an accept statement.  If a statement
-contains one or more anonymous allocators, then the execution of one or
-more parts of that statement which contain subprogram calls with anonymous
-allocators is the execution of one or more masters.  If a declaration
-contains one or more anonymous allocators, the elaboration one or more
-parts of that declaration which contain subprogram calls with anonymous
-allocators is the execution of one or more masters.  An anonymous allocator
-is an allocator that is the actual parameter in a subprogram call whose
-associated formal parameter is an access parameter."
-
-The second wording change is to 3.10.2(13) to account for the accessibility
-level of the allocator:
-
-"The accessibility level of the anonymous access type of an access
-parameter is the same as that of the view designated by the actual.  If the
-actual is an allocator, this is the accessibility level of the execution of
-the immediately enclosing statement or the elaboration of the immediately
-enclosing declaration (which is itself a master -- see 7.6.1)."
-
-The third wording change is to an Implementation Permission paragraph to
-subsection 7.6.1:
-
-"Implementations have the permission to determine how many actual masters
-are executed in the execution of a statement or the elaboration of a
-declaration that causes the execution of multiple subprogram calls with
-anonymous allocators."
-
-With the new wording for master, there is no need to change 7.6.1(13) to
-account for anonymous allocators since 7.6.1(4) will handle the task
-waiting and finalization for the "new" master.
-
-!discussion 98-10-02
-
-As the question states, there are three possibilities for the master of the
-task or a controlled object created by the anonymous allocator:
-1)      the innermost enclosing (normal) master
-2)      some construct associated with the innermost enclosing statement or
-       declaration
-3)      the called subprogram's body.
-
-Let's examine each alternative, starting with innermost enclosing (normal)
-master.  While this requires minimal (no) change to the language, it is
-clumsy in the presence of loops. If the anonymous allocator is inside a
-loop, one clearly wants to recover the storage associated with the
-anonymous allocator before going on to the next loop iteration.  This would
-require a block statement inside the loop just for encapsulating the
-statement with the subprogram call.
-
-The second alternative, some construct associated with the innermost
-enclosing statement, would introduce one of two options:
-a)      introduce a new master, namely a subprogram call with an anonymous
-       allocator
-b)      introduce a new "blocking point" in the execution of a statement
-       containing a subprogram call with an anonymous allocator
-
-Let's examine the first option, introducing a new master. The following is
-a  proposed wording change to 7.6.1(3) to introduce the new master:
-
-"Leaving an execution happens immediately after its completion, except in
-the case of a master:  the execution of a task body, a subprogram_body, an
-entry_body and certain statements and the elaboration of certain
-declarations.  The execution of a statement is the execution of a master if
-the statement is a block_statement or an accept statement.  If a statement
-contains one or more anonymous allocators, then the execution of one or
-more parts of that statement which contain subprogram calls with anonymous
-allocators is the execution of one or more masters.  If a declaration
-contains one or more anonymous allocators, the elaboration one or more
-parts of that declaration which contain subprogram calls with anonymous
-allocators is the execution of one or more masters.  An anonymous allocator
-is an allocator that is the actual parameter in a subprogram call whose
-associated formal parameter is an access parameter."
-
-An additional word change is needed in 3.10.2(13) to account for the
-accessibility level of the allocator:
-
-"The accessibility level of the anonymous access type of an access
-parameter is the same as that of the view designated by the actual.  If the
-actual is an allocator, this is the accessibility level of the execution of
-the immediately enclosing statement or the elaboration of the immediately
-enclosing declaration (which is itself a master -- see 7.6.1)."
-
-If the new wording for master is used, then it appears that there is no
-need to change 7.6.1(13) to account for anonymous allocators since 7.6.1(4)
-will handle the "new" master.  Some might argue this change as too strong,
-where pretty much anything is a master, and the concept loses its intuitive
-appeal.  The counter argument is that subprogram calls with anonymous
-allocators represent a (very) small subset of subprogram calls.
-
-This wording also appears to be unaffected by what statement or declaration
-the subprogram call with an anonymous allocator might appear.  And the only
-affect it appears to have on the context where it is used is to add more
-time to the execution of the enclosing statement or the elaboration of the
-enclosing declaration.  In particular, their appearance in a barrier
-condition are handled by the existing rules on entry calls, namely, such an
-anonymous allocator can not allocate a task object because that would
-violate 9.5.1(14) which prevents task activation.
-
-The second option, introducing a new "blocking point", would leave the
-enclosing block as the master of the task created by the anonymous
-allocator.  Instead this option would add words to 7.6.1(13) which says
-that any tasks created by an anonymous allocator in a subprogram call are
-waited for before proceeding to the next statement.  Some might argue that
-this introduces yet another exception to the rules on master-task
-dependency.  But more importantly, requiring that the task be awaited
-before going on to the next statement without considering the statement
-itself a master, we will get in trouble with the "terminate" alternative
-rules, which require that a task depend on some "completed master" for
-collective termination to kick in.
-
-The third alternative would make the called subprogram's body the master of
-the task or controlled object created by the anonymous allocator.  This is
-based on the concept the formal parameters of a subprogram should be
-considered locals of the subprogram, with the actual parameters being the
-initial expressions for the formals.  With this idea, the conceptual
-"frame" for the called subprogram is created at the start of the evaluation
-of the actuals, rather than after the evaluation is complete.  When the
-subprogram body returns, it must wait for the task to complete before
-returning, as usual.  This model matches the wording in 3.10.2(13) pretty
-well.  As a favor to implementors, an Implementation Permission would be
-added where an implementation may postpone waiting for such tasks until
-other finalization associated with other anonymous objects created by the
-subprogram call is performed (as defined by 7.6.1(13)). To support this
-alternative, at least two parts of the ARM that may be affected by wording
-change: 6.4(10) which describes the overall dynamic semantics of a
-subprogram call and 6.4.1(8,9) which describe the semantics of parameter
-association evaluation.  6.4(10) is very clear that the parameter
-association evaluations are done outside and separately from the execution
-of the subprogram body.  This is inconsistent with the normal relationship
-of a master and the resources that are dependent on the master.  It appears
-that this paragraph will need major changes.  If that is true, what other
-parts of the ARM would be affected by this change?  For example, isn't the
-dynamic semantics of parameter association evaluation for subprogram calls
-used as the model for entry calls and protected subprogram calls.  Does
-this mean that the protected subprogram body is blocked waiting for the
-task to complete?  I don't think so.  This alternative is beginning to
-appear very messy.
-
-It appears that the first option of the second alternative is best choice.
-
-Assuming the first option of the second alternative is selected,
-implementations should have the permission to determine how many masters to
-execute in the presence of multiple subprogram calls with anonymous
-allocators, as this example should illustrate:
+In 3.10.2(7), replace "enclosing master" with "enclosing unrestricted master".
 
-with P; use P;
-procedure Test2 is
-  function F (M: access T) return Boolean;
-  function G (N: access T) return Boolean;
-  procedure H (I, J: Boolean);
-  ...
-begin
-  ...
-  H (F (new CT), G (new CT));           -- (4)
-  ...
-end Test2;
+Delete the second sentence of 3.10.2(13).
+
+In 6.5(18), replace "master" with "unrestricted master".
+
+In 7.6.1(3), replace
+
+   ".. except in the case of a *master*: the execution of ... or an
+   accept_statement."
+
+with
+
+   ".. except in the case of a *master*. An *unrestricted master* is
+   the execution of a task_body, a block_statement, a subprogram_body,
+   an entry_body, or an accept_statement. A *restricted master*
+   is the execution of a statement, declaration, pragma, or
+   entry_barrier condition which is not an unrestricted master.
+
+Replace 7.6.1(13/1 - 13.1/1) with
+
+  A restricted master is a master of any anonymous object created as part of
+  its execution by the evaluation of an allocator of an anonymous access type,
+  a function call, or an aggregate except if the object is
+
+    - created as part of the execution of a more nested restricted master;
+
+    - created as part of a rename declaration which renames any part of the
+      object. In this case, the nearest enclosing unrestricted master of the
+      rename declaration is defined to be a master of the object; the
+      accessibility level of the object is defined to be the accessibility
+      level of this master.
+
+  or
+
+    - created by an allocator of an anonymous access type which is used to
+      initialize an access discriminant of another object. In this case, the
+      masters of the allocated object are defined to be masters of the
+      discriminated object; the accessibility level of the allocated object
+      is defined to be that of the discriminated object.
+      The allocated object is finalized when the discriminated object is
+      finalized. The storage occupied by the allocated object is deallocated
+      when the storage occupied by the discriminated object is deallocated.
+
+  For a statement, the finalization of such an anonymous object occurs
+      - when the statement is completed;
+  or
+      - immediately before beginning the execution of a nested statement;
+  or
+      - in the case of a potentially blocking operation, immediately before
+        the operation blocks the current task
+  , whichever occurs first. Otherwise, this finalization occurs when the entity
+  is completed.
+
+  The accessibility level of the anonymous object is the accessibility
+  level of this master.
+
+
+In 9.3(2), replace "master" with "unrestricted master".
+In 9.3(3), replace "master" with "unrestricted master".
+In 13.11(18), replace "master" with "unrestricted master".
+
+
+Add at the end of 13.11.2(17).
+
+  If the object being reclaimed has an access discriminant which designates
+  an object which which was created by an allocator of the (anonymous) type
+  of the access discriminant, then the designated object should also be
+  reclaimed.
 
-In the statement (4), the implementation should be permitted to execute one
-master, associated with the completion of the call to H, or to execute two
-masters, one associated with the completion of F and the other associated
-with the completion of G.  The following proposed Implementation Permission
-paragraph should be added to subsection 7.6.1:
-
-"Implementations have the permission to determine how many actual masters
-are executed in the execution of a statement or the elaboration of a
-declaration that causes the execution of multiple subprogram calls with
-anonymous allocators."
 
-!appendix 96-09-15
+!discussion
+
+The Problem
+-----------
+
+The language does not properly define the master of certain objects.
+These include anonymous objects associated with function calls, aggregates, and
+allocators of anonymous access types. Since this affects task dependence, the
+point at which finalization occurs, accessibility levels, and object lifetimes,
+this means that the run-time behavior of a program which creates such objects
+is unclear.
+
+The Solution
+------------
+
+A new master is defined for objects associated with the evaluation of an
+allocator of an anonymous type, a function call, or an aggregate. For these
+objects only, the enclosing statement or declaration acts as a master.
+Finalization, task dependence, accessibility levels, and lifetimes for these
+objects are all defined in terms of this master.
+
+This is not an incompatible change. This AI defines the run-time behavior
+of constructs whose behavior was previously undefined, but is otherwise
+consistent with the existing language definition.
+
+Alternative Solutions
+---------------------
+
+One could define the master of an object of the sort discussed in this AI
+to be the innermost enclosing garden-variety master (i.e. task_body,
+block_statement, subprogram_body, entry_body, or accept_statement).
+This approach might be simpler to describe, but the lifetimes of objects would
+be extended too far.
+
+The interactions with loops, in particular, would require that implementers
+stand on their heads in order to make life more difficult for users. In this
+example,
+
+  begin
+    for I in 1 .. 100 loop
+      Some_Procedure (Function_Call_Requiring_Finalization);
+    end loop;
+  end;
+
+neither users nor implementers want to accumulate 100 unfinalized function
+result temps before finalizing the first one.
+
+Other alternatives have been mentioned which only address special cases of
+the problem (e.g. for an allocator which is passed as an actual parameter
+of an anonymous access type, use the called routine as the master), but
+these do not make sense in the context of the more general problem.
+
+
+Implementation Issues
+---------------------
+
+An implementation must somehow keep track of whether a given
+access discriminant component "belongs" to the enclosing discriminated
+object. In this example
+
+     type Designated is ... ;
+     X : aliased Designated;
+
+     type T (Discrim : access Float) is limited null record;
+     type T_Ref is access T;
+     Ptr1 : T_Ref := new T (Discrim => X'Access);
+     Ptr2 : T_Ref := new T (Discrim => new Designated);
+
+     procedure Free is new Ada.Unchecked_Deallocation (T, T_Ref);
+   begin
+     Free (Ptr1);
+     Free (Ptr2);
+
+finalization and deallocation of Ptr1.all does not include
+finalization and deallocation of Ptr1.Discrim.all. On the other hand,
+finalization of Ptr2.all includes finalization of Ptr2.Discrim.all (even
+if type T is has a user-defined Finalize routine) and Ptr2.Discrim.all is also
+deallocated when Ptr2.all is deallocated.
+
+Only a non-component object of the discriminated type can "own" the object
+designated by its discriminant. For a non-allocated object, ownership is known
+statically. Thus, distributed overhead need only be incurred in the case of an
+allocated object with one or more access discriminants. One implementation
+strategy would be to prepend this information to the allocated object in
+much the same way that some implementations prepend dope vectors for allocated
+arrays when the designated subtype is unconstrained.
+
+Open Issues
+-----------
+None have been identified.
+
+Technical Notes
+---------------
+
+1) In this example
+
+          My_Array_Of_Tasks :
+              Task_Vector (1 .. Function_Call_Requiring_Finalization.Field);
+
+   , the declaration is the master of the function result object but is
+   not the master of the tasks. This declaration, like every declaration,
+   is now a master, but 9.3(3) now refers to "unrestricted masters" and the
+   declaration is a "restricted master".
+
+   The distinction between two kinds of masters (tentatively called
+   "unrestricted" and "restricted") is necessary because some places
+   in the manual need to refer to *all* masters (e.g. the discussion in
+   7.6.1(4) of the finalization of a master or the definition in
+   3.10.2(6) of the accessibility level of a master) while other places
+   need to refer only to old-style (i.e. unrestricted) masters (e.g. 3.10.2(7)
+   and 9.3(3)). An earlier (uncirculated) version of this AI attempted to
+   simply use the term "master" in both cases, but this didn't work well.
+
+   The terms "unrestricted master" and "restricted master" are not themselves
+   very satisfactory. Does anyone have a better alternative?
+
+2) It seems somewhat odd that
+     X : Some_Access_Type := new T1 (Access_Discrim => new T2);
+   and
+     subtype S is T1 (Access_Discrim => new T2);
+     X : Some_Access_Type := new S;
+   mean very different things in a more nested scope than Some_Access_Type.
+   The former will execute successfully; the latter will raise Program_Error
+   due to a failed accessibility check.
+   Users may not expect this, but this is not a change.
+
+3) As per Tuck's and Randy's suggestions, this AI does not
+   address the complications in this area introduced by other unapproved AIs
+   (230 and 325, in particular), although wording was chosen which
+   should work without modification for 287 (again, as per Tuck's suggestion).
+
+4) In this example
+       while Function_Call_Requiring_Finalization.Field loop
+           Some_Procedure_Call;
+       end loop;
+   , the function result object is finalized before the procedure is called.
+
+5) In this example
+      X : T;
+      Y : T renames Function_Call_Requiring_Finalization.Field;
+   , X and the function result object have the same master.
+   This is consistent with AI-182; this is not a change.
+
+6) The anonymous objects created as part of the evaluation of an allocator of
+   an anonymous access type may include a storage pool, in which case storage
+   for the allocated object may be reclaimed when the storage pool is finalized;
+   this will not occur until after the allocated object has been finalized.
+
+7) The first sentence of 7.6.1(13/1) (the one ending in "until after
+   it is no longer accessible by any name") is replaced by the rule defining
+   the master and accessibility level in this case.
+   Note also that a function result cannot be passed as an actual parameter
+   for a generic formal IN OUT parameter in a generic_instantiation, so no
+   description of the dynamic semantics of this case was ever needed.
+
+8) A compound statement which acts as a master need not be treated as though it
+   encloses any other master for purposes of determining accessibility levels.
+   In this example
+       while Function_Call_Requiring_Finalization.Field loop
+         declare
+           X : Some_Type;
+         begin
+           null;
+         end;
+       end loop;
+   , an implementation may choose to view the master of X as being at a deeper
+   accessibility level than the master of the function call or not; it doesn't
+   matter.
+
+9) Instead of defining compound statements to be masters, another approach
+   would be to define conditions, selector expressions for case statements,
+   loop parameter specifications, delay_expressions, etc. to be masters.
+   This would eliminate the need for the special treatment of entry_barrier
+   conditions.
+
+10) The discussion section of AI-169 mentions problems stemming from
+    "an anonymous object which is not associated with any particular master".
+    Such an anonymous object now has a master.
+
+11) In this example
+        function Dereference (X : access Some_Task_Type) return Task_Type is
+        begin
+           returns X.all;
+        end;
+
+        Y : Task_Type renames Dereference (new Task_Type);
+    , the attempt to return X.all now raises Program_Error because
+    of the change to 6.5(18). This is a good thing, as this would be
+    very difficult to implement otherwise. The behavior of this example
+    was previously unclear.
+
+12) The execution of a block_statement is an unrestricted master, not a
+    restricted master.
+
+13) We refer to "the master" of an object only in informal discussion.
+    A precise definition of this term would be straightforward, but
+    so far it has not been necessary for RM wording.
+
+--!corrigendum
+
+!ACATS Test
 
+ACATS C-Test(s) should be created to test that the correct master is used.
+
+!appendix
+
 !section 3.10(2)
 !subject Anonymous access types and finalization
 !reference RM95 3.10(2)
@@ -1059,6 +1160,295 @@
 call). Indeed, this is one of the very few places where we diverge from a
 pure-one-pass design, and it's because we do that that it becomes messy. But
 this is probably not a language issue.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, December 1, 2003  4:04 PM
+
+>    The distinction between two kinds of masters (tentatively called
+>    "unrestricted" and "restricted") is necessary because some places
+>    in the manual need to refer to *all* masters (e.g. the discussion in
+>    7.6.1(4) of the finalization of a master or the definition in
+>    3.10.2(6) of the accessibility level of a master) while other places
+>    need to refer only to old-style (i.e. unrestricted) masters (e.g.
+> 3.10.2(7)
+>    and 9.3(3)). An earlier (uncirculated) version of this AI attempted to
+>    simply use the term "master" in both cases, but this didn't work well.
+
+Can you elaborate on this?  It is not ideal to have to make this distinction.
+What would happen if we just used "master" everywhere?  There are already
+plenty of blocks and subprograms which are called masters but don't really
+do anything master-ish.
+
+>    The terms "unrestricted master" and "restricted master" are not themselves
+>    very satisfactory. Does anyone have a better alternative?
+
+The best alternative is to eliminate the distinction, or use something
+like "a master which is the execution of a block or a program unit"
+if there are only a very small number of places we need to make the
+distinction.  Do we really ever have to talk about "restricted" masters?
+Can't these at least just be "masters"?
+
+****************************************************************
+
+From: Steven W. Baird
+Sent: Tuesday, December 2, 2003  5:30 PM
+
+> Can you elaborate on this?  It is not ideal to have to make this distinction.
+
+I agree with you that it would be nice if we could find a way to avoid
+introducing these terms, but I haven't found it yet.
+
+Tuck wrote:
+> What would happen if we just used "master" everywhere?
+
+Simply eliminating the distinction between the different kinds of masters
+would not work.
+
+For example, if 9.3(3) referred to "master" instead of "unrestricted
+master", then the elaboration of the declaration
+    X : Some_Task_Type;
+would have to deadlock waiting for the (unactivated) task to complete
+because the declaration is now a master.
+
+> The best alternative is to eliminate the distinction, or use something like
+> "a master which is the execution of a block or a program unit" if there are
+> only a very small number of places we need to make the  distinction.  Do we
+> really ever have to talk about "restricted" masters?  Can't these at least
+> just be "masters"?
+
+Unfortunately, the number of places we need to make the distinction is not
+small.
+
+There are several places in the manual that reference masters (3.10.2,
+7.6.1, 9.3, 9.8, 10.2) and several that reference
+unrestricted masters (3.10.2, 6.5, 7.6.1, 9.3, 13.11).
+
+Restricted masters are referenced only 7.6.1.
+
+It might be possible (albeit awkward) to somehow restructure 7.6.1 to
+avoid using the term "restricted master", but it seems
+to me that there are too many uses of "unrestricted master" to replace
+each of them with something like "a master which is
+the execution of a task_body, a block_statement, a subprogram_body, an
+entry_body, or an accept_statement".  Even if
+we manage a shorter definition, we still don't want to replicate it this
+many times.
+
+What do you think?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, December 2, 2003  5:43 PM
+
+A couple of comments on this AI:
+
+> !wording
+
+You've lost the !recommendation section. Even though it just says "(See
+summary.)", it has to be present.
+
+> Replace 7.6.1(13/1 - 13.1/1) with
+>
+>   A restricted master is a master of any anonymous object created as part of
+>   its execution by the evaluation of an allocator of an anonymous access type,
+>   a function call, or an aggregate except if the object is
+>
+>     - created as part of the execution of a more nested restricted master;
+>
+>     - created as part of a rename declaration which renames any part of the
+>       object. In this case, the nearest enclosing unrestricted master of the
+>       rename declaration is defined to be a master of the object; the
+>       accessibility level of the object is defined to be the accessibility
+>       level of this master.
+>
+>   or
+>
+>     - created by an allocator of an anonymous access type which is used to
+>       initialize an access discriminant of another object. In this case, the
+>       masters of the allocated object are defined to be masters of the
+>       discriminated object; the accessibility level of the allocated object
+>       is defined to be that of the discriminated object.
+>       The allocated object is finalized when the discriminated object is
+>       finalized. The storage occupied by the allocated object is deallocated
+>       when the storage occupied by the discriminated object is deallocated.
+>
+>   For a statement, the finalization of such an anonymous object occurs
+>       - when the statement is completed;
+>   or
+>       - immediately before beginning the execution of a nested statement;
+>   or
+>       - in the case of a potentially blocking operation, immediately before
+>         the operation blocks the current task
+>   , whichever occurs first. Otherwise, this finalization occurs when the
+>   entity is completed.
+
+The format of these bulleted lists is a non-starter. You can't put text
+between bullets, you can't start lines with punctuation, and you can't have
+text following that belongs to the list. None of those things are supported
+in HTML, the RM formatting tool, and I believe that they may violate some of
+ISO's formatting rules as well. (Not that we follow those too closely.)
+Trying to fix this wording is a bigger job than I want to take on right now,
+so I'll leave it to the author. A lot of the discussion also does this; it
+also needs to be fixed - before this AI gets to editorial review!!
+
+> An implementation must somehow keep track of whether a given
+> access discriminant component "belongs" to the enclosing discriminated
+> object.
+
+The distributed overhead that this implies seems to be overkill for an
+extremely marginal case. Is there anything *useful* that can be accomplished
+with this construct that can't be handled with named access types? The need
+for anonymous discriminants comes from self-referencing data structures, and
+by definition, those don't use allocators for the discriminants!
+
+I'd just say its a bounded error to deallocate one of these things. (Which
+implies that you should never create one in the first place, reasonable
+advice in any case.)
+
+> Only a non-component object of the discriminated type can "own" the object
+> designated by its discriminant. For a non-allocated object, ownership is known
+> statically. Thus, distributed overhead need only be incurred in the case of an
+> allocated object with one or more access discriminants. One implementation
+> strategy would be to prepend this information to the allocated object in
+> much the same way that some implementations prepend dope vectors for allocated
+> arrays when the designated subtype is unconstrained.
+
+Janus/Ada uses a single set of thunks to allocate/deallocate all objects
+(whether they are local or allocated from the heap), with a pool parameter
+and passing in the top-level chunk of memory. It wouldn't work to have
+different representations in the heap and on the stack. Secondly, we'd have
+to have a new kind of descriptor in order to implement the above, which
+would mean a new kind of subtype, and extra work to identify that subtype
+and do the right thing everywhere in the compiler that an access object can
+be referenced. Sounds like a nightmare to me, plus the extra cost of an
+extra indirection on every use. The alternative of having a bit with every
+access discriminant sounds better on both counts, except that it would
+change the representation of any object with an access discriminant (making
+such objects incompatible with those from the existing Ada 95
+implementation), and could waste as much as 31 bits per discriminant
+(because of alignment issues). Can this case really be worth that??
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 2, 2003  8:09 PM
+
+> The format of these bulleted lists is a non-starter. You can't put text
+> between bullets, you can't start lines with punctuation, and you can't have
+> text following that belongs to the list.
+
+I think all of this is due to the wording being "wrapped"
+by some mail software somewhere.  I suggest Steve just
+reformat it with narrower margins and send it again,
+or attach it as a ".txt" file rather than including it
+in the body of the mail message.
+
+>>An implementation must somehow keep track of whether a given
+>>access discriminant component "belongs" to the enclosing discriminated
+>>object.
+>
+> The distributed overhead that this implies seems to be overkill for an
+> extremely marginal case. ...
+
+I agree.  We should *allow* implementations to finalize and
+deallocate the object created by the anonymous allocator when
+the enclosing object is deallocated, but we shouldn't require it.
+It should be postponed no later than when the outer access type
+is finalized.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 2, 2003  8:11 PM
+
+> Simply eliminating the distinction between the different kinds of masters
+> would not work.
+>
+> For example, if 9.3(3) referred to "master" instead of "unrestricted
+> master", then the elaboration of the declaration
+>     X : Some_Task_Type;
+> would have to deadlock waiting for the (unactivated) task to complete
+> because the declaration is now a master.
+
+This seems like a problem that is solvable without creating
+multiple kinds of masters.  Suppose we change 9.3(3) to say:
+
+   If the task is created by the elaboration of an object_declaration,
+   it depends on each master that includes this elaboration{,
+   other than the object_declaration itself}.
+
+We also want to be sure that (the elaboration of) a package or protected
+unit is never considered a master, since we don't want them to become
+masters of tasks or finalizable objects declared within them.
+
+It might be simpler to turn certain expressions into masters,
+rather than statements or declarations to avoid this containment
+problem.  Then all we need to define is when such expression masters
+should be/must be finalized.
+
+> It might be possible (albeit awkward) to somehow restructure 7.6.1 to
+> avoid using the term "restricted master", but it seems
+> to me that there are too many uses of "unrestricted master" to replace
+> each of them with something like "a master which is
+> the execution of a task_body, a block_statement, a subprogram_body, an
+> entry_body, or an accept_statement".  Even if
+> we manage a shorter definition, we still don't want to replicate it this
+> many times.
+
+I think if you make expressions into masters, you can just say
+"masters" in all these contexts.  And as a fall back,
+we have the term "expression masters" and "non-expression masters"
+if we really need them (but I don't think we do).
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, December 3, 2003  1:26 AM
+
+To suggest just some wordsmithing, why not use "master" for the general
+case, then "master which is not a statement"
+and "master which is a statement" when you need to be specific?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, December 3, 2003  3:29 AM
+
+> The distributed overhead that this implies seems to be
+> overkill for an extremely marginal case. Is there anything
+> *useful* that can be accomplished with this construct that
+> can't be handled with named access types? The need for
+> anonymous discriminants comes from self-referencing data
+> structures, and by definition, those don't use allocators for
+> the discriminants!
+
+I disagree with Randy and Tuck here.  I see access discriminants as a
+way to work-around the fact that discriminants have to be of an
+elementary type.  If I use an access discriminant (as opposed to a
+discriminant of a named access type) it is _precisely_ because I expect
+that the two objects will be strongly tied, and in particular will be
+finalized at the same point.  This is an important invariant that should
+be maintained.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, December 3, 2003  9:07 PM
+
+> I think all of this is due to the wording being "wrapped"
+> by some mail software somewhere.  I suggest Steve just
+> reformat it with narrower margins and send it again,
+> or attach it as a ".txt" file rather than including it
+> in the body of the mail message.
+
+I thought that originally, and tried to correct it, but the text makes no
+sense that way. It's quite clear that Steve intended to start lines with
+commas and put hanging "or"s between bullets, and that just isn't allowed.
+(There also was a lot of word wrapping problems, but those
+I fixed when I filed the AI.)
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent