Section 6: Subprograms 6.1 Subprogram Declarations
7.6 User-Defined Assignment and Finalization Replace paragraph 5: [AI95-00161-01]
type Controlled is abstract tagged private;
by:
type Controlled is abstract tagged private; pragma Preelaborable_Initialization(Controlled);
Replace paragraph 6: [AI95-00348-01]
procedure Initialize (Object : in out Controlled); procedure Adjust (Object : in out Controlled); procedure Finalize (Object : in out Controlled);
by:
procedure Initialize (Object : in out Controlled) is null; procedure Adjust (Object : in out Controlled) is null; procedure Finalize (Object : in out Controlled) is null;
Replace paragraph 7: [AI95-00161-01]
type Limited_Controlled is abstract tagged limited private;
by:
type Limited_Controlled is abstract tagged limited private; pragma Preelaborable_Initialization(Limited_Controlled);
Replace paragraph 8: [AI95-00348-01]
procedure Initialize (Object : in out Limited_Controlled); procedure Finalize (Object : in out Limited_Controlled);
private
... -- not specified by the language end Ada.Finalization;
by:
procedure Initialize (Object : in out Limited_Controlled) is null; procedure Finalize (Object : in out Limited_Controlled) is null;
private
... -- not specified by the language end Ada.Finalization;
Replace paragraph 9: [AI95-00348-01; AI95-00360-01]
A controlled type is a descendant of Controlled or Limited_Controlled. The (default) implementations of Initialize, Adjust, and Finalize have no effect. The predefined "=" operator of type Controlled always returns True, since this operator is incorporated into the implementation of the predefined equality operator of types derived from Controlled, as explained in 4.5.2. The type Limited_Controlled is like Controlled, except that it is limited and it lacks the primitive subprogram Adjust.
by:
A controlled type is a descendant of Controlled or Limited_Controlled. The predefined "=" operator of type Controlled always returns True, since this operator is incorporated into the implementation of the predefined equality operator of types derived from Controlled, as explained in 4.5.2. The type Limited_Controlled is like Controlled, except that it is limited and it lacks the primitive subprogram Adjust.
A type is said to need finalization if:
• it is a controlled type, a task type or a protected type; or
• it is a limited type that has an access discriminant whose designated type needs finalization; or
• it is one of a number of language-defined types that are explicitly defined to need finalization. Replace paragraph 21: [AI95-00147-01]
• For an aggregate or function call whose value is assigned into a target object, the implementation need not create a separate anonymous object if it can safely create the value of the aggregate or function call directly in the target object. Similarly, for an assignment_statement, the
implementation need not create an anonymous object if the value being assigned is the result of evaluating a name denoting an object (the source object) whose storage cannot overlap with the target. If the source object might overlap with the target object, then the implementation can avoid the need for an intermediary anonymous object by exercising one of the above permissions and perform the assignment one component at a time (for an overlapping array assignment), or not at all (for an assignment where the target and the source of the assignment are the same object). Even if an anonymous object is created, the implementation may move its value to the target object as part of the assignment without re-adjusting so long as the anonymous object has no aliased
subcomponents. by:
• For an aggregate or function call whose value is assigned into a target object, the implementation need not create a separate anonymous object if it can safely create the value of the aggregate or function call directly in the target object. Similarly, for an assignment_statement, the
implementation need not create an anonymous object if the value being assigned is the result of evaluating a name denoting an object (the source object) whose storage cannot overlap with the target. If the source object might overlap with the target object, then the implementation can avoid the need for an intermediary anonymous object by exercising one of the above permissions and perform the assignment one component at a time (for an overlapping array assignment), or not at all (for an assignment where the target and the source of the assignment are the same object).
Furthermore, an implementation is permitted to omit implicit Initialize, Adjust, and Finalize calls and associated assignment operations on an object of nonlimited controlled type provided that:
• any omitted Initialize call is not a call on a user-defined Initialize procedure, and
• any usage of the value of the object after the implicit Initialize or Adjust call and before any subsequent Finalize call on the object does not change the external effect of the program, and
• after the omission of such calls and operations, any execution of the program that executes an Initialize or Adjust call on an object or initializes an object by an aggregate will also later execute a Finalize call on the object and will always do so prior to assigning a new value to the object, and
• the assignment operations associated with omitted Adjust calls are also omitted.
This permission applies to Adjust and Finalize calls even if the implicit calls have additional external effects.
7.6.1 Completion and Finalization
Replace paragraph 3: [AI95-00162-01]After execution of a construct or entity is complete, it is left, meaning that execution continues with the next action, as defined for the execution that is taking place. Leaving an execution happens immediately after its completion, except in the case of a master: the execution of a task_body, a block_statement, a
subprogram_body, an entry_body, or an accept_statement. A master is finalized after it is complete, and before it is left.
by:
After execution of a construct or entity is complete, it is left, meaning that execution continues with the next action, as defined for the execution that is taking place. Leaving an execution happens immediately after its completion, except in the case of a master: the execution of a body other than a package_body; the
elaboration of a declaration other than the declaration of a package; the execution of an accept_statement, a block_statement, or a simple_statement; or the evaluation of an expression or range that is not part of an enclosing expression, range, or simple_statement. A master is finalized after it is complete, and before it is left.
Replace paragraph 11: [AI95-00280-01]
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.
by:
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.
Replace paragraph 12: [AI95-00256-01]
The target of an assignment statement is finalized before copying in the new value, as explained in 7.6. by:
The target of an assignment_statement is finalized before copying in the new value, as explained in 7.6.
Replace paragraph 13: [AI95-00162-01]
If the object_name in an object_renaming_declaration, or the actual parameter for a generic formal in out parameter in a generic_instantiation, denotes any part of an anonymous object created by a function call, the anonymous object is not finalized until after it is no longer accessible via any name. Otherwise, an anonymous object created by a function call or by an aggregate is finalized no later than the end of the innermost enclosing declarative_item or statement; if that is a compound_statement, the object is finalized before starting the execution of any statement within the compound_statement.
by:
The master of an object is the master enclosing its creation whose accessibility level (see 3.10.2) is equal to that of the object.
Replace paragraph 13.1: [AI95-00162-01]
If a transfer of control or raising of an exception occurs prior to performing a finalization of an anonymous object, the anonymous object is finalized as part of the finalizations due to be performed for the object's innermost enclosing master.
by:
In the case of a potentially blocking operation which is a master, finalization of an (anonymous) object occurs before blocking if the last use of the object occurs before blocking. In particular, for a
delay_statement, any finalization occurs before delaying the task. In the case of an expression which is a master, finalization of any (anonymous) objects occurs as the final part of evaluation of the expression.
Replace paragraph 16: [AI95-00256-01]
• For an Adjust invoked as part of the initialization of a controlled object, other adjustments due to be performed might or might not be performed, and then Program_Error is raised. During its
propagation, finalization might or might not be applied to objects whose Adjust failed. For an Adjust invoked as part of an assignment statement, any other adjustments due to be performed are performed, and then Program_Error is raised.
by:
• For an Adjust invoked as part of assignment operations other than those invoked as part of an assignment_statement, other adjustments due to be performed might or might not be performed, and then Program_Error is raised. During its propagation, finalization might or might not be applied to objects whose Adjust failed. For an Adjust invoked as part of an
assignment_statement, any other adjustments due to be performed are performed, and then Program_Error is raised.