CVS difference for ai05s/ai05-0005-1.txt
--- ai05s/ai05-0005-1.txt 2007/08/07 01:16:16 1.12
+++ ai05s/ai05-0005-1.txt 2007/09/13 02:20:42 1.13
@@ -1132,7 +1132,171 @@
****************************************************************
-Editor's note (August 3, 2007): All of the items above this
+From: Randy Brukardt
+Sent: Wednesday, September 5, 2007 11:38 PM
+
+I was fixing 7.6(16) as we discussed before I left on my ill-fated vacation, and I got
+to reading 7.6(16.b):
+
+Reason: The verbiage in the Initialize rule about access discriminants constrained
+by per-object expressions is not necessary here, since such types are limited, and
+therefore are never adjusted.
+
+["here" being the definition of "adjustment".]
+
+This looks like it is no longer true, as we surely can have access discriminants
+of nonlimited types these days.
+
+The "verbiage" in question gives a required order for operations. Do we need such an order?
+I don't think so, because an Adjust can't change the discriminant values of an object
+(only the assignment of the bits can do that). So I think that the reason above should
+say that and not depend on limited types.
+
+But if I forgot some case where an ordering is required, then we probably need an AI.
+Any idea if it is needed and if so, what it should say??
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, September 6, 2007 2:13 AM
+
+You can't give defaults to access discriminants
+in a non-limited type (3.7(10/2)). This means access
+discriminants never change after creation, and
+in particular can't be changed in an Adjust.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, September 6, 2007 9:45 PM
+
+Humm, I think we intended that, but I don't think it is actually true in
+*every* case. The rule about defaults does not apply to discriminants that
+have a named access type, so I think you could have a changeable per-object
+access discriminant. Making my best Steve Baird impression, consider the following:
+
+ type Comp_Type (CD : access Integer) is record
+ ...
+ end record;
+
+ type Acc_Int is access all Integer;
+
+ One : constant aliased Integer := 1;
+ Two : constant aliased Integer := 2;
+
+ type Obj_Type (D : Acc_Int := One'access) is record
+ Comp : Comp_Type (D);
+ end record;
+
+ Obj : Obj_Type;
+ Obj2 : Obj_Type (Two'access);
+
+ Obj := Obj2; -- Seems to change the discriminant of Comp.
+
+The discriminant D of Obj_Type is not an access discriminant, so 3.7(10/2) does
+not apply and it can have a default. D then is then used as a per-object constraint
+for Comp. When the assignment happens, D goes from One'access to Two'access, and
+surely the discriminant of Comp does too.
+
+This construct seems to not cause the problems that we fixed by dropping the
+discriminant default, because the accessibility check that was needed on the assignment
+is going to be done by the conversion to the named type of the outer discriminant.
+Consider:
+
+ procedure Fooey is
+ Three : constant aliased Integer := 3;
+ Obj3 : Obj_Type (Three'access); -- Error: Accessibility check fails.
+ begin
+ Obj := Obj3; -- Which is good 'cause we sure wouldn't want to allow this.
+ end Fooey;
+
+The net seems to be that you can change an access discriminant in very restricted
+circumstances, as there is no reason to disallow it.
+
+So the question remains: does this matter for Adjust? Initialize specifies that
+per-object constrained components are done last. But I can't think of a way where
+it might matter where they are done for adjustment, because an Adjust of a component
+cannot change the discriminant of the per-object constrained component; only the
+outer assignment can do that. And there is a requirement that inner (component)
+Adjusts be done first, so a surrounding one that changed such a discriminant would
+necessarily happen after any component Adjusts were completed, eliminating any issue.
+
+So 7.6(16.b) should just be fixed.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, September 7, 2007 7:23 AM
+
+My head hurts... ;-)
+
+Interesting example. It is generally true that
+by changing the discriminant of an object in
+a whole-object assignment you can do all kinds
+of violence to its components, including having
+them disappear or appear (if the component is
+in a discriminant-dependent variant), get
+shorter or longer, etc. I guess we need to
+add that you can change the value of an access
+discriminant of a component as another kind
+of violence.
+
+I'm pretty sure we *did* include the case of an
+access discriminant initialized from an enclosing
+discriminant when we analyzed the safety of
+allowing access discriminants on nonlimited
+types. On the other hand, I don't remember
+considering this particular nastiness, and I
+am comforted that you see no accessibility
+holes opening as part of the enclosing assignment.
+
+In some ways, when doing a whole-object assignment that
+changes discriminants, one might best view it as
+destroying one object and creating a new one.
+And in fact, since Finalize is applied to the
+left hand side, and then it is completely overwritten
+followed by an Adjust, it closely resembles the
+process of destruction and recreation. On the
+other hand, renames of components and access-values
+designating components are permitted to survive
+across these "mutating" assignments so long as the
+components aren't "discriminant dependent." Any
+component whose access discriminant comes from
+an enclosing discriminant is clearly discriminant
+dependent, so we that means we *can* think of the
+component as disappearing and then reappearing
+with a new discriminant value after the assignment.
+
+I suppose if it is a subcomponent but not a direct
+component, then it is possible that the Adjust
+might involve another whole-object assignment to
+an enclosing component. E.g.
+
+ procedure Adjust(X : in out Outer_Rec) is
+ begin
+ X.Go_Between := Massage(X.Go_Between);
+ -- Presume our subcomponent of interest is
+ -- inside "Go_Between" and has an access discrim
+ -- passed down from the "Go_Between" component
+ -- This could change its discriminant again.
+ end Adjust;
+
+Note that it would be quite unwise if Outer_Rec's Adjust
+involved a whole-object assignment to X itself; e.g.:
+
+ X := Massage_Outer_Rec(X);
+
+as this would trigger an infinitely recursive call on
+Outer_Rec's Adjust.
+
+I've reached the point of blathering... ;-)
+
+In any case, thanks for doing the analysis of this
+nasty case.
+
+****************************************************************
+
+Editor's note (September 6, 2007): All of the items above this
marker have been included in the working version of the AARM.
****************************************************************
Questions? Ask the ACAA Technical Agent