CVS difference for ais/ai-00168.txt

Differences between 1.8 and version 1.9
Log of other versions for file ais/ai-00168.txt

--- ais/ai-00168.txt	1999/08/31 22:53:55	1.8
+++ ais/ai-00168.txt	1999/10/08 23:41:05	1.9
@@ -1,4 +1,4 @@
-!standard 04.06    (12)                               99-08-31  AI95-00168/04
+!standard 04.06    (12)                               99-10-06  AI95-00168/05
 !standard 03.07.01 (07)
 !class binding interpretation 96-11-16
 !status Corrigendum 2000 99-07-27
@@ -80,7 +80,7 @@
 conversion to convert an array object with aliased components to an array type
 with non-aliased components.  Such a conversion must be disallowed.
 
-At the Henley meeting, the following case was also discussed:
+At an ARG meeting, the following case was also discussed:
 
   with Q;
   package body P is
@@ -110,25 +110,33 @@
 
 !corrigendum 3.07.01(7)
 
-@dinsa
+@drepl
 A @fa<discriminant_constraint> is only allowed in a @fa<subtype_indication> whose
 @fa<subtype_mark> denotes either an unconstrained discriminated subtype, or an
 unconstrained access subtype whose designated subtype is an unconstrained
 discriminated subtype.
-@dinst
-A @fa<discriminant_constraint> is not allowed in a @fa<subtype_indication> whose
-@fa<subtype_mark> denotes a general access subtype whose designated subtype is a
-private type with defaulted discriminants, if the partial view of the private
-type has no discriminants.
+@dby
+A @fa<discriminant_constraint> is only allowed in a @fa<subtype_indication> whose
+@fa<subtype_mark> denotes either an unconstrained discriminated subtype, or an
+unconstrained access subtype whose designated subtype is an unconstrained
+discriminated subtype. However, in the case of a general access subtype, the
+designated subtype shall not be of a type whose partial view is constrained.
+
+!corrigendum 4.06(11)
 
+@drepl
+@xbullet<Corresponding index types shall be convertible; and>
+@dby
+@xbullet<Corresponding index types shall be convertible;>
+
 !corrigendum 4.06(12)
 
-@dinsa
+@drepl
 @xbullet<The component subtypes shall statically match.>
-@dinst
-In a view conversion for an array type, the target type and the operand type
-shall either both have aliased components, or both have non-aliased
-components.
+@dby
+@xbullet<The component subtypes shall statically match; and>
+@xbullet<In a view conversion, the target type and the operand type shall both
+or neither have aliased components.>
 
 !ACATS test
 
@@ -175,6 +183,342 @@
 do not appear to cover the case shown above, but it appears that a view
 conversion between an unconstrained and constrained view of an object
 should be illegal.
