CVS difference for ai05s/ai05-0041-1.txt

Differences between 1.4 and version 1.5
Log of other versions for file ai05s/ai05-0041-1.txt

--- ai05s/ai05-0041-1.txt	2008/02/05 06:29:01	1.4
+++ ai05s/ai05-0041-1.txt	2008/02/06 01:44:29	1.5
@@ -1,4 +1,7 @@
-!standard 3.7.1(7/2)                                          08-02-04    AI05-0041-1/04
+!standard 3.7.1(7/2)                                          08-02-05    AI05-0041-1/05
+!standard 3.3(27.9/3)
+!standard 3.3(27.10/3)
+!standard 3.10.2(27.2/2)
 !standard 4.8(6/2)
 !class binding interpretation 07-03-27
 !status work item 07-03-27
@@ -12,9 +15,12 @@
 For the purposes of the rules for allowing allocated unconstrained objects, any
 ancestor that has a constrained partial view causes the rules to apply.
 
+In a generic body, 3.10.2(27.2/2) is checked assuming that any untagged formal private
+or derived type has a constrained partial view.
+
 !question
 
-It seems that the meaning of "partial view" in 3.7.1(7/2) is either
+(1) It seems that the meaning of "partial view" in 3.7.1(7/2) is either
 obscure or too narrow. The ACATS 2.6 test contains an subtest like the following,
 for which the legality is not obvious.
 
@@ -57,6 +63,60 @@
 
 Similar examples can be created using nested packages rather than child packages.
 
+(2) There seems to be a contract-model problem with 3.10.2(27.2/2)
+in the case of a generic formal discriminated type as seen from 
+within the generic body.
+
+Consider this example:
+
+  procedure Foo  is
+    subtype Index is Integer range 0 .. 255;
+    Smaller_Index : constant Index := 10;
+    Larger_Index  : constant Index := 20;
+
+    generic
+        type T1 (D : Index) is private;
+    package G is
+        type Ref is access all T1;
+        Smaller : aliased T1 (Smaller_Index);
+        Ptr     : Ref;
+    end G;
+
+    package body G is
+    begin
+        Ptr := Smaller'Access; -- Legal? (No.)
+    end G;
+
+    package Pkg is
+        type T2 is private;
+    private
+        type T2 (D : Index := 100) is
+            record
+                F : String (1 .. D);
+            end record;
+
+       package I is new G (T2);
+    end Pkg;
+
+    package body Pkg is
+        Larger : T2 (Larger_Index);
+    begin
+        I.Ptr.all := Larger;
+    end Pkg;
+
+  begin
+    ...;
+  end Foo;
+
+3.10.2(27.2/2) is satisfied at the line marked "Legal?", because
+T1 does not have a partial view. This allows assigning a jumbo value
+to a not-so-jumbo object; this is not good.
+
+An assume-the-worst rule seems to be needed. For purposes of checking
+3.10.2(27.2/2) within a generic body, it should be assumed that any 
+untagged formal discriminated type of the generic has a constrained
+partial view.
+
 !recommendation
 
 (See Summary.)
@@ -69,32 +129,37 @@
     no {ancestor of its type that has a constrained} partial view [of its
     type that is constrained].
 
-Change the new text for 3.3(23.10/3) from AI05-0008-1 as follows:
+Replace the new text for 3.3(23.10/3) from AI05-0008-1 with the following:
 
   For the purposes of determining within a generic body whether an
   object is known to be constrained:
 
      * if a subtype is a descendant of an untagged generic formal
-       derived type, it is not considered indefinite and is considered to
+       derived type, and the subtype is not an unconstrained array
+       subtype, it is not considered indefinite and is considered to
        have a constrained partial view;
 
      * if a subtype is a descendant of a formal access type, it is not
        considered pool-specific.
 
 Change 3.7.1(7/2) as follows:
+
+   ... However, in the case of an access subtype, a discriminant_
+   constraint is {legal only if any dereference of a value of the access
+   type is known to be constrained (see 3.3).} [... rest of paragraph
+   deleted ...]
 
-   ... However, in the case of an access subtype, a
-   discriminant_constraint is illegal if the designated type has {an
-   ancestor that has} a {constrained} partial view [that is constrained]
-   or, for a general access subtype, has default_expressions 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 all formal access types of the generic might be
-   general access types, {all untagged generic formal derived types have
-   constrained partial views,} and all untagged discriminated formal
-   types of the generic might have default_expressions for their
-   discriminants.
+Change 3.10.2(27.2/2) as follows:
+ 
+   
+ * D shall be discriminated in its full view and unconstrained in any 
+   partial view, and the designated subtype of A shall be unconstrained.
+   {For the purposes of determining within a generic body whether D is
+   unconstrained in any partial view, a discriminated subtype is is
+   considered to have a constrained partial view if it is a descendant
+   of an untagged generic formal private or derived type. In addition to
+   the places where Legality Rules normally apply (see 12.3), this rule
+   applies also in the private part of an instance of a generic unit.}
 
 Change 4.8(6/2) as follows:
 
