CVS difference for ais/ai-00373.txt

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

--- ais/ai-00373.txt	2004/02/06 05:01:50	1.1
+++ ais/ai-00373.txt	2004/06/08 00:44:48	1.2
@@ -1,4 +1,4 @@
-!standard 03.03.01(20)                                 04-02-05  AI95-00373/00
+!standard 03.03.01(20)                                 04-06-07  AI95-00373/01
 !class binding interpretation 04-02-05
 !status received 04-01-17
 !priority Low
@@ -13,12 +13,149 @@
 
 !wording
 
-!discussion
+Replace 3.3.1(18/1 - 20) with
 
---!corrigendum
+  3. The object is created, and, if there is not an initialization expression,
+  any per-object expressions (see 3.8) are elaborated and any implicit initial
+  values for the object or for its subcomponents are obtained as determined by
+  the nominal subtype. Any initial values (whether explicit or implicit) are
+  assigned to the object or to the corresponding subcomponents. As described
+  in 5.2 and 7.6, Initialize and Adjust procedures can be called.
+
+  For the third step above, evaluations and assignments are
+  performed in an arbitrary order subject to the following restrictions:
+      - Assignment to any part of the object is preceded
+        by the evaluation of the value that is to be assigned.
+      - The evaluation of a default_expression that includes the name of
+        a discriminant is preceded by the assigment to that discriminant.
+      - The evaluation of the default_expression for any component that
+        depends on a discriminant is preceded by the assignment to that
+        discriminant.
+
+  Furthermore, a component of an object is said to *require late initialization*
+  if it has an access discriminant value constrained by a per-object
+  expression, or if it has an initialization expression which includes a name
+  denoting the current instance of the type or denoting an access discriminant.
+  The assignments of the fourth step for any components not requiring late
+  initialization must precede the evaluations of the third step for any
+  components requiring late initialization.
+  If two components both require late initialization, then
+  the assignment of the fourth step for the component occurring earlier
+  in the order of the component declarations must precede the evaluation of
+  the third step for the component occurring later.
 
 !example
 
+  procedure Test is
+    type Inner;
+    type Outer;
+
+    function Flag_Init (X : access Inner) return Boolean;
+
+    type Inner (Discrim : access Outer) is limited
+	record
+	    Flag : Boolean := Flag_Init (Inner'Access);
+	end record;
+
+    type Type_With_Lots_Of_Interesting_Components is
+       -- contains tasks, discriminants, access values, protected records,
+       -- controlled types, or whatever gives you heartburn
+       ... ;
+
+    type Outer is limited
+	record
+	    F1 : Inner (Outer'Access);
+	    F2 : Type_With_Lots_Of_Interesting_Components;
+	    F3 : Inner (Outer'Access);
+	end record;
+
+    procedure Do_All_Sorts_Of_Things
+		 (Interesting : in out
+		     Type_With_Lots_Of_Interesting_Components) is separate;
+    --
+    -- abort task components, dereference access values, etc.
+
+    function Flag_Init (X : access Inner) return Boolean is
+    begin
+	Do_All_Sorts_Of_Things (X.Discrim.all.F2);
+	return True;
+    end Flag_Init;
+
+    Problematic : Outer;
+    --
+    -- If F2 field is not initialized ahead of both the F1 and F3 fields,
+    -- then Do_All_Sorts_Of_Things will be invoked on a record containing
+    -- uninitialized tasks, discriminants, access values, etc.
+
+    procedure Do_Something is separate;
+  begin
+    Do_Something;
+  end Test;
+
+!discussion
+
+An implementation is currently given too much freedom in choosing the order in
+which components are initialized.
+The problem is illustrated by the preceding example (see also Bob Duff's
+initial description of the problem).
+
+This proposal does not completely solve the problem of evaluating uninitialized
+components (e.g. discriminants, access values, tasks, etc), but it greatly
+reduces the chances of inadvertantly introducing such a problem, either by
+writing new Ada source or by compiling exisiting source with another compiler.
+
+If a type has two components which both "require late initialization", then
+one of them is going to be initialized first and problems may arise if
+this initialization involves evaluation of the second component (or any part
+thereof). Portability is improved by nailing down the order in which such
+components are initialized.
+
+Technical notes:
+
+1) A discriminant never requires late initialization because RM 8.3(17) implies
+   that the current instance of a type cannot be named in the discriminant
+   part of the type.
+
+2) The reference to "the order of the component declarations" is intended to
+   echo 7.6(12).
+
+3) Given this example
+    type T (D : Some_Discrete_Type) is
+      limited record
+        F1 : T1 (T'Access);
+        F2 : T2 (D) ;
+        F3 : T3 := F (D);
+      end record;
+   , F2 and F3 do not "require late initialization".
+   We want F1 initialized last in this case. Evaluation of a scalar
+   discriminant does not cause a component to "require late initialization".
+
+4) Given this example
+    type Tt (Dd : Some_Type := Some_Value) is
+      record
+        Ff : Some_Type := Dd;
+      end record;
+   , the current wording of  3.3.1(20) allows the following (bad) order:
+       a) Evaluate the initial value of the Dd component.
+       b) Evaluate the initial value of the Ff component.
+       c) Assign the value computed in step #1 to the Dd component.
+       d) Assign the value computed in step #2 to the Ff component.
+   The problem is that step b involves the evaluation of a component which
+   is not initialized until step c. No reasonable implementation would
+   choose this order, but the language definition shouldn't rely on that.
+
+5) The former steps #3 and #4 (i.e. 3.3.1(18/1 and 19)) are now merged into
+   one step. It did not make sense to leave them as separate steps
+   because 3.3.1(15) explicitly states that the steps are to be performed
+   sequentially.
+
+6) Should it be stated explicitly that the evaluation-before-initialization
+   cases that this proposal does not prevent (i.e. cases involving two or more
+   components which require late finalization) result in erroneous execution?
+   Would an AARM note be appropriate?
+
+--!corrigendum
+
 !ACATS test
 
 !appendix
@@ -194,5 +331,21 @@
 seem reasonable to add rules requiring components initialized by
 these special expressions to delay evaluation until earlier components
 that don't involve per-object expressions have all been initialized.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 7, 2004  7:40 PM
+
+The AI doesn't contain a summary, question, or recommendation.
+Recommendation can be "(See summary.)", but the other two are required.
+[Editor's note: this is about version /01 of the AI.]
+
+The last paragraph of the new wording refers to the "fourth step", but there
+is no fourth step anymore.
+
+I think that Note 6 needs to be stated somewhere, at least in the AARM. But
+it really is something users ought to know, so explicit mention in the
+Standard would be a good idea.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent