Version 1.1 of acs/ac-00209.txt

Unformatted version of acs/ac-00209.txt version 1.1
Other versions for file acs/ac-00209.txt

!standard 7.6.1(11/2)          11-01-28 AC95-00209/01
!class confirmation 11-01-28
!status received no action 11-01-28
!status received 10-10-14
!subject Storage pool pathology (not!)
!summary
!appendix

From: Randy Brukardt
Sent: Thursday, October 14, 2010  11:51 PM

Consider the finalization of the following code (all in a single declaration
list):

     type Acc is access Some_Controlled_Type;

     Acc_Pool : Some_Storage_Pool;

     for Acc'Storage_Pool use Acc_Pool;

[The declaration of Acc_Pool freezes the type Some_Storage_Pool, but not the
unrelated type Acc. So I think specifying the pool is OK. Or did I miss
something?]

Declarations finalize in the reverse order of their elaboration. Thus Acc_Pool
will finalize before Acc.

The collection of objects in Acc will be allocated in Acc_Pool, and in many
implementations, linked through that storage.

If Acc_Pool frees any storage it has allocated (a reasonable thing to do) when
it is finalized, finalization of the collection of Acc will be walking around in
deallocated memory. This does not sound like a recipe for success. :-) [I know
that some pools will allocate stack-based memory and there won't be a problem,
but this still seems weird.]

If my analysis here is correct, we need some sort of rule here. Either: (1) we
do nothing but add some mention that execution can be erroneous if the pool gets
finalized before the access type; (2) or we add some rule to prevent a
declaration like this.

Note that this can also happen if the storage pool is allocated by an allocator,
and explicitly deallocated. However, in that case, the existing dangling point
rule would be triggered by the finalization of the collection.

***************************************************************

From: Tucker Taft
Sent: Friday, October 15, 2010  9:15 AM

I don't think we have a problem here.  Finalizations do happen in reverse order,
but the finalization of an access collection occurs at the point where the
access type is frozen, not at the point where it was declared.  An access type
is necessarily frozen after the declaration of its storage pool.

Here is the wording, taken from 7.6.1(11/2):

     The order in which the finalization of a master
     performs finalization of objects is as follows:
     Objects created by declarations in the master are
     finalized in the reverse order of their creation.
     For objects that were created by allocators for
     an access type whose ultimate ancestor is declared
     in the master, this rule is applied as though each
     such object that still exists had been created in
     an arbitrary order at the first freezing point
     (see 13.14) of the ultimate ancestor type; the
     finalization of these objects is called the
     finalization of the collection.

***************************************************************

From: Bob Duff
Sent: Friday, October 15, 2010  9:33 AM

> [The declaration of Acc_Pool freezes the type Some_Storage_Pool, but
> not the unrelated type Acc. So I think specifying the pool is OK. Or
> did I miss something?]

Objects of the Acc collection get finalized at the the mirror image of the
freezing point (if you can imagine what I mean by that!).  The "for..." freezes,
so I think we're OK.

> Note that this can also happen if the storage pool is allocated by an
> allocator, and explicitly deallocated. However, in that case, the
> existing dangling point rule would be triggered by the finalization of
> the collection.

I can't imagine why you would allocate a pool with an allocator, given that you
can't allocate the access type with an allocator. Every pool I have every used
is declared by an object decl. The pool might allocate chunks of memory from
some underlying pool, but you would allocate the pool object iself in a pool.

Anyway, I agree with this part of your analysis -- if you Unchecked_Deallocate a
pool before the collections have been finalized, you're doing wrong.

***************************************************************

From: Randy Brukardt
Sent: Friday, October 15, 2010  2:58 PM

> I don't think we have a problem here.  Finalizations do happen in
> reverse order, but the finalization of an access collection occurs at
> the point where the access type is frozen, not at the point where it
> was declared.  An access type is necessarily frozen after the
> declaration of its storage pool.

Ugh, another case where I thought the implementation in Janus/Ada was correct,
and apparently it is not. Not sure how to fix that, either, generating code at
the freezing point isn't possible in general (the freezing might be in a nested
construct), but the registration of the collection anchor has to take place at
that point during the elaboration in order to get the correct effect (and not at
the declaration of the access type, which I believe is where it is occurring
now).

Humm, inspecting the code, it appears that the Janus/Ada compiler actually does
it at freezing (but apparently doesn't worry about the nesting problem, I guess
that was left for until there was a bug report).

Anyway, there is no language problem. Sorry for the false alarm.

***************************************************************


Questions? Ask the ACAA Technical Agent