@@ -166,15 +231,52 @@
 we need to tweak the "known to be constrained" rules so that they take into account
 these changes, so that renames of discriminant-dependent components of potentially
 unconstrained objects are illegal.
+
+Presuming we have gotten the "known to be constrained" rules right, we now try
+to use the term "known to be constrained" wherever appropriate, rather than repeating
+rules about having constrained partial views, etc. (e.g. in 3.7.1(7/2)).
+
+Note that we have incorporated the former AI-61, by providing updated wording
+for 3.10.2(27.2/2). We had hoped to use the "known to be constrained"
+wording here as well, as in the following:
+
+   D shall be a discriminated type, the designated subtype of A
+   shall be unconstrained, and any dereference of a value of type
+   A is known to be constrained (see 3.3).
+   
+However, that is more restrictive, since it disallows taking 'Access of
+a constrained object whenever the type has defaults for its discriminants,
+even when there are no constrained partial views. "Known to be constrained"
+is not the same as "not known to be unconstrained." There is a grey area
+in the middle where we don't know whether or not it is constrained, and
+depending on particular circumstances, we choose one or the other. For
+example, for the purposes of checking constraints on assignment,
+we presume the dereference of a general access value is constrained,
+even when it might designate an unconstrained object through use of
+'Access. For the purposes of renaming a discriminant-dependent component, 
+we presume the enclosing object is unconstrained unless we know
+it is constrained.
+
+It might be worth defining "known to be unconstrained" so we can centralize
+the definition of the "assume the worst" rule for generics.  If we had
+that, then 3.10.2(27.2/2) could become:
+
+   D shall be a discriminated type, the designated subtype of A
+   shall be unconstrained, and any dereference of a value of type
+   A is not known to be unconstrained (see 3.3).
+   
+A bit of a double negative, unfortunately.
 
---!corrigendum 10.1.2(20/2)
+--!corrigendum 3.10.2(27.2/2)
 
 
 
 !ACATS test
+
+The test case in the first question should be replaced in the ACATS 3.0 test B371001
+(it has been removed until this AI is resolved).
 
-The test case in the question should be replaced in the ACATS 3.0 test B371001 (it has been
-removed until this AI is resolved).
+Add an ACATS B-Test like the example in the second question.
 
 !appendix
 
@@ -414,6 +516,165 @@
 
 ****************************************************************
 