+
+****************************************************************
+
+From the editor:
+
+While reviewing the corrigendum wording at the September 1999 meeting,
+Robert Eachus pointed out the problem of 3.7.1(7) can also happen for derived
+types where additional visibility appears at a later point:
+
+   package P is
+     type T is private
+   private
+     type T (D: integer := _) is
+   end P;
+
+   package P.Child is
+      type NT is new P.T;
+      type ANT is access all NT;
+   private
+      subtype SANT is ANT (1); -- Illegal, we hope!
+   end P.Child;
+
+The wording and AI will need to be updated to reflect this.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 6, 1999
+
+I have been going back and forth in my mind whether
+an aliased object whose type is private without discriminants,
+but whose full view has defaulted discriminants, is constrained
+by its initial value.  E.g.:
+
+   procedure test is
+       package p is
+           type T is private;
+           T_True : constant T;
+       private
+           type T(D : Boolean := False) is record
+               case D is
+                   when True => String(1..10);
+                   when False => null;
+               end case;
+           end record;
+           T_True : constant T := (D => True, (others => 'x'));
+       end;
+       X : aliased P.T;  -- Default initialized with D => False;
+                         -- is it constrained?
+   begin
+       X := T_True;  -- Constraint_Error?
+   end;
+
+3.3.1(9) indicates that an object is constrained by its initial value
+if it is aliased and has an unconstrained nominal subtype.
+X has a constrained nominal subtype, since T has no discriminants
+at the point where X is declared.  So are we allowed to change its
+discriminant by a whole-object assignment?
+
+Note that this is related to the following question:
+
+Is the object created by an allocator for an access-to-T type
+constrained by its initial value?
+
+The "aliased" keyword didn't exist in Ada 83, but clearly what we
+now call "aliased" objects did, namely those objects created by
+allocators.  The reason for forcing objects in the heap with discriminants
+to be constrained is the possibility of access subtypes, where
+a value might be set to point to the object when the discriminant
+has one value, and then, if unconstrained, might have its discriminant
+changed in a way inconsistent with the access subtype.
+
+Note that (Ada95) AI-168 deals with a similar case, but makes
+the presumption that even if the partial view lacks discriminants,
+an aliased object is constrained by its initial value, but an
+aliased component might nevertheless have its discriminant changed
+by an assignment to the enclosing object.  We seem to be presuming
+that a direct assignment to the component would raise Constraint_Error,
+even though the private type makes no indication of any discriminants.
+
+So based on the AI-168 writeup, I guess the answer to my
+original question is that the object "X" above is constrained,
+and constraint_error should be raised.  This seems to mean
+that implementing a private type with a type with defaulted
+discriminants is dangerous, if it is going to be used in the
+heap or for an aliased object, since the discriminants
+are going to suddenly become constrained in an annoying way.
+This also probably means that the language-defined private types in various
+RTS packages must not be implemented with full views that have
+defaulted discriminants.   For example, the full view of
+Unbounded_String should not have defaulted discriminants.
+
+Is that right?  It seems like a serious breach of privateness,
+and an undesired pitfall in the language.
+
+Unfortunately, trying to work out the solution is pretty nasty.
+It basically means that aliased variables of a type with a partial view that
+lacks discriminants should *not* be constrained by their initial
+value, including when created by an allocator.  Furthermore, the
+prohibition of access subtypes would need to extend to pool-specific
+access types, since they can point to objects created by allocators
+with changeable discriminants.  That would be a (very minor?) upward
+incompatibility with Ada 83.
+
+Whatever we decide, I think 3.3.1(9) and perhaps elsewhere needs
+to make it clear what happens when the partial view has no
+discriminants, but the full view has defaulted ones.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, October 07, 1999 2:24 PM
+
+At 06:52 PM 10/6/1999 -0400, Tucker Taft wrote:
+>Unfortunately, trying to work out the solution is pretty nasty.
+>It basically means that aliased variables of a type with a partial view that
+>lacks discriminants should *not* be constrained by their initial
+>value, including when created by an allocator.  Furthermore, the
+>prohibition of access subtypes would need to extend to pool-specific
+>access types, since they can point to objects created by allocators
+>with changeable discriminants.  That would be a (very minor?) upward
+>incompatibility with Ada 83.
+
+>Whatever we decide, I think 3.3.1(9) and perhaps elsewhere needs
+>to make it clear what happens when the partial view has no
+>discriminants, but the full view has defaulted ones.
+
+   I think I now understand the issue, and I think the case of pool-specific
+access subtypes is a red herring. The only place such a subtype could be
+specified is where the full type of the designated object is known.  If this
+means that more cases than in Ada 83 have to have "assume the largest"
+semantics so be it.
+
+   To me it is much more important for the implementor of a package to do the
+best he can without worrying about things that may never happen.  In most
+cases of record types with components that depend on a discriminant, the size of
+the objects won't vary that much.  The exceptions are mostly records containing
+strings which should be using bounded or unbounded strings anyway.
+
+   I may not be saying this as well as I could.  I think that the feature of
+being able to export a mutable type as a private abstraction is important.
+Adding this major a restriction to make access subtypes work in pathological
+cases is silly.
+
+****************************************************************
+
+From: Robert A Duff
+Sent: Friday, October 08, 1999 10:02 AM
+
+Tuck says:
+
+> I have been going back and forth in my mind whether
+> an aliased object whose type is private without discriminants,
+> but whose full view has defaulted discriminants, is constrained
+> by its initial value.
+
+I agree with Tucker (ie I'm going back and forth).
+
+On the one hand, clients certainly shouldn't have to trip over
+mysteriously-constrained heap objects.  So the best answer is that these
+things are *not* constrained.
+
+On the other hand, implementers have long depended on the fact that heap
+objects with discrims are always constrained -- is it a big burden to
+change that fact?
+
+I guess I lean toward the user, rather than the implementer -- that is,
+make these things unconstrained, and disallow access subtypes in the
+troublesome cases.  But it's pretty weird to have unconstrained heap
+objects in just this case -- I would be happier if the original
+designers of Ada 83 had allowed unconstrained heap objects.  I remember
+that being a surprise to me, when I first learned Preliminary Ada (or
+was called Green then?) -- coming from a Pascal background, where
+variant records in the heap are just like ones on the stack --
+unconstrained.
+
+Robert Eachus says:
+
+>      I think I now understand the issue, and I think the case of
+> pool-specific access subtypes is a red herring.  The only place such a
+> subtype could be specified is where the full type of the designated
+> object is known.  If this means that more cases than in Ada 83 have to
+> have "assume the largest" semantics so be it.
+
+I don't think this helps.  There could still be places where you can see
+both the access subtype, and the unconstrained object, so that the
+object can change colors out from under you.  If we allow you to create
+an unconstrained heap object, then I think we need to disallow
+constrained access subtypes.
+
+****************************************************************
+
+From: Norman Cohen
+Sent: Friday, October 08, 1999 10:35 AM
+
+Robert Duff writes:
+
+   <<On the other hand, implementers have long depended on the fact that heap
+   objects with discrims are always constrained -- is it a big burden to change
+   that fact?>>
+
+It would certainly not have been a burden to write compilers to support
+unconstrained heap objects in the first place  (provided--see below--that access
+subtypes were also removed from the language).  After all, the compilers could
+implement the usual user workaround:
+
+   type Wrapper is
+      record
+         Value: Discriminated_Type := Initial_Value;
+      end record;
+
+   type Pointer is access Wrapper;
+
+Whether it is a big burden to change existing compilers in this way is, of
+course, a very different question.  I suspect that it would be very difficult to
+find all the places in which compilers have implicitly depended on unconstrained
+heap objects being disallowed.
+
+Bob continues:
+
+   <<I guess I lean toward the user, rather than the implementer -- that is,
+   make these things unconstrained, and disallow access subtypes in the
+   troublesome cases.  But it's pretty weird to have unconstrained heap objects
+   in just this case -- I would be happier if the original designers of Ada 83
+   had allowed unconstrained heap objects.  I remember that being a surprise to
+   me, when I first learned Preliminary Ada (or was called Green then?) --
+   coming from a Pascal background, where variant records in the heap are just
+   like ones on the stack -- unconstrained.>>
+
+The Ada-83 rule was necessary to support access subtypes.  (I think we could
+have done without access subtypes in Ada 83, but once we had them, there was no
+choice about unconstrained heap objects.)  Here is the problem:
+
+      type Pointer is access Discriminated_Type;
+      subtype Constrained_Pointer is access Pointer (Discrim_Value_1);
+   begin
+      Constrained: Constrained_Pointer := new Discriminated_Type(Discrim_Value_1);
+      Unconstrained: Pointer := Constrained;
+      Unconstrained.all := Discriminated_Type'(Discrim_Value_2,...);
+
+Now Constrained designates an object that violates the discriminant constraint
+on the access subtype.
+
+Notice how this problem cannot arise when the user workaraound is used, because
+the designated type of the access type is no longer discriminated, i.e., the
+access type has no nontrivial subtypes.
+
+-- Norman
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, October 08, 1999 11:30 AM
+
+Robert A Duff wrote:
+
+>On the other hand, implementers have long depended on the fact that heap
+>objects with discrims are always constrained -- is it a big burden to
+>change that fact?
+
+   As Norm pointed out, there have always been objects on the heap with
+unconstrained components.  With aliased components in Ada 95, we can now have
+pointers to the heap (not created by allocaters) that designate unconstrained
+components.  Right?  So I see all these problems coming up with assignment to
+objects with aliased components in any case.
+
+>I don't think this helps.  There could still be places where you can see
+>both the access subtype, and the unconstrained object, so that the
+>object can change colors out from under you.  If we allow you to create
+>an unconstrained heap object, then I think we need to disallow
+>constrained access subtypes.
+
+    See above.  For the case we have been discussing, I think we are clean.  The
+problem seems to occur where there are two access values designating the same
+object, but with two different views.  So we may have to bite the bullet and
+eliminate access subtypes, but I think the better fix is to define a check on
+the discriminant that the implementation is allowed to optimize away if it can
+figure how.
+
+                                        Robert I. Eachus
+
+****************************************************************
+
+From: Robert A Duff
+Sent: Friday, October 08, 1999 12:50 PM
+
+>    As Norm pointed out, there have always been objects on the heap with
+> unconstrained components.  With aliased components in Ada 95, we can now
+> have pointers to the heap (not created by allocaters) that designate
+> unconstrained components.  Right?
+
+No, aliased components are constrained by their initial value, for the
+same reason as heap objects -- access subtypes.
+
+- Bob
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, October 08, 1999 2:17 PM
+
+    Is there an AI that changes 3.9.3(9), or there a different rule that covers
+that?
+
+   RM 3.9.3(9):  "A view of an object is defined to be aliased if it is defined
+by an object_declaration or component_definition with the reserved word aliased,
+or by a renaming of an aliased view. In addition, the dereference of an
+access-to-object value denotes an aliased view, as does a view conversion (see
+4.6) of an aliased view. Finally, the current instance of a limited type, and a
+formal parameter or generic formal object of a tagged type are defined to be
+aliased. Aliased views are the ones that can be designated by an access value.
+If the view defined by an object_declaration is aliased, and the type of the
+object has discriminants, then the object is constrained; if its nominal subtype
+is unconstrained, then the object is constrained by its initial value.
+Similarly, if the object created by an allocator has discriminants, the object
+is constrained, either by the designated subtype, or by its initial value."
+
+    The next to the last sentence says that an aliased object defined by is
+constrained, but says nothing about an object defined by a component_definition.
+(See first sentence.)
+
+                                        Robert I. Eachus
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, October 08, 1999 3:18 PM
+
+Robert E. gave the wrong section reference: it is actually 3.10(9). But there
+isn't any AI that changes 3.10(9); the only AIs on section 3.10 are in the
+Corrigendum. The AARM doesn't shed any light, either.
+
+Unless someone else can point out another rule, I agree with Robert E. that
+there is a problem here.
+
+				Randy.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent