CVS difference for ai05s/ai05-0234-1.txt

Differences between 1.4 and version 1.5
Log of other versions for file ai05s/ai05-0234-1.txt

--- ai05s/ai05-0234-1.txt	2011/01/27 06:06:17	1.4
+++ ai05s/ai05-0234-1.txt	2011/02/08 08:21:06	1.5
@@ -1,4 +1,4 @@
-!standard  6.5(21/3)                               10-11-18    AI05-0234-1/01
+!standard  6.5(21/3)                               11-02-07    AI05-0234-1/02
 !class binding interpretation 10-11-15
 !status work item 10-11-15
 !status received 10-10-31
@@ -66,106 +66,178 @@
 
 !wording
 
-Modify 4.8(10.1/3) as (modified by AI05-0051-1) as follows:
+Insert after Static Semantics section of 3.10.2:
 
+  Dynamic Semantics
+  -----------------
+
+  At a given point in a program's execution, a given coextension is
+  a coextension of exactly one non-coextension object. This non-coextension
+  object is defined to be the "owner" of the coextension.
+
+  It is possible for the master and accessibility level of an object to
+  change in the following cases:
+    - When an aggregate or function call result is built in place
+      and one object "mutates into" another object as described in 7.6,
+      the two objects may have different masters and accessibility levels.
+    - When a return statement completes normally by returning from a function
+      and the function result object is not built in place,
+      the accessibility level of the return object changes to be
+      a level determined by the point of call as described above.
+    - When a coextension of one object becomes a coextension of
+      a different object as described above, the master and
+      accessibility level of the coextension become those of the
+      new owner.
+
+  Informally, the "ultimate master" of an object (or of an
+  access type associated with a coextension object), is the master
+  that the object will have eventually when all of these transformations
+  have occurred.
+
+  This is defined as follows:
+
+    If the result of a function call
+    or aggregate is built in place (see 7.6), the ultimate master
+    of the result object is that
+    of the object that the result object is used to initialize.
+
+    If the result object of a function call
+    is not built in place, the ultimate master
+    of the result object is the master
+    determined by the point of call (as described above).
+
+    In the case of a function call whose result is not built
+    in place, but for which coextension
+    ownership will be transferred (as described above),
+    the ultimate master of the coextensions
+    (if any) of the result object is that of the object to
+    which coextension ownership will be transferred;
+    this rule is applied recursively in the case where the
+    new owner is also such a function call result.
+
+       AARM note:
+       Informally, the ultimate master of
+       a coextension is that of its "ultimate owner".
+
+    In all other cases, the ultimate master of
+    a coextension is that of the coextension's owner.
+
+    The ultimate master of the access type of an
+    allocator that creates a coextension is that
+    of the coextension.
+
+    For any other entity whose master is defined,
+    the ultimate master of the entity is the same
+    as its master.
+
+The ultimate accessibility level of an entity
+is defined to be the accessibility level of its ultimate master.
+
+AARM note:
+   Despite the use of the future tense ("to which coextension
+   ownership will be transferred") and words like
+   "eventually" and "ultimate", implementers do not require
+   a crystal ball. An additional implicit parameter may be needed
+   in some cases in order to communicate information known at a
+   function's call site to the callee.
+
+   The terms "ultimate master" and "ultimate accessibility level" play
+   no role in the static semantics of the language. In particular, they
+   play no role in any accessibility-related legality rules. These terms
+   define properties of an object, not of a view of an object.
+
+Add at the end of the "Dynamic Semantics" section of 4.3.1:
+
+   If the type of the aggregate is discriminated and has
+   default expressions for its discriminants and has
+   one or more access discriminants for which the
+   aggregate provides an expression (as opposed to a
+   record_component_association with <>), then a check is
+   made that the accessibility level of the anonymous access type of
+   each such access discriminant, as determined by the expression provided
+   in the aggregate, is not deeper than the ultimate accessibility level
+   of the anonymous object created for the evaluation
+   of the aggregate. If this check fails, Program_Error is raised. 
+
+   AARM note:
+     This check is guaranteed to pass in the (usual) case that
+     the aggregate's anonymous result object's accessibility
+     level matches its ultimate accessibility level.
+     An aggregate cannot contain a reference to something
+     shorter-lived than itself unless the aggregate object's
+     accessibility level changes, and such a pending change would
+     be reflected in the ultimate accessibility level of the object.
+     Note also that only a limited type may have a defaulted
+     access discriminant, so this rule has no effect unless the
+     type of the aggregate is limited.
+
+
+Modify 4.8(10.1/3) as (modified by AI05-0024-1 and AI05-0051-1) as
+follows:
+
       For any allocator, if the designated type of the type of the
       allocator is class-wide, then a check is made that the
       accessibility level of the type determined by the
       subtype_indication, or by the tag of the value of the
-      qualified_expression, is not deeper than that of the type of the
-      allocator. If the subtype determined by the subtype_indication or
-      qualified_ expression {(or by the tag of the value of the qualified
+      qualified_expression, includes the elaboration {of the ultimate
+      master} of the type of the allocator. If the subtype determined by
+      the subtype_indication or
+      qualified_expression {(or by the tag of the value of the qualified
       expression if the type of the qualified expression is class-wide)}
       of the allocator has one or more access discriminants, then a
       check is made that the accessibility level of the anonymous access
-      type of each access discriminant is not deeper than that of the
-      type of the allocator. Program_Error is raised if either such check
-      fails.
+      type of each access discriminant is not deeper than [that]{the
+      ultimate accessibility level} of the type of the allocator.
+      Program_Error is raised if either such check fails.
 
-Replace 6.5(21/3) (as modified by AI05-0051-1) with:
+[Editor's note: Steve said he wanted other changes as well, but I can't figure
+out what they are supposed to be; he did not show them, rather describing
+what to change from some unknown baseline.]
 
-    If any part (ignoring the values of bounds and discriminants) of the return
-    object of a function (or a coextension thereof) has one or more access
-    discriminants whose value is not constrained by the result subtype of the
-    function, a check is made that the accessibility level of the anonymous
-    access type of each access discriminant is not deeper than the level of the
-    return object as determined by the point of call (see 3.10.2). If this check
-    fails, Program_Error is raised.
+In 6.5(8) replace
 
-Add a (massive) AARM note after 6.5(21/3):
+  A check is made that the master of the type identified by the tag of the
+  result includes the elaboration of the master that elaborated the function
+  body.
 
-   For a function with a classwide result type, the access values that
-   need to be checked are determined by the tag of the return object.
-   In order to implement this accessibility check in the case where
-   the tag of the result is not known statically at the point of the
-   return statement, an implementation may need to somehow
-   associate with the tag of a specific tagged
-   type an indication of whether the type has unconstrained access
-   discriminants (explicit or inherited) or has any subcomponents
-   with such discriminants. If an implementation is already maintaining
-   a statically initialized descriptor of some kind for each specific
-   tagged type, then an additional Boolean could be added to this
-   descriptor.
-
-   Note that the flag should only be queried in the case where any
-   access discriminants which the result object might have would
-   have subtypes with "bad" accessibility levels (as determined by
-   the rules of 3.10.2 for determining the accessibility level of
-   the type of an access discriminant in the expression or
-   return_subtype_indication of a return statement).
-
-   Thus, in a case like
-
-       type Global is access T'Class;
-       function F (Ptr : Global) return T'Class is
-       begin
-           return Ptr.all;
-       end F;
-
-   there is no need for a runtime accessibility check. The setting
-   of the bit doesn't matter and there is no need to query it.
-
-   On the other hand, given
-
-      function F return T'Class is
-          Local : T'Class := ... ;
-      begin
-          return Local;
-      end F;
-
-   In this case, a check would typically be required.
-
-   The need for including subcomponents in this check is illustrated by
-   the following example:
-
-      X : aliased Integer;
-
-      type Component_Type (Discrim : access Integer := X'Access)
-        is limited null record;
-
-      type Undiscriminated is record
-        Fld : Component_Type;
-      end record;
-
-      function F return Undiscriminated is
-          Local : aliaed Integer;
-      begin
-          return X : Untagged := (Fld => (Discrim => Local'Access)) do
-            Foo;
-          end return;
-          -- raises Program_Error after calling Foo.
-      end F;
+with
 
-   Ramification:
-   In the case where the tag of the result is not known statically
-   at the point of the return statement and the runtime accessibility
-   check is needed, discriminant values and array bounds
-   play no role in performing this check. That is, array components are
-   assumed to have non-zero length and components declared
-   within variant parts are assumed to be present  Thus, the check
-   may be implemented simply by testing the aforementioned descriptor
-   bit and conditionally raising Program_Error.
+  A check is made that the master of the type identified by the tag of the
+  result includes the elaboration of the ultimate master of the return object.
+
+====
+
+
+Modify 6.5(21) (as modified by AI05-0051) as follows:
+
+    If [any part of] the return object (or coextension
+    thereof) of a function has one or more [unconstrained] access
+    discriminants whose value is not constrained by the result subtype of
+    the function, a check is made that the accessibility level of the
+    anonymous access type of each access discriminant, as determined by
+    the expression or the return_subtype_indication of the function, is
+    not deeper than the [level of the return object as determined by the
+    point of call]{ultimate accessibility level of the
+    return object} (see 3.10.2). If this check fails, Program_Error is
+    raised. 
+
+[Editor's note: Steve referenced 7.6 instead on 3.10.2 here. But that makes
+no sense, the "ultimate accessibility level" is defined in 3.10.2, so
+we reference there.]
+
+[Author's Note: The new 4.3.1 wording plugs the holes associated with
+defaulted access discriminants for limited types, thereby eliminating the
+need for the "any part of" wording in 6.5(21).]
+
+[Author's Note: AI05-0051's wording changes for this paragraph includes
+adding
+  "whose value is not constrained by the result subtype of the function" .
+What does this wording mean if the result subtype is
+Some_Constrained_Subtype'Class ? Like a zombie, AI05-0057 refuses to
+stay buried. [Editor's comment: The same thing that it means anywhere
+else -- which we can't agree on. I don't see anything different here.]]
 
+
 !discussion
 
 The language already specifies accessibility checks for access discriminants in
@@ -1736,3 +1808,60 @@
 
 ****************************************************************
 
+From: Steve Baird
+Sent: Monday, February 7, 2011  3:18 PM
+
+Here is a first cut at wording for this AI. [This is version /02 of
+the AI - Editor.]
+
+Thanks to Gary, Randy, and Bob for reviewing preliminary versions.
+
+Discussion:
+
+The following argument provides motivation for the proposed changes:
+
+   1) We need some kind of accessibility checks to deal with the
+      "access discriminants with defaults" problem illustrated
+      in the AI (the example involving type Component_Type).
+
+      One could view this problem as a consequence of introducing
+      defaulted access discriminants for limited types. This introduces
+      the need to either check aggregates (the approach taken in
+      this version of the AI) or somehow check arbitrarily deeply nested
+      subcomponents at the point of a function return (the approach
+      taken by the previous version of this AI).
+
+   2) We don't want to repeat checks at the point where an
+      object's accessibility level changes; we want to perform
+      the checks against the correct accessibility level in the
+      first place so that checks are performed while we still have
+      useful info about both entities whose accessibility levels
+      are being compared.
+
+      The AI lists the various scenarios where the accessibility level
+      of an object may change. One could imagine an approach where
+      additional checks are performed at these points. This seems like
+      a bad idea. The previous version of thie AI took this approach
+      and involved conservative checks associated with a
+      "has-subcomponents-with-defaulted-access-discriminants" flag in the
+      descriptor for a tagged type. The current approach is more precise;
+      cases which would would have failed overly conservative runtime
+      accessibility checks with the earlier approach will now succeed.
+
+   3) This means that we have to know the "ultimate
+      accessibility level" of an aggregate result object
+      at the point where the discriminant value is given.
+
+      I think this is implementable using the approach outlined
+      in AI05-0051, but this needs to be confirmed. In particular,
+      we need to look at combinations such as a non-build-in-place
+      function call used to initialize an allocator where the
+      function result owns a coextension and the result subtype
+      of the function is class-wide with no discriminants.
+
+   4) Having defined this notion for use with aggregates, we might as
+      well use it elsewhere (see above changes to 4.8 and 6.5)
+      even though the only holes that this fixes are related to coextensions
+      (and are therefore less important, at least to some folks).
+
+****************************************************************

Questions? Ask the ACAA Technical Agent