+From: Steven W Baird
+Sent: Thursday, June 21, 2007  5:10 PM
+
+There seems to be a contract-model problem with 3.10.2(27.2/2)
+in the case of a generic formal discriminated type as seen from 
+within the generic body.
+
+This problem allows the construction of an access value which
+designates an unconstrained view of a constrained object.
+
+This in turn allows, among other things, assigning a jumbo value
+to a not-so-jumbo object; things go downhill rapidly from there.
+
+Consider this example:
+
+  procedure Foo  is
+    subtype Index is Integer range 0 .. 255;
+    Smaller_Index : constant Index := 10;
+    Larger_Index  : constant Index := 20;
+
+    generic
+        type T1 (D : Index) is private;
+    package G is
+        type Ref is access all T1;
+        Smaller : aliased T1 (Smaller_Index);
+        Ptr     : Ref;
+    end G;
+
+    package body G is
+    begin
+        Ptr := Smaller'Access;
+    end G;
+
+    package Pkg is
+        type T2 is private;
+    private
+        type T2 (D : Index := 100) is
+            record
+                F : String (1 .. D);
+            end record;
+
+       package I is new G (T2);
+    end Pkg;
+
+    package body Pkg is
+        Larger : T2 (Larger_Index);
+    begin
+        I.Ptr.all := Larger;
+    end Pkg;
+
+  begin
+    ...;
+  end Foo;
+
+An assume-the-worst rule seems to be needed. For purposes of checking
+3.10.2(27.2/2) within a generic body, it should be assumed that any 
+untagged
+formal discriminated type of the generic has a constrained partial view.
+
+This would cause the preceding example to be rejected.
+
+If this compile-time check is viewed as being too conservative, the 
+problem
+could also be solved via a new runtime check (or even a post-compilation
+check). The compile-time solution seems preferable.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, June 21, 2007  6:08 PM
+
+Alternatively, we could say that objects designated by values
+of type "Ref" are constrained by their initial value.  But
+if we do that, we will also have to disallow converting values of
+type Ref to access types that designate objects that are *not*
+constrained by their initial value.  Your solution is probably
+cleaner, and avoids the question of what to do if you had
+a formal access type declared similarly to Ref.
+
+I would presume that the implementer of the generic could
+move Smaller'Access into the spec, and then get instantiation-time
+checking rather than having the generic body rejected.
+
+I think this means we need the usual blather that
+states that 3.10.2(27.2) is checked in the private
+part of an instance, plus something like:
+
+     For the purposes of this check in a generic body,
+     an untagged formal private type is presumed to
+     have a constrained partial view.
+
+I don't think we want to restrict ourselves to
+"discriminated" formals, since "(<>)" indicates
+the formal is indefinite without making it
+"discriminated."  But perhaps it is irrelevant
+since you can't create a non-matching subtype
+in that case.
+
+****************************************************************
+
+From: Steven W Baird
+Sent: Friday, June 22, 2007  2:50 PM
+
+This sounds good except for one detail: the rule
+should not be restricted to formal private types.
+Formal derived types need to be included as well
+because the "has a constrained partial view" property
+is not preserved by derivation.
+
+Consider the following variation on the original example:
+
+  procedure Foo2 is
+    subtype Index is Integer range 0 .. 255;
+    Smaller_Index : constant Index := 10;
+    Larger_Index  : constant Index := 20;
+
+    type Has_No_Constrained_Partial_View (D : Index := 100) is
+        record
+            F : String (1 .. D);
+        end record;
+
+    generic
+        type T1 is new Has_No_Constrained_Partial_View;
+    package G is
+        type Ref is access all T1;
+        Smaller : aliased T1 (Smaller_Index);
+        Ptr     : Ref;
+    end G;
+
+    package body G is
+    begin
+        Ptr := Smaller'Access;
+    end G;
+
+    package Pkg is
+        type Has_A_Constrained_Partial_View is private;
+    private
+        type Has_A_Constrained_Partial_View is
+           new Has_No_Constrained_Partial_View;
+
+        package I is new G (Has_A_Constrained_Partial_View);
+    end Pkg;
+
+    package body Pkg is
+        Larger : Has_A_Constrained_Partial_View (Larger_Index);
+    begin
+        I.Ptr.all := Larger;
+    end Pkg;
+  begin
+    ...;
+  end Foo2;
+
+I'd certainly agree that this is, to quote Randy's recent
+description, "another Baird anomaly that no one in their
+right mind would ever try to use", but we should still
+get the definition right.
+
+****************************************************************
+
 From: Stephen W. Baird [private thread]
 Date: Monday, July 16, 2007  2:36 PM
 
@@ -901,5 +1162,66 @@
 types from *all* of the rules about constrained partial views. Not just
 for generic formal types. Maybe that isn't possible for regular tagged
 types, but it would be helpful to have some proof of that.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Tuesday, February 5, 2008  12:48 AM
+
+> Here is the last AI I'll be submitting before the meeting.
+
+I see you were supposed to combine AI-61 into AI-41. So neither of them are
+really done. Sigh.
+
+****************************************************************
+
+From: Tucker Taft
+Date: Tuesday, February 5, 2008  2:25 PM
+
+I have attached a version 5 of AI-41 that incorporates AI-61,
+in case we still want to tackle it at the meeting.  And
+yes I know this is after the deadline...
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Tuesday, February 5, 2008  7:35 PM
+
+A couple of technical comments:
+
+Humm. "Known to be constrained" is just a definition; it does not include
+the Legality Rules boilerplate (about being enforced in the private part).
+Thus, you shouldn't delete that from 3.7.1(7/2) (the other wording can go,
+of course). The same is true for the radical proposal for 3.10.2(27.2/2) -
+it would still be necessary there (but see below).
+
+In my original writeup of AI-61, I had the following editor's note about the
+boilerplate:
+
+[Editor's note: 3.10.2(28/2) already includes the boilerplate about the
+private part. I have to wonder if it would be better to have this apply to
+*all* of the requirements on 'Access. (Do we really want any of these unchecked
+in private parts? For instance, we appear to allow an access-to-variable type
+to point at a constant in a private part.) If we make this change, we should
+delete the last line of 3.10.2(28/2) and insert the following before 3.10.2(29):
+   In addition to the places where Legality Rules normally apply (see 12.3), these
+   requirements apply also in the private part of an instance of a generic unit.
+end Editor's note.]
+
+In particular, we'll have added the boilerplate to 3.10.2(26) [by
+AI05-0008], to 3.10.2(27) [by AI05-0041], and it has always applied to
+3.10.2(28). But it doesn't seem to apply to 3.10.2(25), and it seems like it
+should.
+
+If that's the case, it seems bizarre to give the same sentence in four
+consecutive bullets; it would be better to factor it out (perhaps even give
+it it's own bullet). Something like:
+
+* In addition to the places where Legality Rules normally apply (see 12.3),
+these four requirements apply also in the private part of an instance of a
+generic unit.
+
+and then take it out of 3.10.2(26), 3.10.2(27.2), and 3.10.2(28).
+["requirements" echos the lead-in in 3.10.2(24)]
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent