CVS difference for ais/ai-00416.txt

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

--- ais/ai-00416.txt	2005/03/15 01:16:10	1.3
+++ ais/ai-00416.txt	2005/03/15 02:13:15	1.4
@@ -1,4 +1,4 @@
-!standard 3.9.2(2)                                     05-02-14  AI95-00416/03
+!standard 3.9.2(2)                                     05-03-10  AI95-00416/04
 !class amendment 05-02-07
 !status work item 05-02-07
 !status received 05-02-07
@@ -8,7 +8,8 @@
 
 !summary
 
-Dispatching on access result is supported.
+Dispatching on access result is supported, but
+nulls are allowed.
 
 Tasks are activated after returning from a function
 that returns an object containing tasks.
@@ -92,17 +93,6 @@
 contains an explicit constraint (access discriminants specified
 individually).
 
-When using a part of a function call as a prefix for an access
-discriminant, the level of the function decl determines the
-accessibility level. I.e. accessibility level of type of access
-discriminant of a part of a function call is determined by the level of
-the function decl. When taking 'Access of a part of a function call, the
-level is that of the innermost master (i.e., the function call
-corresponds to a temporary object).
-
-Define this as equivalent to converting each access discriminant to
-the type of the access discriminant of the target.
-
 ---------------------
 
 Tasks are not activated until outermost enclosing object fully and
@@ -111,23 +101,6 @@
 that is not successfully initialized, is finalized prior to exiting
 the return statement.
 
----------------------
-
-For a limited function return, the caller has to control where the
-return object is built. If the result subtype is unconstrained, while
-the call is being used to initialize a constrained object, including a
-component, the space available to the object is bounded. To avoid
-overrunning this space, the caller must pass in some sort of implicit
-parameters which will allow the return statement to determine the limits
-on the space it may occupy. One possibility is to pass in the values
-for the discriminants, or perhaps to preeinitialize them in the space
-for the return object. There should be an implementation permission to
-allow raising Constraint_Error at the beginning of the return statement,
-prior to fully evaluating the return expression or executing the handled
-sequence of statements. Something analogous to a 'Constrained bit can
-be provided, to indicate whether the discriminant values are preinitialized.
-
-
 !wording
 
 Change first sentence of 3.2.3(1):
@@ -152,15 +125,18 @@
 
 Change 3.9.2(4):
 
-    ... if it is a call with a controlling result {or access result}, ...
+    ... if it is a call with a controlling result {or controlling
+    access result}, ...
 
 Change 3.9.2(5):
 
-    ... or it is a call with a controlling result {or access result} and ...
+    ... or it is a call with a controlling result {or controlling
+    access result} and ...
 
 Change 3.9.2(6):
 
-    ... if it is a call with a controlling result {or access result}, ...
+    ... if it is a call with a controlling result {or controlling
+    access result}, ...
 
 Delete the second sentence of 3.9.2(11):
 
@@ -172,21 +148,32 @@
 
 Change 3.9.2(18/2):
 
-    * If the call has a controlling result {or access result} and
-      {(possibly parenthesized or qualified)} is itself{, or
-      designates,} a [(possibly parenthesized or qualified)] controlling
-      operand of an enclosing call on a dispatching operation of a
+    * If the call has a controlling result {or controlling access result} and
+      is itself{, or designates,} a [(possibly parenthesized or qualified)]
+      controlling operand of an enclosing call on a dispatching operation of a
       descendant of type T, then its controlling tag value is determined
       by the controlling tag value of this enclosing call;
 
 Change 3.9.2(18.1/2):
 
-    * If the call has a controlling result {or access result} and
+    * If the call has a controlling result {or controlling access result} and
       {(possibly parenthesized, qualified, or dereferenced)} is the
       [(possibly parenthesized or qualified)] expression of an
       assignment_statement whose target is of a class-wide type, then
       its controlling tag value is determined by the target;
 
+Add after 3.10(12):
+
+  AARM NOTE:
+    Note that we considered imposing a similar implicit null exclusion
+    for controlling access results, but chose not to do that, because
+    there is no Ada95 compatibility issue, and there is no automatic
+    null check inherent in the use of a controlling access result. If a
+    null check is necessary, it is because there is a dereference of the
+    result. If there is no dereference of the result, a null return
+    value is perfectly acceptable, and can be a useful indication of a
+    particular status of the call.
+
 Add after 3.10.2(7/2):
 
    AARM NOTE:
@@ -219,16 +206,10 @@
 
     * The accessibility level of the result of a function call that is
       used as a prefix of a name or as the actual parameter in a call
-      is that of the nearest enclosing master. In other contexts, the
+      is that of the immediately enclosing master. In other contexts, the
       accessibility level is that of the object being initialized from
       the function result.
 
-  AARM Note:
-      Even though the level of a function result is defined to be that
-      of the nearest enclosing master, the level of an access discriminant
-      of a function result is defined to be that of the function declaration
-      (see 3.10.2(12/2) below).
-
 Add after 3.10.2(10/2):
 
     * Within a return statement, the accessibility level of the return
@@ -244,8 +225,9 @@
       so that the object may be designated by objects local to the
       return statement, but not by objects outside the return statement.
       In addition, the intent is that the return object gets finalized
-      if the return statement ends without actually returning (e.g. due
-      to propagating an exception, or a goto).
+      if the return statement ends without actually returning (for example,
+      due to propagating an exception, or a goto). For a normal return,
+      of course, no finalization is done before returning.
 
 Delete 3.10.2(11.1/2) (it is redundant).
 
@@ -275,25 +257,13 @@
          level of the object or subprogram designated by the associated
          value (or library level if the value is null);
 
-       + For an access discriminant of an object with an unconstrained
-         nominal subtype that represents part of the result of calling a
-         function, the accessibility level of the function;
-
-       + For an access discriminant of an object with an unconstrained
-         nominal subtype that represents part of the result of calling a
-         function, the accessibility level of the function;
-
        + For an access discriminant of any other object with an unconstrained
          nominal subtype, the accessibility level of the object.
 
       AARM NOTE: In other words, if you know the value of the discriminant
         from a discriminant constraint or an aggregate component association,
         then that determines the accessibility level; if you don't know it,
-        then it is based on the level of the function that returned the
-        object, or on the object itself if it was not returned by a function.
-        We don't actually define the level of the object returned by a function
-        to always be that of the function, since it might actually have a much
-        shorter lifetime (or longer, for that matter).
+        then it is based on the object itself.
 
 Delete 3.10.2(12.a/2) (it was moved up to be after paragraph 7/2).
 
@@ -305,14 +275,14 @@
       the same as that of the access type, except for an allocator that
       defines the value of an access parameter or an access discriminant.
       For an access parameter, the accessibility level is that of the
-      called function. For an access discriminant, the accessibility
-      level is determined as follows:
-         + for an allocator used to define the constraint in a subtype_declaration,
-           the level of the subtype_declaration;
-         + for an allocator used to define the discriminant of a return object,
-           the level of the master that elaborated the function body;
-         + for an allocator used to define the discriminant of any other kind of
-           object, the level of the object.
+      master immediately enclosing the call. For an access discriminant,
+      the accessibility level is determined as follows:
+         + for an allocator used to define the constraint in a
+           subtype_declaration, the level of the subtype_declaration;
+         + for an allocator used to define the constraint in a
+           component_definition, the level of the enclosing type;
+         + for an allocator used to define the discriminant of an object,
+           the level of the object.
 
 Add after 4.8(5.1/2):
 
@@ -345,7 +315,7 @@
 
   AARM NOTE:
     We know that if the result type is class wide, then there must be
-    a return expression.  Similarly, if the result subtype is unconstrained,
+    a return expression. Similarly, if the result subtype is unconstrained,
     then either the return_subtype_indication (if any) is constrained,
     or there must be a return expression.
 
@@ -354,12 +324,12 @@
   AARM NOTE:
     If the result type is controlled or has a controlled part, appropriate
     calls on Initialize or Adjust are performed prior to executing
-    the handled_sequence_of_statements, unless of course if the
+    the handled_sequence_of_statements, except when the
     initial expression is an aggregate (which requires build-in-place
     with no call on Adjust).
 
-    If the return statement exits without resulting in a return (e.g. due
-    to an exception propagated from the return expression or the
+    If the return statement exits without resulting in a return (for example,
+    due to an exception propagated from the return expression or the
     handled sequence of statements, or a goto out of the handled sequence
     of statements), the return object is finalized prior to leaving the
     return statement.
@@ -399,7 +369,7 @@
 
                      Implementation Permission
 
-     If the result subtype of a function is unconstrained and limited,
+     If the result subtype of a function is unconstrained,
      and a call on the function is used to provide the initial value of
      an object with a constrained nominal subtype, Constraint_Error may
      be raised at the point of the call while elaborating a
@@ -409,17 +379,16 @@
 
    AARM NOTE: Without such a permission, it would be very difficult
      to implement "build-in-place" semantics. Such an exception is not
-     handleable within the function, because in the nonlimited case, the
-     constraint check to verify that the result satisfies the
+     handleable within the function, because in the return-by-copy
+     case, the constraint check to verify that the result satisfies the
      constraints of the object being initialized happens after the
      function returns, and we want the semantics to change as
-     little as possible when switching between limited and nonlimited.
+     little as possible when switching between
+     return-by-copy and build-in-place.
      This implies further that upon detecting such a situation, the
      implementation may need to simulate a goto to a point outside any
      local exception handlers prior to raising the exception.
 
-   TBD: Should we allow this for nonlimited result types as well?
-
 Change 7.6.1(3/2):
 
      ... except in the case of a master: the execution of a body other
@@ -428,8 +397,6 @@
      accept_statement, a block_statement, or a simple_statement]
      {a statement};
 
-Add at end of 7.6.1(13/2):
-
 Change 9.2(2):
 
      A task object (which represents one task) can be {a part of a
@@ -476,8 +443,77 @@
      their activation.
 
 !discussion
+
+Our intent is to define the checks needed when an object with
+access discriminants is initialized by assignment as equivalent
+to converting each access discriminant to
+the type of the access discriminant of the target.
+
+When a function call is used as a prefix (or as an actual parameter), such
+as for taking 'Access or selecting a component, it is considered
+a temporary object, and the accessibility level of an access discriminant
+subcomponent will have the level of the nearest enclosing master.
+On the other hand, if the function call is used as a "whole" to initialize
+an allocator, a declared object, or a return object, it takes on the
+accessibility level of the function declaration.
+
+We want to preserve the model that an allocator (of an anonymous type)
+that is used to initialize an access discriminant results in an
+allocated object that has the same storage pool and lifetime as the
+object with the access discriminant. This should be true whether
+the enclosing object is limited or non-limited.
+
+For a limited function return, the caller has to control where the
+return object is built. If the result subtype is unconstrained, while
+the call is being used to initialize a constrained object, including a
+component, the space available to the object is bounded. To avoid
+overrunning this space, the caller must pass in some sort of implicit
+parameters which will allow the return statement to determine the limits
+on the space it may occupy. One possibility is to pass in the values
+for the discriminants, or perhaps to preeinitialize them in the space
+for the return object. There should be an implementation permission to
+allow raising Constraint_Error at the beginning of the return statement,
+prior to fully evaluating the return expression or executing the handled
+sequence of statements. Something analogous to a 'Constrained bit can
+be provided, to indicate whether the discriminant values are preinitialized.
+
+-----------------
 
-(See proposal.)
+Our last discussion about access discriminants
+and allocators in Paris was a bit concerning,
+I'm sure. For what it's worth, I believe I have
+worked out all the problems, and the "joined at
+the hip" model will work for nonlimited types
+as well. Generally, the solution is to return
+more closely to the rule that an access discriminant
+always has the same level as the object it is
+a component of. I had broken that rule for objects
+returned by functions when referring to an
+access discriminant of a subcomponent of the
+result, and that was causing the trouble, I
+believe. Calling a function and then only using
+a part of the result is quite rare, and using
+a part that happens to have an access discriminant
+that is initialized from the enclosing object's
+access discriminant is well below the noise
+level.
+
+Overall, the general rule becomes that as soon
+as you select a component of a function result,
+the function result is treated as a "temp",
+and it takes on a very local accessibility
+level, as do any access discriminants it has.
+E.g.:
+
+    X : T := func().component;
+
+is not permitted if component has an access
+discriminant initialized from the enclosing object,
+because the call is a temp, and we are
+trying to initialize a longer-lasting
+object. Another way to think about it is
+that only when "build-in-place" is possible
+can the result of the function call be long-lived.
 
 !example
 

Questions? Ask the ACAA Technical Agent