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

Differences between 1.1 and version 1.2
Log of other versions for file ai05s/ai05-0027-1.txt

--- ai05s/ai05-0027-1.txt	2006/11/14 01:19:19	1.1
+++ ai05s/ai05-0027-1.txt	2006/12/16 03:13:19	1.2
@@ -1,4 +1,4 @@
-!standard A.18.2(238/2)                                   06-11-13    AI05-0027-1/01
+!standard A.18.2(238/2)                                   06-12-13    AI05-0027-1/02
 !class binding interpretation 06-11-13
 !status work item 06-11-13
 !status received 06-11-03
@@ -23,6 +23,49 @@
 
 !discussion
 
+!example
+
+Access to a finalized container can happen if a Finalize routine accesses
+a container object declared in the same master as the Finalize routine.
+This is more likely than it appears at first glance.
+
+Imagine for a moment that someone needs to instrument a controlled type to
+collect some usage information. The program might be structured like:
+
+    package Pack is
+        type T is new Ada.Finalization.Controlled with ...
+        overriding
+        procedure Finalize (Object : in out T);
+
+        type Acc_T is access all T'Class;
+        A_List : Acc_T;
+    end Pack;
+
+    package body Pack is
+        package Usage_History is new Ada.Containers.Vectors (...);
+        Finalzation_Usage: Usage_History.Vector;
+
+        procedure Finalize (Object : in out T) is
+        begin
+            -- operations on Finalization_Usage to collect data on the
+            -- finalization of objects of T.
+        end Finalize;
+    end Pack;
+
+When the program finalizes, any allocated objects remaining on A_List will be
+finalized when the finalization of the collection for type Acc_T is occurs. However,
+since finalization occurs in reverse order of declaration, the object
+Finalization_Usage will be finalized before the collection for Acc_T. So those
+finalizations will be accessing an object that is already finalized.
+
+Note that it doesn't matter where A_List is declared; it only matters where
+the access type is declared relative to the collection object. It's not unusual
+for that type to be declared visibly (this program structure is taken from the
+CLAW Windows interface library), and good Ada practice is to hide things in the
+body when possible. But doing so can easily cause finalization anomolies (see
+AI95-00280 for some examples).
+
+
 --!corrigendum A.18.2(239/2)
 
 
@@ -356,6 +399,75 @@
 also the case of someone calling Unchecked_Deallocation on a container, 
 or more realistically on an object that contains a container.  But I 
 think if that happens outside the container package bodies, anything goes.)
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Thursday, December 14, 2006  12:31 AM
+
+Ages ago, Matt Heaney wrote:
+
+> I am curious, though, about what motivated Pascal's suggestion: under what
+> circumstances would someone be able to refer to an object that has been
+> finalized?  If finalization happens immediately prior to the object being
+> destroyed, then how can someone refer to the object at all?
+
+I was working on the minutes for that AI that came out of this discussion,
+and I remembered that I wasn't convinced that it could actually happen for a
+container object (because you can't control what happens inside the
+container). So I spent a bit of time trying to figure out how it could
+happen. It turns out to be more likely than you might expect.
+
+Access to a finalized container can happen if a Finalize routine accesses a
+container object declared in the same master as the Finalize routine. How
+could that happen in real code?
+
+Imagine for a moment that someone needs to instrument a controlled type to
+collect some usage information. The program might be structured like:
+
+    package Pack is
+        type T is new Ada.Finalization.Controlled with ...
+        overriding
+        procedure Finalize (Object : in out T);
+
+        type Acc_T is access all T'Class;
+        A_List : Acc_T;
+    end Pack;
+
+    package body Pack is
+        package Usage_History is new Ada.Containers.Vectors (...);
+        Finalzation_Usage: Usage_History.Vector;
+
+        procedure Finalize (Object : in out T) is
+        begin
+            -- operations on Finalization_Usage to collect data on the
+            -- finalization of objects of T.
+        end Finalize;
+    end Pack;
+
+When the program finalizes, any allocated objects remaining on A_List will
+be finalized when the finalization of the collection for type Acc_T is
+occurs. However, since finalization occurs in reverse order of declaration,
+the object Finalization_Usage will be finalized before the collection for
+Acc_T. So those finalizations will be accessing an object that is already
+finalized. ["Finalization of the collection" for an access type is defined
+in 7.6.1(11/2).]
+
+Note that it doesn't matter where A_List is declared; it only matters where
+the access type is declared relative to the collection object. It's not
+unusual for that type to be declared visibly (this program structure is
+taken from the CLAW Windows interface library), and good Ada practice is to
+hide things in the body when possible. But doing so can easily cause
+finalization anomolies (some of the cases in AI95-00280 were originally
+encountered in CLAW).
+
+This argues strongly for at *least* the resolution decided on by the ARG in
+ABQ: Program_Error for tampering operations, bounded error (Program_Error or
+acts as empty) for operations that just read from the container.
+
+I've added this example to the otherwise empty AI, so that Tucker doesn't
+have to remember to add it when he writes it up 90 minutes before the next
+ARG meeting starts. ;-)
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent