CVS difference for ais/ai-00252.txt

Differences between 1.10 and version 1.11
Log of other versions for file ais/ai-00252.txt

--- ais/ai-00252.txt	2004/01/23 04:59:24	1.10
+++ ais/ai-00252.txt	2004/09/04 01:13:43	1.11
@@ -1,4 +1,5 @@
-!standard 04.01.03 (09)                               03-12-03  AI95-00252/07
+!standard 04.01.03 (09)                               04-08-26  AI95-00252/08
+!standard 04.01.03 (13)
 !standard 04.01.03 (15)
 !standard 06.03.01 (10)
 !class amendment 00-12-04
@@ -108,6 +109,14 @@
     selected_component. The selected_component denotes a view of this
     subprogram that omits the first formal parameter.
 
+Add the following after 4.1.3(13):
+
+   Legality Rules
+
+If a selected_component resolves to a view of a subprogram whose first
+parameter is an access parameter, the prefix shall denote an aliased view of an
+object.
+
 Add the following after 4.1.3(15):
 
     For a selected_component with a tagged prefix and selector_name that
@@ -170,6 +179,9 @@
 
 The implicit .all and "'Access" are added because they seem like useful
 capabilities which do not significantly complicate the proposal.
+This does not change the requirements on the object; in particular, an
+access parameter's object must be an aliased view. This is a legality rule,
+because we don't want resolution to depend on whether something is aliased.
 
 We talk about "covering" types rather than "ancestor" types for two reasons.
 One is that it is only operations on class-wide types that are being imported
@@ -275,6 +287,25 @@
 @fa<selected_component>. The @fa<selected_component> denotes a view of this
 subprogram that omits the first formal parameter.>
 
+!corrigendum 4.1.3(13)
+
+@dinsa
+If the @fa<prefix> does not denote a package, then it shall be a
+@fa<direct_name> or an expanded name, and it shall resolve to denote a program
+unit (other than a package), the current instance of a type, a
+@fa<block_statement>, a @fa<loop_statement>, or an @fa<accept_statement> (in
+the case of an @fa<accept_statement> or @fa<entry_body>, no family index is
+allowed); the expanded name shall occur within the declarative region of this
+construct. Further, if this construct is a callable construct and the
+@fa<prefix> denotes more than one such enclosing callable construct, then the
+expanded name is ambiguous, independently of the @fa<selector_name>.
+@dinst
+@i<@s8<Legality Rules>>
+
+If a @fa<selected_component> resolves to a view of a subprogram whose first
+parameter is an access parameter, the @fa<prefix> shall denote an aliased view
+of an object.
+
 !corrigendum 4.1.3(15)
 
 @dinsa
@@ -771,3 +802,297 @@
 [This is version /05 - ED.]
 
 ****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, June 25, 2004  2:55 PM
+
+AI 252 seems to make the following program legal:
+
+    type T is tagged null record;
+    function H (Y : access T) return Integer;
+
+    X : T;
+
+    C : Integer := X.H; -- Legal?
+
+Notice that we have managed to pass to H an access value designating a
+non-aliased object.  I realize that tagged types are passed by reference,
+but it seems surprising that the Object.Operation notation would give you
+the capability to pass X as an actual for an anonymous access type in
+circumstances where X'Access would be illegal.
+
+Was this intended?  The proposal section of the AI seems to indicate that
+the above call should be legal only if X is aliased, but I see no rule to
+that effect in the wording section.
+
+If the AI needs to be amended, this should be a legality rule, not a name
+resolution rule.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, June 25, 2004  5:50 PM
+
+It's certainly hard to say from the AI. Moreover, it's hard to say from our
+other thinking (for instance, that "T" and "access T" be essentially equivalent
+for tagged incomplete types).
+
+Argubly, its the requirement of "aliased" on tagged objects that is unnecessary
+(since the type is already by-reference and implicitly aliased). So an argument
+could be made to drop that altogether.
+
+But in tha absence of that, I agree that there should be a rule; the clear
+intent is that the prefix form not be different from the normal form.
+
+> If the AI needs to be amended, this should be a legality rule, not a name
+> resolution rule.
+
+I agree; a resolution rule would be awful for this (requiring different sets of
+operations to be considered depending on the aliased state). (Indeed,
+resolution rules shouls be added only when absolutely necessary - legality
+rules are usually better, because the cause of the error is easier to report
+accurately and thus fix.)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, June 28, 2004  2:24 AM
+
+> Argubly, its the requirement of "aliased" on tagged objects
+> that is unnecessary (since the type is already by-reference
+> and implicitly aliased).
+> So an argument could be made to drop that altogether.
+
+I see you point, but I think it would be a bad idea, and it would weaken
+the safety of Ada.  If I declare a non-aliased object of a
+tagged/task/protected type, I know for a fact that it won't be altered by
+accesses through access values.  That helps me assert the correctness of
+my program.  If all such objects become aliased, then it becomes very much
+like C, where I always have to worry that a pointer operation could wreak
+havoc behind my back.  So we should not confuse aliased (a logical
+property at the source level) and by-reference (a physical property at the
+implementation level).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 28, 2004  1:08 PM
+
+Humm. When the object is passed as a parameter, that allows the implementation
+to take an Unchecked_Access of it and keep it. (That's precisely what Claw does
+- and it can modify the object "behind your back", if something happens in
+Windows that requires it [such as closing the parent window]. No havoc, I
+hope.) So I don't think there is any such property in Ada 95.
+
+It's true that if the type is private (not tagged private), the "havoc" can
+occur only within the abstraction. But that would still be true (if not visibly
+tagged, then not aliased, either). Otherwise, the only protection is on
+directly taking 'Access of the object (but formals are all right), and that
+doesn't seem to be a worthwhile restriction for correctness.
+
+The property you mention is a useful one, it just doesn't exist for tagged
+types in Ada 95. And that's not a huge problem, because tagged types are
+generally used in tight abstractions, where the only way to modify an object is
+to use the abstraction. In this case, nothing bad is likely to happen even if
+someone does keep an access behind your back.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, June 29, 2004  12:06 PM
+
+> It's true that if the type is private (not tagged private),
+> the "havoc" can occur only within the abstraction.
+
+Now that you mention this, it is clear that making tagged objects aliased
+by default would be privacy breaking.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, June 29, 2004  12:15 PM
+
+Huh? An object would only have the properties that the current view of its type
+has, so certainly an object of a non-tagged private type would not be aliased,
+even if the full type is tagged. That's already true for the magic parameter
+rule (if the type isn't tagged, you can't take 'Access of it, even if you could
+have done so knowing the full type). All I was suggesting to do was to extend
+that rule to cover all known-to-be-tagged objects.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, July 14, 2004  12:43 PM
+
+It was my original intent that an "implicit" 'Access would only
+be permitted if the object were explicitly declared "aliased."
+
+In general I think it is still wise to require an explicit
+"aliased" on tagged object declarations to permit use
+of explicit 'Access, even though we make tagged formals implicitly
+aliased.
+
+On the other hand, I could be convinced that allowing an implicit 'Access
+in the Object.Operation notation should not require an
+explicit "aliased", since that will almost certainly be a source
+of confusion for the user, and doesn't add a lot of safety.
+
+In other words, I am on the fence about this one.
+
+If pushed for a decision, I guess I favor not requiring
+the "aliased" for this implicit 'Access.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, July 29, 2004  11:49 AM
+
+If pushed for a decision, I would favor requiring "aliased" for the
+implicit Access.  That's because it makes it easier to explain that this
+is "merely" a syntactic transformation.  I am opposed to the notion of
+adding special semantics to the Obj.Op notation.
+
+An alternative would be to say that "aliased" is not required for objects
+of by-reference types, and do that for both implicit and explicit Access.
+But that looks like a bigger change.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, July 29, 2004  12:12 PM
+
+I am happy to follow Pascal's view on this, because as I said
+I am very much on the fence about it.  That is, stick with the
+pure syntactic transformation, and require that the prefix be
+aliased.  Note that formal tagged parameters are implicitly aliased,
+so you wouldn't have to worry when using a formal parameter as
+the prefix.  That is probably a somewhat more common case than having
+a local object.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, July 29, 2004  7:43 PM
+
+While I would prefer to completely eliminate the requirement for aliased on
+by-reference types, the middle position is a bit uncomfortable. So I'll
+go along with this resolution.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, August 12, 2004  4:57 AM
+
+Steve ran into a contract model problem with AI 252 as currently written.
+
+3.9.2(8) has a rule that prevents mixing statically and dynamically tagged
+controlled operands.  It is unclear how to check this rule in generic bodies
+with the Obj.Op notation.  Consider:
+
+	package Pack is
+	    type T is tagged ...;
+	    procedure Prim (U, V : T);
+	end;
+
+	X : Pack.T'Class := ...;
+	Y : Pack.T;
+
+	generic
+	    with procedure Formal1 (W : Pack.T);
+	    with procedure Formal2 (W : Pack.T);
+	procedure Gen;
+
+	procedure Gen is
+	begin
+	    Formal1 (Y);
+	    Formal2 (X);
+	end;
+
+	procedure Inst is Gen (Formal1 => X.Prim, Formal2 => Y.Prim);
+
+The calls to Formal1 and Formal2 in the instance body violate the no-mixing
+rule.
+
+We seem to have two options:
+
+1 - Disallow the instantiation, i.e. say that you cannot pass Obj.Op as a
+generic actual.  That seems like a significant loss of functionality to me.  If
+we believe that it is convenient to avoid having to name the package when
+calling a subprogram, that's true when instantiation a generic too.
+
+2 - Assume the best on generics, recheck on the specification of
+instantiations, and do a run-time check in generic bodies.  If the check fails
+it will look quite mysterious to users, but then it's not going to fail very
+often because this situation is somewhat of a pathology.
+
+Whatever we decide, we should adopt a consistent position for subprogram
+renamings.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, August 26, 2004  9:30 PM
+
+I'd think that a better fix would be:
+
+3 - Follow the standard rules for legality (which say that this is only checked
+in a generic spec.) and then let the standard tag checking rules do the job in
+any calls not covered. That makes more sense than a mysterious runtime legality
+rule check. It does require some mods to 3.9.2(15), to say that any dynamically
+tagged operands are checked to see that they have the tag T. But that is
+consistent with the rule 3.9.2(16) and *much* more palatable than a special
+runtime legality check.
+
+Wait a minute. A formal subprogram is never a dispatching operation (AI-200
+reaffirms this). Thus, 3.9.2(8) never applies to a call on a formal subprogram
+as in the example above. That's a good thing!
+
+Whatever happens for a mixed static/dynamic non-dispatching call should happen
+here. (I think that the dynamic operand is effectively truncated to the
+specific type. That's ugly in my view, but whatever.) This case doesn't seem to
+be a problem.
+
+A rename can be a primitive operation, but a prefix call needs an object, and
+the object will freeze the type, making the further declaration of primitive
+operations illegal. So there is no problem there, either. So no change to the
+standard or the AI is needed.
+
+Have I missed something?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, August 27, 2004  1:41 AM
+
+> Wait a minute. A formal subprogram is never a dispatching
+> operation (AI-200 reaffirms this). Thus, 3.9.2(8) never
+> applies to a call on a formal subprogram as in the example
+> above. That's a good thing!
+>
+> Whatever happens for a mixed static/dynamic non-dispatching
+> call should happen here. (I think that the dynamic operand is
+> effectively truncated to the specific type. That's ugly in my
+> view, but whatever.) This case doesn't seem to be a problem.
+
+Yes, you're absolutely right.  No problem in this case.
+
+> A rename can be a primitive operation, but a prefix call
+> needs an object, and the object will freeze the type, making
+> the further declaration of primitive operations illegal. So
+> there is no problem there, either. So no change to the
+> standard or the AI is needed.
+
+This is not exactly true, because the prefix of the call can be an access
+value, and that won't freeze the (tagged) type.  But it still the case
+that for renamings all the information can be easily obtained by the
+compiler: you look at the prefix of the call, and act as if it were a
+parameter.  You may have to go through many levels of renamings,
+collecting the prefixes as you go, but the processing is not fundamentally
+different from what you currently do.  (At least, that's how I have
+implemented it.)
+
+So I agree that there is no problem here, but it's still good to record
+this discussion in the AI for future reference.
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent