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

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

--- ai05s/ai05-0234-1.txt	2010/11/16 05:59:59	1.1
+++ ai05s/ai05-0234-1.txt	2010/11/18 07:07:36	1.2
@@ -197,3 +197,1129 @@
 
 ****************************************************************
 
+From: Steve Baird
+Sent: Monday, November 15, 2010  3:39 PM
+
+How do we want to proceed on the "son of AI05-0051" problem?
+
+If we can agree on a general approach, I can try to come up with wording to
+throw rocks at on Friday.
+
+To recap, we want to prevent (probably via some kind of runtime check, but that
+is to be decided) two bad things:
+
+    - a function with a classwide result returning a value which has
+      an access discriminant which designates an object which is
+      too short-lived
+    - an allocator of an access-to-classwide type which allocates a
+      an object which has an access discriminant which designates an
+      object which is too short-lived
+
+Randy and I have discussed an approach. It involves a tiny amount of distributed
+overhead (an extra bit in the descriptor associated with a tagged type; the
+value of the bit is known statically when the type is declared). Tuck may have
+also mentioned this approach at the Fairfax meeting when we discussed this
+problem for about 20 seconds - I'm not sure.
+
+The bit indicates whether the given type has unconstrained access discriminants
+(inherited or not).
+
+To provide motivation, consider a very straightforward (albeit draconian)
+solution. We add a runtime accessibility check at the point of the
+return/allocator based on the accessibility level of the returned/allocated
+"expression" (the term "expression" isn't quite general enough in the case of an
+uninitialized allocator, but you get the idea).
+
+This means that the following would raise P_E:
+
+     function F return T'Class is
+         Result : Some_Specific_Undiscriminated_Type := ''' ;
+     begin
+         ...
+         return Result;
+     end F;
+
+That seems like an unacceptable incompatibility.
+
+So we add the rule that the check is only performed if the specific type in
+question (which, in genreal, is not known until runtime) has one or more
+unconstrained access discriminants.
+
+Most implementations would need something like the aforementioned descriptor bit
+in order to implement this.
+
+This check is still conservative in the sense that it fails in come cases which
+would be safe to allow, but handling types with no access discriminants is a
+substantial improvement.
+
+There are other (statically known) cases where we could safely omit the check.
+Notably, we can be a lot more precise in the case of an immutably limited type,
+although we still have to worry about, for example,
+
+     declare
+         Local : aliased T;
+         subtype S is My_Limited_Type (Discrim => Local'Access);
+     begin
+         Global_Ptr := new S;
+     end;
+
+and we have to do the right thing in the usual build-in-place cases (an
+aggregate, a function call, an extended-return-statement object).
+
+In some cases, the accessibility level of the object designated by the
+discriminant may be known (as opposed to conservatively using the accessibility
+level of the discriminated object). For example, consider an aggregate where the
+discriminant value is given explicitly as part of the aggregate.
+
+It might seem odd to reject
+
+         return Some_Specific_Type
+           (Discrim =>  Some_Safe_Global'Access; ,,,,);
+
+on the grounds that the the discriminant *might* refer to a local.
+
+Or what about
+       return Some_Safe_Global_Constrained_Subtype (Acc_to_Cw.all);
+
+So one question about this approach has to do with which, if any, special cases
+we want to identify in order to make the test less conservative.
+
+I think that we don't care about ancestor types (except to the extent that they
+contribute inherited discriminants which noone has chosen to constrain),
+
+If a more-distant ancestor type, T1, introduces an access discriminant, and a
+less-distant ancestor type, T2, constrains it, then there are two cases:
+   The acceessibility level of T2 is such that it will or will not fail
+   the accessibility check on the specific *type* of an allocated or
+   returned value in the classwide case.
+
+If it is going to fail the check, then we don't need another check.
+Raising P_E once is good enough. If it is going to pass the check, then the
+discriminant value that was supplied must be ok too, as it must designate
+something that already existed when T2 was declared.
+
+Thoughts?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  3:57 PM
+
+This message seems to adequetely sum up what Steve and I talked about, with one
+minor (but important) exception:
+
+The proposed check is purely a runtime check (since we cannot know in general
+what the specific type returned is), but it would have to include both the
+static and dynamic accessibility checks. That is necessary to avoid introducing
+distributed overhead for parameters passed by reference. That happens since the
+language is very clear that the dynamic accessibility of such a parameter is
+that of the actual object, and we definitely don't want to have to pass that
+accessibility with all reference parameters. The reason we don't have to do that
+now is that the static accessibility check rejects any cases where it could
+matter -- they're already illegal. We cannot change that without adding major
+runtime overhead (this was the same problem that made handling conditional
+expressions such a mess).
+
+This clearly is a wording challenge, but I don't think it can be helped. (And
+hardly anyone will ever run into this in practice.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, November 15, 2010  5:07 PM
+
+I was thinking about this a bit and came to the conclusion that paragraphs
+12-12.4 in 3.10.2 might already answer most of your questions. Basically it says
+what is the accessibility level of the discriminants, and I believe it handles
+some of the special cases you mention.
+
+The most recent wording for 4.8(10.1) for AI05-51/09 says:
+
+    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.
+
+That says that the tag is checked if class-wide, which implies that the
+"has-access-discriminants" bit you mention needs to exist.
+
+The most recent AI05-51 wording for 6.5(21) says:
+
+   If any part of the return object (or coextension
+   thereof) of a function 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, 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 (see 3.10.2). If this check
+   fails, Program_Error is raised.
+
+Although it doesn't explicitly say that the tag is checked, it sort of implies
+it in saying that the level of the access discriminants is "determined by the
+expression," and 3.10.2(12-12.4) indicates what that means.  We could be more
+explicit about checking the tag, as the wording is in 4.8(10.1).
+
+Hence, I don't see that we need anything more than a "tweak" of the AI05-51
+wording.
+
+As far as the "static" check, I'll need Randy to give an example of what he has
+in mind there. I don't see how the value of the tag can possibly affect the
+static check.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, November 15, 2010  5:47 PM
+
+> I was thinking about this a bit and came to the conclusion that
+> paragraphs 12-12.4 in 3.10.2 might already answer most of your
+> questions.
+> Basically it says what is the accessibility level of the
+> discriminants, and I believe it handles some of the special cases you
+> mention.
+
+I agree. I had forgotten about those rules.
+
+> The most recent wording for 4.8(10.1) for AI05-51/09 says:
+>
+>    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.
+>
+> That says that the tag is checked if class-wide, which implies that
+> the "has-access-discriminants" bit you mention needs to exist.
+>
+> ...
+
+> Hence, I don't see that we need anything more than a "tweak" of the
+> AI05-51 wording.
+
+I believe that we did not approve AI05-51/09 at the last meeting; we backed out
+of my proposed changes and approved, in effect, AI05-51/08, You expressed
+concern at the time that the wording proposed in version 09 would require
+storing an accessibility level for each access discriminant at runtime, so we
+decided to close up AI05-0051 and deal with the problems we are discussing today
+in a separate AI.
+
+If we decide that it makes sense after all, we can obviously still adopt the
+wording of AI05-51/09 or some variation thereon.
+
+I'm just pointing out that the baseline that we are working from today does not
+include those version 09 changes (if I am remembering what happened in Fairfax
+correctly).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, November 15, 2010  5:51 PM
+
+> I'm just pointing out that the baseline that we are working from today
+> does not include those version 09 changes (if I am remembering what
+> happened in Fairfax correctly).
+
+Thanks for clarifying that.  I guess I need to go back and look at version 08.
+But having accepted the fact that we need the "has-access-discriminants" bit,
+coupled with a re-reading of 3.10.2(12-12.4) I now think your proposed wording
+in version 09 looks pretty good.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  5:57 PM
+
+...
+> I believe that we did not approve AI05-51/09 at the last meeting; we
+> backed out of my proposed changes and approved, in effect, AI05-51/08,
+> You expressed concern at the time that the wording proposed in version
+> 09 would require storing an accessibility level for each access
+> discriminant at runtime, so we decided to close up
+> AI05-0051 and deal with the problems we are discussing today in a
+> separate AI.
+
+My notes end with:
+
+We decide to revert to the previous version of this wording, and create a new AI
+to address this specific problem. (Especially as AI-142-4 also modified this
+paragraph.)
+
+So Steve's memory is correct. Forget the /09 version of the AI.
+
+(Note that /09 wording doesn't make a lot of sense to me, as it seems to mix
+statically determined and dynamically known types in the same sentence without
+explaining which is which.)
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, November 15, 2010  4:53 PM
+
+>...  the language is very clear that the dynamic accessibility of  such
+>a parameter is that of the actual object, and we definitely don't want
+>to have to pass that accessibility with all reference parameters.
+
+I'm not disagreeing with you because I see the argument: A dynamic accessibility
+level is a property of an object (as opposed to a view of an object) and a
+by-reference parameter doesn't introduce a new object - just a view of an
+existing object.
+
+But how do you reconcile this with 3.10.2(7/2):
+   A parameter of a master has the same accessibility level
+   as the master.
+?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  5:12 PM
+
+> But how do you reconcile this with 3.10.2(7/2):
+>    A parameter of a master has the same accessibility level
+>    as the master.
+> ?
+
+I can't, because out of context this doesn't make any sense at all. Masters
+don't have parameters; a master is a execution or evaluation of something
+(typically a statement), so I'm not quite sure what this is referring to. In
+context, it appears to be talking about parameters of declarations, but that
+doesn't make much sense either with this particular wording.
+
+I presume this is intended to do two things: define the *static* accessibility
+of parameters, and define the *dynamic* accessibility of by-copy parameters, but
+it is badly botched. Besides the by-reference case, it also is confused with
+access parameters that have some other accessibility defined (either that of the
+passed-in entity or "deeper than anything else"). This wording makes no sense
+for dynamic accessibility (with which it is associated), period.
+
+I would prefer to invoke the Duff rule on this one (the ARG is not in the
+business of answering questions that no one - other than ARG members musing
+around - has asked). But perhaps there is really something wrong here (not
+surprising, almost everything about accessibility is screwy in one way or
+another).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, November 15, 2010  5:37 PM
+
+Dynamic accessibility level *can* vary
+depending on the "view."  Parameters
+in general are treated like local variables, even when of a type that requires
+pass by reference.  The one exception is explicitly aliased parameters, where
+they are guaranteed to live at least as long as the return object.
+
+Similarly, even if an access discriminant is initialized to designate a global
+variable, the dynamic accessibility level of a dereference of the access
+discriminant is (generally) determined by the dynamic accessibility level of the
+enclosing object.
+
+So dynamic accessibility levels do vary
+according to the view.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  5:25 PM
+
+...
+> As far as the "static" check, I'll need Randy to give an example of
+> what he has in mind there.
+> I don't see how the value of the tag can possibly affect the static
+> check.
+
+Maybe I'm confused, but in the examples that Steve showed, the accessibility
+check was against the level of the expression, not the level of the type. That's
+a check that you cannot make normally at compile-time, as you would fail an
+accessibility check in normal cases.
+
+For example, assuming T is a tagged non-limited type, and TT is an extension of
+it at the same level:
+
+    function Fooey (P : in TT; ...) return T'Class is
+    begin
+       if ... then
+           return T'Class(P); -- OK in Ada 95 and Ada 2005
+       else
+           ...
+       end if;
+    end Fooey;
+
+This return statement is legal in Ada 2005. There would be an accessibility
+check on the tag of TT, but it would staticly be OK.
+
+Now further presume that TT has an access discriminant. If we had directly
+returned the object TT, we would have needed an accessibility check on the
+object. In that case, the static accessibility check would have failed (we
+assume that P is local for this purpose). However, if we didn't have that static
+accessibility check, then we would have to use the accessibility of the actual
+object, which would have to be passed it (adding overhead). The only reason we
+don't need that overhead is because we have the static check that fails.
+
+Now, in the classwide case, we have *only* a runtime check, because in general
+we know nothing about the tag until runtime. That means that unless we add some
+sort of wording about the static check to the dynamic case, we have a
+distributed overhead in that every reference parameter would have to pass a
+dynamic accessibility level (in particular, that would be needed for all tagged
+parameters).
+
+Note that the check you described would always pass if Fooey was called with a
+library-level actual parameter, but should fail if called with a local actual
+parameter. That's what we have to avoid.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, November 15, 2010  5:48 PM
+
+> Now further presume that TT has an access discriminant. If we had
+> directly returned the object TT, we would have needed an accessibility
+> check on the object. In that case, the static accessibility check
+> would have failed (we assume that P is local for this purpose).
+> However, if we didn't have that static accessibility check, then we
+> would have to use the accessibility of the actual object, which would
+> have to be passed it (adding overhead). The only reason we don't need
+> that overhead is because we have the static check that fails.
+
+The dynamic accessibility level of a parameter, even if passed by reference, is
+like that of a local variable.  Just think what happens when you take 'Access of
+a tagged parameter in Ada 95 and pass it as an access parameter. It gets a
+run-time accessibility level that makes it look like a local variable.
+
+The new "aliased" parameters are a bit different, in that they promise to live
+at least as long as the return object, so this example should be fine, even in
+Ada 2012.
+
+> Now, in the classwide case, we have *only* a runtime check, because in
+> general we know nothing about the tag until runtime. That means that
+> unless we add some sort of wording about the static check to the
+> dynamic case, we have a distributed overhead in that every reference
+> parameter would have to pass a dynamic accessibility level (in
+> particular, that would be needed for all tagged parameters).
+
+Again, the "dynamic" accessibility level of a parameter is "local" even if the
+actual parameter is a global object.
+
+> Note that the check you described would always pass if Fooey was
+> called with a library-level actual parameter, but should fail if
+> called with a local actual parameter. That's what we have to avoid.
+
+In cases like this, the accessibility level of an access discriminant is the
+same as the enclosing object, and that is "local" since it is a parameter.  That
+means you don't need to pass anything in, and it will fail the run-time check if
+the actual object has access discriminants, even if the actual object is a
+global object.
+
+I think the net effect is that the "static" check you were mentioning is
+*already* a part of the "dynamic" check, since parameters lose their "real"
+accessibility level and take on the accessibility of a local variable.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  5:52 PM
+
+> Dynamic accessibility level *can* vary depending on the "view."
+> Parameters in general are treated like local variables, even when of a
+> type that requires pass by reference.
+
+This is an oxymoron. Views are static properties that do not have any effect on
+dynamic properties. It doesn't make any sense.
+
+Beyond that, the one place in the standard that gives some credence to this view
+is clearly wrong, in that it is contradicted later in the same clause when
+access parameters are discussed.
+
+We never actually decided the question of whether by-reference parameters are
+objects in their own right, or whether they are just views of the actuals. It
+appears that we will need to do something on this line (either that, or fix up
+the wording to make sense).
+
+> The one exception is
+> explicitly aliased parameters, where they are guaranteed to live at
+> least as long as the return object.
+>
+> Similarly, even if an access discriminant is initialized to designate
+> a global variable, the dynamic accessibility level of a dereference of
+> the access discriminant is (generally) determined by the dynamic
+> accessibility level of the enclosing object.
+
+The accessibility is that of the access discriminant (which is that of the
+enclosing object). So what? I don't see your point here.
+
+> So dynamic accessibility levels do vary according to the view.
+
+Well, that simply doesn't make sense in the Ada model. Of course, nothing else
+about accessibility makes sense, either, so perhaps we can get away with it. But
+if that is what we want, it needs to be clearly explained in the AARM, and it is
+not.
+
+Remember that "view of" can automatically be appended to static semantic rules,
+but not to dynamic rules. If you mean that, you had better say so. Yes, I see
+these rules are defined in "Static semantics", but that makes no sense for a
+dynamic value.
+
+Accessibility is still badly defined. What else is new.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, November 15, 2010  6:11 PM
+
+> > But how do you reconcile this with 3.10.2(7/2):
+> >    A parameter of a master has the same accessibility level
+> >    as the master.
+> > ?
+
+I didn't see the above-quoted message from Steve.
+
+Tucker said in another message that dynamic accessibility is a view property.  I
+agree -- it has to be that way, because by-ref and by-copy are (sometimes)
+impl-def, and we don't want the semantics to differ (other than the essential
+difference in aliasing).  I realize we're talking about tagged types in this
+conversation, but I'm just saying in general, passing something by ref shouldn't
+cause differences in accessibility level and so forth.
+
+> I can't, because out of context this doesn't make any sense at all.
+> Masters don't have parameters; a master is a execution or evaluation
+> of something (typically a statement), so I'm not quite sure what this is
+> referring to.
+
+It's talking about a master that is the execution of a procedure body, and the
+(formal) parameters of that.  These are the plain old run-of-the-mill masters we
+got from Ada 83 -- all these "little" masters like statements were added since
+then.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, November 15, 2010  6:31 PM
+
+Thanks to Tuck and Bob for straightening that one out.
+Ignoring new-fangled explicitly aliased parameters, a parameter pretty much
+behaves like a local with respect to accessibility.
+
+In most cases, one is more likely to arrive at the right answer if you go back
+to the RM and read the relevant wording instead of relying on internalized "I'm
+sure I remember it works this way" knowledge. In the case of accessibility
+rules, however, every rereading is an opportunity to get confused all over
+again.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, November 15, 2010  6:35 PM
+
+...
+> > > But how do you reconcile this with 3.10.2(7/2):
+> > >    A parameter of a master has the same accessibility level
+> > >    as the master.
+> > > ?
+>
+> I didn't see the above-quoted message from Steve.
+
+Steve sent it just to me, not sure if that was by accident or on purpose, but
+since I wanted to get the Tucker and Bob take on it, I replied to the list of
+names.
+
+> Tucker said in another message that dynamic accessibility is a view
+> property.  I agree -- it has to be that way, because by-ref and
+> by-copy are (sometimes) impl-def, and we don't want the semantics to
+> differ (other than the essential difference in aliasing).  I realize
+> we're talking about tagged types in this conversation, but I'm just
+> saying in general, passing something by ref shouldn't cause
+> differences in accessibility level and so forth.
+>
+> > I can't, because out of context this doesn't make any sense at all.
+> > Masters don't have parameters; a master is a execution or evaluation
+> > of something (typically a statement), so I'm not quite sure what
+> > this is referring to.
+>
+> It's talking about a master that is the execution of a procedure body,
+> and the (formal) parameters of that.  These are the plain old
+> run-of-the-mill masters we got from Ada 83
+> -- all these "little" masters like statements were added since then.
+
+It would be nice if this wording said that. Especially the word "formal", in
+which case it makes at least some sense.
+
+"A {formal} parameter of {the entity that} a master {is executing} has the same
+accessibility level as the master."
+
+Or something like that. Plus we need an exception for access parameters (because
+this rule surely doesn't not apply to them), and for explicitly aliased
+parameters. So
+
+"{Unless otherwise defined, } a {formal} parameter of {the entity that} a master
+{is executing} has the same accessibility level as the master."
+
+And we also need an AARM note to explain that.
+
+"AARM Ramification: Note that accessibility can differ depending on the view of
+an object (for both static and dynamic accessibility). In addition to the formal
+parameter case above, similar effects occur for the entities designated by
+access discriminants."
+
+"AARM Reason: We define the (dynamic) accessibility of formal parameters in
+order that it not depend on the parameter passing model (by-reference or
+by-copy) as that is implementation defined. Otherwise, there would be a
+portability issue."
+
+Or something like that (not sure we really want to list out examples, there may
+be more). Since we never actually say "dynamic accessibility in the standard, I
+put that in parens in the notes.
+
+P.S. Note that my original concern probably still exists for explicitly aliased
+parameters used in an allocator, although I doubt anyone will ever write a test
+to check that case. ;-)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, November 15, 2010  6:43 PM
+
+> Or something like that. Plus we need an exception for access
+> parameters (because this rule surely doesn't not apply to them), and
+> for explicitly aliased parameters. So
+
+I mostly agree with your message, but I don't see the problem for access
+parameters.  Are you talking about the parameter itself, or what it designates?
+"X: access T", the accessibility level of X is not relevant, since it's not
+aliased, so X'[Unchecked_]Access is illegal.  The accessibility level of X.all
+is dynamic, but X.all is not a parameter so the rule we're talking about doesn't
+apply.
+
+The new aliased parameters may well need more thought.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 16, 2010  12:23 AM
+
+> > Or something like that. Plus we need an exception for access
+> > parameters (because this rule surely doesn't not apply to them), and
+> > for explicitly aliased parameters. So
+>
+> I mostly agree with your message, but I don't see the problem for
+> access parameters.  Are you talking about the parameter itself, or
+> what it designates?  "X: access T", the accessibility level of X is
+> not relevant, since it's not aliased, so X'[Unchecked_]Access is
+> illegal.  The accessibility level of X.all is dynamic, but X.all is
+> not a parameter so the rule we're talking about doesn't apply.
+
+I suppose you are right.
+
+> The new aliased parameters may well need more thought.
+
+They don't need "more thought", they have their own accessibility rule
+(3.10.2(13.3/3)). I wasn't aware of this older blanket rule, or I would have
+added wording to repeal it in that case.
+
+They probably need "more thought" for AI05-0234-1, because I'd expect that the
+static/dynamic case would come up for allocators (as Tucker points out, they
+have to pass a return statement).
+
+BTW, it seems that we really want formal by-reference parameters to be a new
+object that happens to share memory with the old object. Besides this
+accessibility rule (where claiming that dynamic accessibility is a view property
+is unappealing), we also had similar issues with the values of representation
+aspects like 'Size and 'Alignment. We surely don't want to have to pass those
+along with parameters just so we can report them accurately. (I recall we
+decided that wasn't necessary with some phony hand-waving.) I wouldn't be
+surprised if this keeps coming up until we finally give in and change the
+definition...
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, November 16, 2010  2:21 PM
+
+> Hence, I don't see that we need anything more than a "tweak" of the
+> AI05-51 wording.
+> ....
+> Although it doesn't explicitly say that the tag is checked, it sort of
+> implies it in saying that the level of the access discriminants is
+> "determined by the expression," and 3.10.2(12-12.4) indicates what
+> that means.  We could be more explicit about checking the tag, as the
+> wording is in 4.8(10.1).
+
+I think that perhaps the version 09 RM wording is fine as is.
+
+When we say
+   "any part of the return object (or coextension thereof)", I don't see any
+   need to add
+   "Oh and, by the way, you might need to look at the object's
+    tag in order to identify the set of parts we are talking
+    about here".
+, at least in the RM. An AARM note along those lines would be a good idea.
+
+Do you see other changes/tweaks to the version 09 wording that are needed?
+
+I'm trying to determine what, if any, work remains to be done for this AI.
+Perhaps just adding an AARM note as mentioned above to the existing version 09
+wording?
+
+I am assuming that any changes that may result from Randy's discussion of
+whether the definition of the accessibility level of a formal needs revision
+will go in another AI.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 16, 2010  2:44 PM
+
+> When we say
+> "any part of the return object (or coextension thereof)", I don't see
+> any need to add "Oh and, by the way, you might need to look at the
+> object's tag in order to identify the set of parts we are talking
+> about here".
+> , at least in the RM. An AARM note along those lines would be a good
+> idea.
+
+I find it a bit uncomfortable that we mention the tag when talking about the
+check on allocators but don't mention it when talking about the check on a
+return statement, but I guess I can get over it. I definitely think an AARM note
+is in order to emphasize that the need for the check may depend on the value of
+the run-time tag when the type is classwide.
+
+> Do you see other changes/tweaks to the version 09 wording that are
+> needed?
+>
+> I'm trying to determine what, if any, work remains to be done for this
+> AI. Perhaps just adding an AARM note as mentioned above to the
+> existing version 09 wording?
+
+Yes, that seem to be all that is necessary.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 16, 2010  3:16 PM
+
+...
+> I find it a bit uncomfortable that we mention the tag when talking
+> about the check on allocators but don't mention it when talking about
+> the check on a return statement, but I guess I can get over it.
+> I definitely think an AARM note is in order to emphasize that the need
+> for the check may depend on the value of the run-time tag when the
+> type is classwide.
+
+I agree with Tucker here, except that I disagree on the "can get over it".
+Moreover, I'm concerned that the intent is that the checks depends on some
+runtime effect when nothing actually says that.
+
+The /09 wording for return statements appears to be
+
+If the subtype determined by the expression of the simple_return_statement or by
+the return_subtype_indication...
+
+This seems to be talking about the nominal subtype of the expression, simply
+because there is no such thing as a runtime subtype. That means for a class-wide
+type, you are asking whether the class-wide type has access discriminants, which
+is not what we want. If you want to talk about the type determined by the tag, I
+think you need to say that explicitly:
+
+If the subtype determined by the expression of the simple_return_statement or by
+the return_subtype_indication (or the type indicated by the tag if the
+determined subtype is class-wide) has one or more access discriminants...
+
+or something like this. If not, Adam will complain. I think this is way too much
+for a to-be-honest note.
+
+...
+> > I am assuming that any changes that may result from Randy's
+> > discussion of whether the definition of the accessibility level of a
+> > formal needs revision will go in another AI.
+
+My head hurts just thinking about thinking about it. (That is, this is a
+meta-pain.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, November 16, 2010  3:22 PM
+
+> I'm trying to determine what, if any, work remains to be done for this
+> AI. Perhaps just adding an AARM note as mentioned above to the
+> existing version 09 wording?
+
+Plus the intended implementation model (the bit in the type descriptor).
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, November 16, 2010  3:30 PM
+
+> Plus the intended implementation model (the bit in the type
+> descriptor).
+
+Good point.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 16, 2010  3:41 PM
+
+> This seems to be talking about the nominal subtype of the expression,
+> simply because there is no such thing as a runtime subtype. That means
+> for a class-wide type, you are asking whether the class-wide type has
+> access discriminants, which is not what we want. If you want to talk
+> about the type determined by the tag, I think you need to say that explicitly:
+>
+> If the subtype determined by the expression of the
+> simple_return_statement or by the return_subtype_indication (or the
+> type indicated by the tag if the determined subtype is class-wide) has
+> one or more access discriminants...
+
+This isn't the part where the tag comes into play.  It is in:
+
+   Modify 6.5(21/2) as follows:
+
+     If [the result subtype]{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 [that of the master that elaborated the function body]
+     {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.
+
+That mammoth first sentence will need to be broken up a bit if we want to make
+it clear that whether the return object or its coextensions have discriminants
+may involve checking some run-time tags.  Something like the following might
+accomplish this:
+
+     A check is made whether any part of the return object (or any coextension thereof) of
+     a function has one or more access discriminants whose value is not
+     constrained by the result of the function; when the return object or any
+     coextension is of a class-wide type, this depends on the tag of the
+     object.  If any such access discriminants exist, then a check is made
+     that the accessibility level of ...
+
+Pretty groddy, but perhaps clearer (and Adam proof?).
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, November 17, 2010  7:04 PM
+
+>     A check is made whether any part of the return object (or any
+> coextension thereof) of
+>     a function has one or more access discriminants whose value is not
+>     constrained by the result of the function; when the return object
+> or any
+>     coextension is of a class-wide type, this depends on the tag of the
+>     object.  If any such access discriminants exist, then a check is made
+>     that the accessibility level of ...
+>
+> Pretty groddy, but perhaps clearer (and Adam proof?).
+
+A "check" which does not raise an exception or have any other similar
+consequence seems peculiar to me.
+
+Generally, we have wording of the form
+
+   A check is made that blah blah.
+   Mumble_Error is raised if this check fails.
+
+It seems odd to see
+
+    A check is made whether this object has any discriminants.
+    If it does, then a check is made that .... Program_Error
+    is raised if this second check fails.
+
+So here are my suggested changes, relative to the recently posted version 13 of AI05-0051.
+
+====
+
+Modify 4.8(10.1/2) 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
+      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.
+
+The only change is the parenthesized "(or by the tag ...)" wording.
+
+In 6.5(21/2) (as modified by AI05-0051), we've currently got
+
+    If any part of the return object (or coextension thereof) of a
+    function 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, 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 (see
+    3.10.2). If this check fails, Program_Error is raised.
+
+Are we missing an article inside the parens?
+Should that be "(or a coextension thereof)" or perhaps "(or any coextension
+thereof)"? Flip a coin, but either seems like an improvement. Splitting the
+phrase "return object of a function" by adding parens in the middle also seems
+confusing when I read it.
+
+In the phrase "the expression or the return_subtype_indication of the function",
+should "of the function" be replaced by "of the executed return statement"? Does
+it make sense to talk about, for example, *the* return_subtype_indication of a
+function?
+
+Or should that whole ", as determined
+by ... of the function," clause just be deleted?
+Otherwise, how does the current wording apply in a case like
+
+     return X : T'Class := ...  do ... end return;
+
+, where there is no expression and T'Class does not determine whether ther
+return object has access discriminants. So delete the clause.
+
+This all leaves us with
+
+    If any part 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.
+
+Add an AARM note after 6.5(21/2):
+
+   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, an implementation may
+   need to maintain data structures at runtime to keep track of
+   whether a given specific tagged type (as identified by its tag)
+   has unconstrained access discriminants (explicit or inherited)
+   or has any subcomponents with such discriminants.
+   If an implementation is already maintaining a runtime descriptor
+   of some kind for each tagged type, then an additional Boolean
+   could be added to this descriptor. In the cases where this flag
+   needs to be queried, the accessibility level of the
+   access dicriminant(s) (if any) is that of the return object.
+
+Do we need an AARM note to make it clear that this wording handles the following
+example?
+
+     X : aliased Integer;
+
+    type Component_Type (Discrim : access Integer := X'Access) is limited
+      null record;
+
+    type Undiscriminated is record F : Component_Type; end record;
+
+    function F return Undiscriminated is
+        Local : aliaed Integer;
+    begin
+        return X : Untagged := (F => (Discrim => Local'Access)) do
+          Foo;
+        end return;
+          -- raises P_E after calling Foo.
+    end F;
+
+I think no note is needed - the rule for this example follows from the "or has
+any subcomponents" wording above.
+
+This means that components with defaulted discrims must participate in the
+computation of the aforementioned descriptor bit. On the other hand, a component
+subject to a propagated discriminant constraint doesn't affect the setting of
+the bit.
+
+Note that we don't raise P_E before calling Foo because of
+3.10.2(10.1/2):
+
+    Within a return statement, the accessibility level of the return
+    object is that of the execution of the return statement. If the
+    return statement completes normally by returning from the function,
+    then prior to leaving the function, the accessibility level of the
+    return object changes to be a level determined by the point of call,
+    as does the level of any coextensions (see below) of the return
+    object.
+
+Do we need to explicitly state that we don't want to distinguish between present
+and inactive variant fields. Suppose that type Untagged in the preceding example
+had a Boolean discriminant which governed a variant part and the declaration of
+the F component was moved into one of the arms of the variant part. I think we
+want to look at tags at runtime, but not at discriminant values.
+
+Does this need a TBH note?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, November 17, 2010  8:20 PM
+
+> This all leaves us with
+>
+> If any part 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.
+
+Sounds good to me.
+
+>
+> Add an AARM note after 6.5(21/2):
+>
+> 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, an implementation may
+> need to maintain data structures at runtime to keep track of whether a
+> given specific tagged type (as identified by its tag) has
+> unconstrained access discriminants (explicit or inherited) or has any
+> subcomponents with such discriminants.
+> If an implementation is already maintaining a runtime descriptor of
+> some kind for each tagged type, then an additional Boolean could be
+> added to this descriptor. In the cases where this flag needs to be
+> queried, the accessibility level of the access dicriminant(s) (if any)
+> is that of the return object.
+>
+> Do we need an AARM note to make it clear that this wording handles the
+> following example?
+
+I wouldn't hurt to include this example in the AARM note.
+>
+> X : aliased Integer;
+>
+> type Component_Type (Discrim : access Integer := X'Access) is limited
+> null record;
+>
+> type Undiscriminated is record F : Component_Type; end record;
+>
+> function F return Undiscriminated is
+> Local : aliased Integer;
+> begin
+> return X : Untagged := (F => (Discrim => Local'Access)) do Foo; end
+> return;
+> -- raises P_E after calling Foo.
+> end F;
+>
+> I think no note is needed - the rule for this example follows from the
+> "or has any subcomponents" wording above.
+
+I agree it isn't necessary but it wouldn't hurt.
+>
+> This means that components with defaulted discrims must participate in
+> the computation of the aforementioned descriptor bit.
+> On the other hand, a component subject to a propagated discriminant
+> constraint doesn't affect the setting of the bit.
+>
+> Note that we don't raise P_E before calling Foo because of
+> 3.10.2(10.1/2):
+>
+> Within a return statement, the accessibility level of the return
+> object is that of the execution of the return statement. If the return
+> statement completes normally by returning from the function, then
+> prior to leaving the function, the accessibility level of the return
+> object changes to be a level determined by the point of call, as does
+> the level of any coextensions (see below) of the return object.
+>
+> Do we need to explicitly state that we don't want to distinguish
+> between present and inactive variant fields. Suppose that type
+> Untagged in the preceding example had a Boolean discriminant which
+> governed a variant part and the declaration of the F component was
+> moved into one of the arms of the variant part. I think we want to
+> look at tags at runtime, but not at discriminant values.
+
+Agreed.
+>
+> Does this need a TBH note?
+
+Yes, probably.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, November 17, 2010  9:39 PM
+
+...
+> This all leaves us with
+>
+>     If any part 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.
+
+I think this is OK, as it doesn't seem to say that you can figure out whether
+the check is needed statically.
+
+> Add an AARM note after 6.5(21/2):
+>
+>    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, an implementation may
+>    need to maintain data structures at runtime to keep track of
+>    whether a given specific tagged type (as identified by its tag)
+>    has unconstrained access discriminants (explicit or inherited)
+>    or has any subcomponents with such discriminants.
+>    If an implementation is already maintaining a runtime descriptor
+>    of some kind for each tagged type, then an additional Boolean
+>    could be added to this descriptor. In the cases where this flag
+>    needs to be queried, the accessibility level of the
+>    access dicriminant(s) (if any) is that of the return object.
+
+Is it possible to implement a tag without some sort of runtime descriptor? It
+would seem that the model of tagged types require such a descriptor somewhere.
+
+Note that the "runtime descriptor" is likely to be built at compile-time, and
+there isn't any need for this flag to be any different in that respect. So I
+think this note is misleading.
+
+I would have said something like:
+
+    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, an implementation
+    probably will need to 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. In the cases where this flag
+    needs to be queried, the accessibility level of the
+    access dicriminant(s) (if any) is that of the return object.
+
+Which is simpler and doesn't confuse compile-time determined indications with
+the runtime check of the flag.
+
+...
+> Do we need to explicitly state that we don't want to distinguish
+> between present and inactive variant fields.
+> Suppose that type Untagged in the preceding example had a Boolean
+> discriminant which governed a variant part and the declaration of the
+> F component was moved into one of the arms of the variant part. I
+> think we want to look at tags at runtime, but not at discriminant
+> values.
+>
+> Does this need a TBH note?
+
+This is clearly true based on the wording you gave, but it wouldn't hurt to have
+a Ramification that makes it clear that we intended that result. It's not a TBH,
+simply because the wording says precisely this ("any part" means exactly that,
+not any part that happens to be currently selected).
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent