CVS difference for ais/ai-00184.txt

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

--- ais/ai-00184.txt	1998/09/30 00:17:34	1.1
+++ ais/ai-00184.txt	1998/10/01 00:12:33	1.2
@@ -1,26 +1,134 @@
-!standard 04.06    (54)                               97-03-19  AI95-00184/01
+!standard 04.06    (54)                               97-03-29  AI95-00184/02
 !class binding interpretation 97-03-19
 !status work item 97-03-19
 !status received 97-03-19
 !priority High
 !difficulty Hard
-!subject View conversion to an indefinite subtype
+!subject Definiteness and type derivation
 
-!summary 97-03-19
+!summary 98-03-29
 
+It is illegal to rename a component that depends on a discriminant of
+a variable whose nominal subtype is an indefinite generic formal type
+(or a descendant of such a type).
+
+A view conversion cannot be used to obtain a indefinite view of an
+object whose nominal subtype is definite.
+
+!question 98-03-29
+
+The definiteness of a type is not preserved by type derivation.  A type with
+defaulted discriminants may be derived from a type without defaulted
+discriminants and vice-versa.
+
+This makes it possible to rename a component of a record that later
+disappears
+due to an assignment to the enclosing object, as shown in the following
+examples:
+
+1 - An example where the parent type is indefinite and the derived type is
+definite:
+
+ type T1 (D1 : Boolean) is
+    record
+       case D1 is
+          when False =>
+             C1 : Integer;
+          when True =>
+             C2 : Float;
+          end case;
+       end record;
+
+ generic
+    type F is new T1;
+    X : in out F;
+ package G is
+    C1_Ren : Integer renames X.C1;
+ end G;
+
+ type T2 (D2 : Boolean := True) is new T1 (D1 => D2);
+
+ Y : T2;
+
+ package I is new G (T2, Y);
+
+ Y := (D1 => True, C2 => 3.0); -- Oops!  What happened to I.C1_Ren
+
+The declaration of C1_Ren in the generic G is legal as per RM95 8.5.1(5),
+because the formal type F is indefinite.  But when G is instantiated with
+type
+T2, the actual type is definite, so now we have renamed a component that may
+disappear by assignment to the variable Y.  Note that the declaration of
+C1_Ren might be in the body of G, so we cannot avoid this problem by
+rechecking RM95 8.5.1(5) on the instantiation.
 
-!question 97-03-19
+2 - An example where the parent type is definite and the derived type is
+indefinite:
 
+      type Definite_Parent (D1 : Integer := 6) is
+         record
+            F : String (1 .. D1);
+         end record;
 
-!recommendation 97-03-19
+      type Indefinite_Child (D2 : Integer) is new Definite_Parent (D1 =>
+D2);
 
+      Y : Definite_Parent;
 
-!wording 97-03-19
+      procedure P (X : in out Indefinite_Child) is
+         C : Character renames X.F (3);
+      begin
+         X := (0, "");
+         -- X.F (3) has disappeared!
+      end;
+   begin
+      P (Indefinite_Child (Y));
 
+Assume that the implementation chooses to pass X by reference.  Then,
+6.4.1(10) says that there is an implicit view conversion to
+Indefinite_Child,
+and the formal parameter X then denotes the result of this view conversion.
+ The result of the explicit view conversion is unconstrained, and the result
+of the implicit view conversion is also unconstrained, hence X is
+unconstrained, which violates the language design principle of NOTE 3.7(28).
 
-!discussion 97-03-19
+One of the unpleasant consequences of this violation is that the assignment
+to
+X doesn't raise an exception, and after the execution of this assignment C
+denotes a non-existent component.
+
+Note that if the implementation chooses to pass by copy, then there is an
+implicit value conversion -- see 6.4.1(11-11.a).  So in that case, there's
+no
+problem.
+
+!recommendation 98-03-29
+
+(See wording.)
+
+!wording 98-03-29
+
+Change RM95 8.5.1(5) to read: "The renamed entity shall not be a
+subcomponent that depends on a discriminant of a variable whose nominal
+subtype is unconstrained, unless this subtype is indefinite and not
+a descendant of a generic formal type, or the variable is aliased."
+
+Add to RM95 4.6(24): "Furthermore, the target type shall be definite if
+the operand type is."
+
+!discussion 98-03-29
 
+We seem to have two options to fix the above problems:
 
+1 - Decide that definiteness cannot be changed by type derivation.
+Obviously
+this gets rid of the problems, but it is a big change and there may be user
+code out there that depends on this capability.
+
+2 - Try to plug individual holes and hope that there aren't too many of
+them.
+That's what was done in the !wording section.
+
 !appendix 97-03-19
 
 !section 4.6(54)
@@ -73,3 +181,76 @@
 
 
 ****************************************************************
+
+!topic Definiteness and type derivation
+!reference RM95 3.4
+!reference AI95-00184
+!from Pascal Leroy 97-10-14
+<<reference as: 1998-15825.c Pascal Leroy 1998-3-17>>
+!discussion
+
+The definiteness of a type is not preserved by type derivation.  A type with
+defaulted discriminants may be derived from a type without defaulted
+discriminants and vice-versa.
+
+This has a number of pathological consequences, as shown by the examples
+below.  Note that although these examples all have generics, the problems do
+not stem from generics: AI95-00184 has an example without generics.
+
+1 - A renamed subcomponent may disappear:
+
+ type T1 (D1 : Boolean) is
+    record
+       case D1 is
+          when False =>
+             C1 : Integer;
+          when True =>
+             C2 : Float;
+          end case;
+       end record;
+
+ generic
+    type F is new T1;
+    X : in out F;
+ package G is
+    C1_Ren : Integer renames X.C1;
+ end G;
+
+ type T2 (D2 : Boolean := True) is new T1 (D1 => D2);
+
+ Y : T2;
+
+ package I is new G (T2, Y);
+
+The declaration of C1_Ren in the generic G is legal as per RM95 8.5.1(5),
+because the formal type F is indefinite.  But when G is instantiated with
+type
+T2, the actual type is definite, so now we have renamed a component that may
+disappear by assignment to the variable Y.  Note that the declaration of
+C1_Ren might be in the body of G, so we cannot avoid this problem by
+rechecking RM95 8.5.1(5) on the instantiation.
+
+2 - It is possible to create an unconstrained object of an indefinite
+subtype:
+
+ type T1 (D1 : Boolean := True) is ...;
+ type T2 (D2 : Boolean) is new T1 (D1 => D2);
+
+ generic
+    type F is new T1;
+ package G is
+    X : F;
+ end G;
+
+ package I is new G (T2);
+
+The declaration of X in the generic G is legal because F has defaulted
+discriminants.  But when G is instantiated with T2, discriminants don't have
+defaults, so we have created an object I.X without specifying a value for
+its
+discriminants.  Again, the offending construct could be in the body of the
+generic, so it cannot be detected by rechecking the instantiation.
+
+****************************************************************
+
+

Questions? Ask the ACAA Technical Agent