13.11.2 Unchecked Storage Deallocation
Unchecked 
storage deallocation of an object designated by a value of an access 
type is achieved by a call to an instance of the generic procedure Unchecked_Deallocation. 
 
Static Semantics
The following language-defined 
generic library procedure exists: 
generic
   type Object(<>) 
is limited private;
   
type Name   
is access  Object;
procedure Ada.Unchecked_Deallocation(X : 
in out Name)
   
with Convention => Intrinsic;
pragma Preelaborate(Ada.Unchecked_Deallocation);
 
Legality Rules
  A call on an instance of Unchecked_Deallocation 
is illegal if the actual access type of the instance is a type for which 
the Storage_Size has been specified by a static expression with value 
zero or is defined by the language to be zero. 
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.
 
Dynamic Semantics
Given an instance of 
Unchecked_Deallocation declared as follows: 
procedure Free is
    new Ada.Unchecked_Deallocation(
        object_subtype_name, access_to_variable_subtype_name);
Procedure Free has 
the following effect: 
1.
After executing Free(X), the value of X is null.
2.
Free(X), when X is already equal to null, has no effect.
3.
Free(X), when X is not equal to 
null first performs finalization 
of the object designated by X (and any coextensions of the object — 
see 
3.10.2), as described in 
7.6.1. 
It then deallocates the storage occupied by the object designated by 
X (and any coextensions). If the storage pool is a user-defined object, 
then the storage is deallocated by calling Deallocate as described in 
13.11. There is one exception: if the object 
being freed contains tasks, the object might not be deallocated. 
 
 After 
the finalization step of Free(X), the object designated by X, and any 
subcomponents (and coextensions) thereof, no longer exist; their storage 
can be reused for other purposes. 
 
Bounded (Run-Time) Errors
It 
is a bounded error to free a discriminated, unterminated task object. 
The possible consequences are: 
 
No exception is raised.
Program_Error 
or Tasking_Error is raised at the point of the deallocation.
 
Program_Error 
or Tasking_Error is raised in the task the next time it references any 
of the discriminants. 
 
In the first two cases, the storage for the discriminants 
(and for any enclosing object if it is designated by an access discriminant 
of the task) is not reclaimed prior to task termination. 
   An access value that designates a nonexistent 
object is called a 
dangling reference.
 
   If a dangling reference is dereferenced (implicitly 
or explicitly), execution is erroneous (see below). If there is no explicit 
or implicit dereference, then it is a bounded error 
to 
evaluate an expression whose result is a dangling reference. If the error 
is detected, either Constraint_Error or Program_Error is raised. 
Otherwise, 
execution proceeds normally, but with the possibility that the access 
value designates some other existing object.
 
Erroneous Execution
 Evaluating 
a name that denotes a nonexistent object, or a protected subprogram or 
subprogram renaming whose associated object (if any) is nonexistent, 
is erroneous. The execution of a call to an instance of Unchecked_Deallocation 
is erroneous if the object was created other than by an 
allocator 
for an access type whose pool is Name'Storage_Pool.
 
Implementation Advice
For a standard storage pool, Free should actually 
reclaim the storage. 
   A call on an instance of Unchecked_Deallocation 
with a nonnull access value should raise Program_Error if the actual 
access type of the instance is a type for which the Storage_Size has 
been specified to be zero or is defined by the language to be zero. 
30  The rules here that refer to Free apply 
to any instance of Unchecked_Deallocation.
31  Unchecked_Deallocation cannot be instantiated 
for an access-to-constant type. This is implied by the rules of 
12.5.4. 
 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe