CVS difference for ais/ai-00363.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00363.txt

--- ais/ai-00363.txt	2003/11/27 02:01:16	1.2
+++ ais/ai-00363.txt	2004/03/02 00:34:09	1.3
@@ -1,4 +1,4 @@
-!standard  03.07(08/1)                                  03-11-26  AI95-00363/01
+!standard  03.07(08/1)                                  04-02-28  AI95-00363/02
 !class amendment 03-11-26
 !status work item 03-11-26
 !status received 03-11-15
@@ -12,7 +12,40 @@
 
 !problem
 
-[Editor's note: this is not a full write-up.]
+Normally when a discriminated type has defaults, objects of
+the unconstrained subtype allow their discriminants to
+change as part of a whole-object assignment.
+
+Unfortunately, the *possibility* of constrained access subtypes
+means that objects that might be pointed-to by a value of
+such a subtype must be constrained, since the constraint check
+associated with such a subtype is performed only on assignment
+and parameter passing, not on use.
+
+When we added general access types and objects explicitly declared "aliased"
+in Ada 95, we permitted access subtypes on these types as well, and
+generalized what was originally a requirement only on objects created by
+allocators, to apply to all aliased objects, whether declared or
+the result of an allocator, as well as all aliased components.
+
+This has created a stream of headaches, particularly related to
+aliased components, because composite assignments and view
+conversions generally do no per-component constraint checks, so
+extra care needs to be used to prevent the possibility of
+discriminants changing due to operations on the enclosing
+object. See the discussion for details on this stream of headaches...
+
+Another somewhat related problem, which was exacerbated by
+an Ada 95 change, is that if a private type is implemented
+with a full type with defaulted discriminants, then the
+implementation might work great in tests that don't put
+such objects in the heap, but would suddenly start failing
+if a user of the private type decided to allocate objects
+of the type in the heap. This was exacerbated in Ada 95
+because we made it easier for a private type with no
+visible discriminant part to be implemented with a
+discriminant-with-defaults full type. This was possible
+in Ada 83, but required jumping through a few extra hoops.
 
 !proposal
 
@@ -35,14 +68,130 @@
 since subtypes would be disallowed on the "inside" general access types
 as well. Furthermore, there would need to be rules disallowing
 a 'Access that delivers a value of such a type being applied to a
-constrained variable (3.7.2(27)), and disallowing conversion from some other
+constrained variable (3.10.2(27)), and disallowing conversion from some other
 access type that had constrained designated objects (4.6(16)).
-Both 3.7.2(27) and 4.6(16) would then say "discriminated and indefinite"
+Both 3.10.2(27) and 4.6(16) would then say "discriminated and indefinite"
 rather than "discriminated and unconstrained."
 
 !wording
 
+Modify 3.3.1(9):
+
+    ... or the object is constant or [aliased (see 3.10)] {limited} the actual subtype ...
+    [In the case of an aliased object, this initial value may be explicit or
+    implicit; in the other cases, an explicit initial value is required.] ...
+
+Delete 3.6(11).
+
+Replace the second sentence of 3.7.1(7/1) with:
+
+    ... However, in the case of a general access subtype, a discriminant_constraint
+    is illegal if the designated type has defaults for its discriminants. In addition
+    to the places where Legality Rules normally apply (see 12.3), these rules apply
+    also in the private part of an instance of a generic unit. In a generic body,
+    this rule is checked presuming a formal access type of the generic might be a
+    general access type, and a non-tagged discriminated formal type of the generic might
+    have defaults.
+
+NOTE: The change proposed by AI-275 to 12.5.3(8) is no longer justified
+based on concerns about constrained access subtypes. However, the change
+might still be justified if we are concerned about an array with aliased
+components being "viewed" as an array without aliased components, or vice-versa.
+In the presence of optimization, this could be a legitimate concern, so AI-275
+should be reevaluated in the light of that concern, rather than access subtype
+concerns. If AI-275 is dropped, then perhaps the changes associated with
+AI-168 (which are already in RM2000) should be "backed out."
+
+Drop AI-295 -- it was strictly related to access subtype concerns.
+
+In 3.10(9), delete the last two sentences (starting with
+"If the view defined by an object_declaration is aliased...").
+
+Modify 3.10.2(26):
+
+    ... unless this subtype is indefinite, or the variable is [aliased]
+    {constrained by its initial value}.
+
+Modify 3.10.2(27):
+    ... if D is untagged, then the type of the view shall be D, and A's
+    designated subtype shall either statically match the nominal subtype of
+    the view or be discriminated and [unconstrained] {indefinite};
+
+Modify 4.6(16):
+    ... or the target designated subtype shall be discriminated and
+    [unconstrained] {indefinite}; and
+
+Modify 4.8(6):
+
+    If the designated type of the allocator is elementary, then the subtype
+    of the created object is the designated subtype. If the designated type
+    is composite, then the created object is [always constrained;]
+    {unconstrained if and only if:
+
+       * the access type is an access-to-variable type; and
+       * the full view of the designated subtype is nonlimited and unconstrained; and
+       * there is a partial view of the designated subtype that is constrained.
+
+    Otherwise, the created object is constrained;} if the {full view of the}
+    designated subtype is constrained, then it provides the constraint;
+    otherwise the object is constrained by its initial value
+    (even if the designated subtype is unconstrained with defaults).
+
 !discussion
+
+Allowing constrained access subtypes of general access types has created
+a stream of headaches, related to aliased components having their
+discriminants changed.
+
+This issue led to 3.6(11) which requires aliased components
+of non-limited types to be constrained. However, if the type
+is private and its discriminants are only visible in the private part,
+then 3.6(11) provides no protection, so 3.7.1(7) was created to
+disallow general access subtypes of types whose partial view
+lacks discriminants, while the full view has defaulted discriminants.
+
+Furthermore, view conversions of limited array types could
+create a problem, if the target and source type differed
+in whether the components were aliased, since in one view
+the discriminants were mutable, and in the other they weren't.
+This led to AI-168 and changes to 4.6(12).
+
+Generic formal (limited) array types create similar problems,
+if the actual and formal differ on component aliasing, for essentially
+the same reason. 12.5.3(8) worries about the case in one direction,
+and AI-275 was created to worry about the case in the other direction.
+
+It was also noticed that 3.6(11) does not provide protection for
+generic formal private types, since the actual might have
+defaulted discriminants, so AI-295 was created to deal with this
+situation, essentially requiring 3.6(11) to be enforced in the
+private part of the instance, and enforced in the body of the
+instance by a (pseudo) run-time check.
+
+The second problem addressed by this AI is the fact that a private
+type with no visible discriminants can be completed by a type
+with defaulted discriminants. Objects of such a type become
+constrained when allocated in the heap or declared as aliased.
+
+I know about this problem because a few years ago it hit
+some of our customers, because we had implemented Unbounded_Strings
+with a variant record, one variant for "short" strings, and
+one variant for longer strings. It is easy enough to solve
+by wrapping the full type in a record, but it seems a clear
+violation of the "spirit" of privateness, namely that objects
+of a private type with no visible discriminants should suddenly
+behave differently when clients of the type happen to allocate
+them in the heap.
+
+It seems clear that fixing this problem would require allowing
+unconstrained heap objects to be created, at least when using
+an access type declared outside the scope of the full type,
+and disallowing access subtypes of such an access type, even
+if the type is pool-specific. Of course these access subtypes
+would be a bit weird, since they would have to be declared
+somewhere within the scope of the full type to be able to
+see the discriminants, even though the main access type were
+declared outside the scope of the full type.
 
 !example
 

Questions? Ask the ACAA Technical Agent