[Ada] Double finalization of limited controlled result

This patch disables a build-in-place optimization when a function returns a limited controlled result because the optimization may violate the semantics of finalizable types by performing illegal calls to Finalize.

In general, the optimization causes the result object of a build-in-place function to be allocated at the caller site, with a pointer to the object passed to the function. The function then simply initializes the caller-allocated object.

This mode of operation however violates semantics of finalizable types when the context of the call is allocation. The act of allocating the controlled object at the caller site will place it on the associated access type's finalization master. If the function fails the initialization of the object, the malformed object will still be finalized when the finalization master goes out of scope. This is dangerous, and must not happen.

-- Source --

-- pack.ads

with Ada.Finalization; use Ada.Finalization;

package Pack is type Lim_Ctrl is new Limited_Controlled with null record; procedure Finalize (Obj : in out Lim_Ctrl);

- exp_ch6.adb (Add_Unconstrained_Actuals_To_Build_In_Place_Call): Do not add any actuals when the size of the object is known, and the caller will allocate it. (Build_Heap_Allocator): Rename to Build_Heap_Or_Pool_Allocator to better illustrate its functionality. Update the comment on the generated code. Generate a branch for the heap and pool cases where the object is not necessarity controlled. (Expand_N_Extended_Return_Statement): Expand the extended return statement into four branches depending the requested mode if the caller will not allocate the object on its side. (Make_Build_In_Place_Call_In_Allocator): Do not allocate a controlled object on the caller side because this will violate the semantics of finalizable types. Instead notify the function to allocate the object on the heap or a user-defined storage pool. (Needs_BIP_Alloc_Form): A build-in-place function needs to be notified which of the four modes to employ when returning a limited controlled result.- exp_util.adb (Build_Allocate_Deallocate_Proc): Remove a redundant guard which is already covered in Needs_Finalization.