CVS difference for ai05s/ai05-0188-1.txt
--- ai05s/ai05-0188-1.txt 2010/07/28 05:52:58 1.8
+++ ai05s/ai05-0188-1.txt 2010/10/13 04:22:42 1.9
@@ -864,3 +864,477 @@
that.
****************************************************************
+
+From: Steve Baird
+Sent: Monday, August 2, 2010 6:20 PM
+
+In discussions with Randy, we have run into what appear to be some loose ends
+pertaining to conditional expressions.
+
+1) We need wording in 6.2 to extend the definition of
+ "associated object" to handle conditional expressions.
+ This looks easy to fix.
+
+2) 6.5(5.6/3) seems to be a redundant copy of 7.5(2.8/2)
+ which didn't get updated. Rather than update it, it
+ should probably be deleted. Also easy.
+
+3) Interactions between conditional expressions and
+ accessibility levels may need some more thought.
+ Or perhaps these have all been thought about and there
+ are no problems here - given that AIs 147 and 188 do not
+ mention the word "accessibility", this seems unlikely.
+
+ Consider determining the (static) legality of
+ T'(<conditional expression>).Aliased_Component'Access
+
+ Is the static accessibility level of the prefix of the
+ Access attribute well-defined ? It doesn't seem to be.
+
+ One's first reaction in a case like this should be to ask
+ "how are parenthesized expressions handled?". Unfortunately,
+ it is not obvious how to generalize 3.10.2(9/2) to handle
+ conditional expressions:
+ The accessibility level of a view conversion,
+ qualified_expression, or parenthesized expression, is the
+ same as that of the operand.
+ Perhaps we could follow the rules for an aggregate.
+
+ It may be that the dynamic accessibility level of a conditional
+ expression is easy to define as that of the selected dependent
+ expression, but that idea needs both wording and review.
+
+ 6.5 has a legality rule for functions with class-wide results that
+ is defined in terms of the accessibility level of the type of
+ of the (returned) expression. Does this rule do what we want
+ in the case of a conditional expression?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, August 2, 2010 6:38 PM
+
+I would suggest we say that conditional expressions are not aliased, though if
+they are tagged then a formal parameter that denotes a conditional expression is
+of course aliased (but very local).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, August 2, 2010 7:42 PM
+
+That doesn't help. Steve made a similar argument privately, and that would
+surely work for 'Access. But we also have 4.8(5.1/2) and 6.5(5.6/2) [this is
+6.5(5.7/3) in the latest RM draft] that test the accessibility of classwide
+returns (so that objects of more nested types don't get returned). There are
+similar rules for access discriminants (I'm not sure this one can happen, but
+the classwide one surely can). In both of those cases, nothing needs to be
+aliased to trigger the check.
+
+For instance, using 4.8(5.1/2) as the example, what is the static accessibility
+of:
+
+ new T'Class'(if C then A else B)
+
+if A and B have different tagged types at different levels? (The dynamic
+accessibility is less of a problem, as we can just use the level of whatever is
+actually selected.)
+
+We could say that there is no static level in this case (but that threatens all
+of the analysis we've done about dynamic checks not being needed in return
+cases, since that analysis assumes that static checks are made). Or we could
+define a rule requiring the static checks for all of the dependent_expressions
+to pass (but that seems to require changes to 4.8(5.1/2) and 6.5(5.7/3), since I
+can't imagine any way to say in 3.10.2 that conditional_expressions have
+*multiple* static accessibility levels!). Or we could require that the static
+accessibility level of a conditional_expression is calculable by requiring some
+relationship (but that seems limiting for a case that will be very rare in
+practice). No good answer seems obvious...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, August 2, 2010 7:57 PM
+
+Perhaps a "simple" equivalence would handle the function return, by saying that
+a return of a conditional expression is legal only if a return of each of the
+dependent expressions would be legal.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, August 3, 2010 11:13 AM
+
+>> I would suggest we say that conditional expressions are not aliased,
+>> though if they are tagged then a formal parameter that denotes a
+>> conditional expression is of course aliased (but very local).
+>
+> That doesn't help.
+
+It also doesn't help for another reason. Sure conditional expressions are not
+aliased (they don't occur on the list given at the point where the term
+"aliased" is defined), but they can have aliased subcomponents.
+
+Note the example in my original message:
+> Consider determining the (static) legality of
+> T'(<conditional expression>).Aliased_Component'Access
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, August 3, 2010 11:34 AM
+
+Then I would recommend you treat it like a function call or an aggregate, as you
+suggested.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, August 18, 2010 1:44 PM
+
+I think this is right, but I will point out an issue with this approach which
+seems worth mentioning even if we decide to ignore it.
+
+Ideally, I think that it would be desirable to have a conditional expression
+with a static selector expression
+ if True then <exp1> else <exp2>
+be as semantically similar as possible to a parenthesized expression
+ (<exp1>)
+. As a design principle, we want to avoid subtle differences between
+almost-identical things in order to allow program transformations, avoid
+confusion, etc.
+
+[Ok, if you really want to get picky to avoid interactions with freezing rules,
+assume that exp2 is another copy of exp1 - otherwise exp2 might freeze
+something]
+
+3.10.2(9/2) states:
+ The accessibility level of a ... parenthesized expression, is the same
+ as that of the operand.
+
+To maintain the equivalence that I am asserting is at least somewhat desirable,
+we would need to special case either
+ 1) a conditional expression with a static selector expression or
+ 2) a conditional expression all of whose dependent expressions have
+ the same static accessibility level
+or perhaps even a combination of the two (#1 if selector is static, #2
+otherwise) in defining the accessibility level of a conditional expression.
+
+On the other hand, perhaps this doesn't matter. How often is a user going to
+want to do something like
+
+ Flag : Boolean := ... ; -- non-static
+ type R is record F : aliased Integer; end record;
+ R1, R2 : R;
+ type Ref is access constant Integer;
+ Ptr : Ref;
+ begin
+ Ptr := R'(if Flag then R1 else R2).F'Access;
+ declare
+ R3 : R;
+ begin
+ Ptr := R'(if True then R1 else R3).F'Access;
+
+?
+
+The proposed simple, clean "treat it like an aggregate" rule would reject both
+of the two Access attribute uses in this example. Is this ok?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, August 18, 2010 8:22 PM
+
+My initial reaction is that it is not OK. Not so much because of an example like
+this, but because of the potential accessibility checks in allocators and return
+statements. I would not want to see
+
+ return (if Flag then Obj1 else Obj2);
+
+to become illegal because the objects have different types (or whatever it is
+that you are claiming makes the first example illegal; I'm not sure exactly what
+rule you are proposing - the "same as an aggregate" would make all accessibility
+checks fail as an aggregate is extremely local and that makes no sense at all in
+any case where accessibility levels matter).
+
+I thought that we were considering a "runtime check only" for these; it's hard
+to imagine any other rule that will work for these (unless we want to do a
+static check when all of the operands have the same static level). Any other
+rule would be the same as making them illegal in all contexts that require an
+accessibility check, and I don't think that is desirable for any of the reasons
+that you mentioned at the beginning of your message.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, August 19, 2010 11:57 AM
+
+> My initial reaction is that it is not OK. Not so much because of an
+> example like this, but because of the potential accessibility checks
+> in allocators and return statements.
+
+I agree that the example I gave is unimportant. That was my point in asking "how
+often is a user going to want to do ... ?".
+
+Your point that it is probably more important to look at scenarios involving
+return statements and allocators is a good one.
+
+To illustrate your point: given a (non-limited) type with an access
+discriminant, what is the status of
+
+ function F return Has_Access_Discrim is
+ begin
+ if ... then
+ return Global_Var1; -- OK
+ elsif ...
+ return Global_Var2; -- OK
+ else
+ return (if ... then Global_Var1 else Global_Var2); -- ???
+ end if;
+
+with respect to the static accessibility check of 6.5(5.7/3) ?
+
+> I would not want to see
+>
+> return (if Flag then Obj1 else Obj2);
+>
+> to become illegal because the objects have different types (or
+> whatever it is that you are claiming makes the first example illegal;
+> I'm not sure exactly what rule you are proposing - the "same as an
+> aggregate" would make all accessibility checks fail as an aggregate is
+> extremely local and that makes no sense at all in any case where accessibility levels matter).
+
+I was saying that my example would be illegal because the "same as an aggregate"
+rule would cause each conditional expressions to have the accessibility levels
+of its enclosing statement, which would make them too short-lived to be
+designated by a value of type Ref.
+
+The "same as an aggregate" rule makes sense if the implementation model allows
+making a copy. Making a copy is never required; it should be forbidden at least
+in the case of a by-reference type (this follows from the definition of
+"associated object", which we have already noted requires updating). The
+question is whether making a copy should be forbidden in (some) other cases, as
+is implicitly done for parenthesized expressions in 3.10.2(9/2):
+ The accessibility level of a ... parenthesized expression, is the
+ same as that of the operand.
+This rule, in effect, forbids making a copy in at least some cases where the
+accessibility level matters, such as
+
+ Global_Ptr := T'((Global_Var)).Aliased_Component'Access
+
+Note that we don't want to forbid copying in all cases (e.g., a dependent
+expression which is a slice of a packed array of Booleans), but this is not a
+problem because accessibility levels don't matter in these cases (just as for a
+parenthesized expression whose operand is such a slice).
+
+> I thought that we were considering a "runtime check only" for these;
+> it's hard to imagine any other rule that will work for these (unless
+> we want to do a static check when all of the operands have the same
+> static level). Any other rule would be the same as making them illegal
+> in all contexts that require an accessibility check, and I don't think
+> that is desirable for any of the reasons that you mentioned at the beginning of your message.
+
+I don't understand what you are suggesting. Could you suggest wording, or at
+least be more specific?
+
+I could imagine a legality rule that the static accessibility levels of the
+dependent expressions must be pairwise comparable (as opposed to equal). The
+(static) accessibility level of the conditional expression could then be defined
+to be that of its most short-lived dependent expression.
+
+Please remind me of the status of AIs 147 and 188.
+Do we need a new AI to discuss this stuff?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, August 19, 2010 1:30 PM
+
+...
+> Note that we don't want to forbid copying in all cases (e.g., a
+> dependent expression which is a slice of a packed array of Booleans),
+> but this is not a problem because accessibility levels don't matter in
+> these cases (just as for a parenthesized expression whose operand is
+> such a slice).
+
+I didn't think we wanted to allow making a copy. It surely would screw up
+limited types and build-in-place (which we do allow for conditional
+expressions).
+
+> > I thought that we were considering a "runtime check only" for these;
+> > it's hard to imagine any other rule that will work for these (unless
+> > we want to do a static check when all of the operands have the same
+> > static level). Any other rule would be the same as making them
+> > illegal in all contexts that require an accessibility check, and I
+> > don't think that is desirable for any of the reasons that you
+> > mentioned at the beginning of your message.
+>
+> I don't understand what you are suggesting. Could you suggest wording,
+> or at least be more specific?
+
+Wording for accessibility rules? Have you lost your mind? ;-) I don't want to
+spend three days on this, that's your assignment.
+
+I was suggesting something along the lines of:
+
+If the static accessibility levels of the dependent_expressions are all the
+same, the static accessibility level of the conditional_expression is that
+level. Otherwise, the conditional_expression does not have a static level (the
+dynamic accessibility checks will take care of it).
+
+The only problem with this is that it might invalidate the analysis which
+"proved" no need for runtime overhead for aliased and tagged parameters (we
+don't want to have to pass dynamic accessibility levels with them; the entire
+point is to eliminate that runtime hazard from programs). The reason that's a
+problem is that the analysis depends on the static check rejecting any cases
+where the dynamic check could fail; if there is a way to "strip" the static
+check, then the dynamic check has to be made and it requires passing levels with
+parameters.
+
+> I could imagine a legality rule that the static accessibility levels
+> of the dependent expressions must be pairwise comparable (as opposed
+> to equal). The (static) accessibility level of the conditional
+> expression could then be defined to be that of its most short-lived
+> dependent expression.
+
+That's probably a better idea than the above.
+
+> Please remind me of the status of AIs 147 and 188.
+> Do we need a new AI to discuss this stuff?
+
+AI-147 was approved, but AI-188 was not. So we could put any new rules in
+AI-188 - it already makes changes to AI-147 (I'll file this thread onto that
+AI.) It would be nice to have this worked out before the October meeting,
+though.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, August 19, 2010 2:31 PM
+
+>> Making a copy ... should be forbidden at least in the case of a
+>> by-reference type (this follows from the definition of "associated
+>> object", which we have already noted requires updating).
+
+> I didn't think we wanted to allow making a copy. It surely would screw
+> up limited types and build-in-place (which we do allow for conditional
+> expressions).
+
+A type for which build-in-place is required is always a by-reference type. As
+noted earlier, we don't allow copying for those.
+
+And we pretty much have to allow copying for elementary types.
+
+It's those composite but not by-reference types that are the question.
+I feel that the existing rules for parenthesized expressions should be used as
+guidelines in resolving this.
+
+> Wording for accessibility rules? Have you lost your mind? ;-) I don't
+> want to spend three days on this, that's your assignment.
+
+It was worth a try ...
+
+> I was suggesting something along the lines of:
+>
+> If the static accessibility levels of the dependent_expressions are
+> all the same, the static accessibility level of the
+> conditional_expression is that level. Otherwise, the
+> conditional_expression does not have a static level (the dynamic accessibility checks will take care of it).
+
+"Does not have a static level" would break lots of rules which assume that every
+object has a well-defined accessibility level. Perhaps you want something along
+the lines of 3.10.2 (13.1/2)'s
+ The accessibility level of <blah blah> is deeper than that of
+ any master; all such <blah blah>s have this same level.
+?
+
+> It would be nice to have this worked out before the October meeting,
+
+Agreed.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, August 19, 2010 4:04 PM
+
+> "Does not have a static level" would break lots of rules which assume
+> that every object has a well-defined accessibility level.
+
+I don't think this is a real problem; access parameters don't have static levels
+(for one example). Static levels are defined only for a subset of objects. I'd
+be more worried about losing the assumption that composite parameters (to take
+one example) always have a static level.
+
+>Perhaps you want something along the
+> lines of 3.10.2 (13.1/2)'s
+> The accessibility level of <blah blah> is deeper than that of
+> any master; all such <blah blah>s have this same level.
+> ?
+
+Well, that would always cause the static check to fail unless the objects have
+the same level; I don't think that is what we want. But we do have to remember
+to deal with the case where there is no (useful) static level, as in access
+parameters.
+
+BTW, in taking a quick look at 3.10.2, there doesn't seem to be a concept of
+static levels, just a static comparison ("statically deeper than") which is not
+defined for all objects.
+
+So I would say that the accessibility level of a conditional_expression is that
+of the selected dependent_expression (that's obviously dynamic). And then a
+bunch of rules to allow "statically deeper than" to be calculated.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, August 20, 2010 12:21 AM
+
+...
+> I don't think this is a real problem; access parameters don't have
+> static levels (for one example). Static levels are defined only for a
+> subset of objects. I'd be more worried about losing the assumption
+> that composite parameters (to take one example) always have a static
+> level.
+
+AI05-0148 says the same applies to stand-alone objects of anonymous
+access-to-object types. The following wording is in 3.10.2(19-19.1/3):
+
+* The statically deeper relationship does not apply to the accessibility level
+ of the anonymous type of an access parameter specifying an access-to-object
+ type; that is, such an accessibility level is not considered to be statically
+ deeper, nor statically shallower, than any other.
+
+* The statically deeper relationship does not apply to the accessibility level
+ of the type of a stand-alone object of an anonymous access-to-object type;
+ that is, such an accessibility level is not considered to be statically
+ deeper, nor statically shallower, than any other.
+
+All I was proposing is that the same applies to conditional_expressions if the
+dependent_expressions don't have the same static level.
+
+But I think that would break AI-142-4, requiring lots of distributed overhead
+for a silly reason. Tucker and I spent a lot of effort proving that:
+
+ return Some_Param.Component'Access;
+
+never needs a dynamic check (and thus there is no overhead to pass a level with
+the parameter), because any case which causes trouble is illegal (fails the
+static check). But if writing:
+
+ return (if True then Some_Param.Component'Access else null);
+
+gets rid of the static level and requires a dynamic check on the first
+dependent_expression, the entire analysis collapses. (It wouldn't surprise me if
+that happened in other, older cases as well; I just remember the AI-142-4 one
+because it is recent.)
+
+So I think we have to follow your idea of using the statically deepest level of
+any of the dependent_expressions (at least of those which have a level,
+anonymous parameters and objects don't, and literals don't, either). That might
+make some expressions which would work illegal, but the static checks already do
+that, and at least one of the dependent_expressions would have to be illegal in
+order for the entire expression to be illegal, which seems like enough.
+
+I'll leave wording this as an exercise for the OP (original poster) - Mr. Baird.
+
+****************************************************************
Questions? Ask the ACAA Technical Agent