From: Steve Baird <[email protected]>
If Ada.Containers.Bounded_Indefinite_Holders is instantiated with an
Element_Type that requires finalization, the declaration of a Holder object
with an explicit initial value may incorrectly raise Program_Error during
its elaboration.
Tested on x86-64/Linux, applied on the mainline.
gcc/ada/ChangeLog:
PR ada/124016
* libgnat/a-cbinho.adb (Create_Subpool): Handle the case where
the type Holder_Subpool has nontrivial finalization. Declare the
local variable Subpool with its Import aspect specified (to avoid
unwanted finalization), and make corresponding changes in order to
initialize that variable.
* libgnat/s-stposu.ads (_Adjust_Clone): New procedure.
* libgnat/s-stposu.adb (_Adjust_Clone): New body.
--
Eric Botcazoudiff --git a/gcc/ada/libgnat/a-cbinho.adb b/gcc/ada/libgnat/a-cbinho.adb
index a5c513c24e6..8949bfe4c5d 100644
--- a/gcc/ada/libgnat/a-cbinho.adb
+++ b/gcc/ada/libgnat/a-cbinho.adb
@@ -298,13 +298,37 @@ package body Ada.Containers.Bounded_Indefinite_Holders is
Subpool_Start + Holder_Subpool'Max_Size_In_Storage_Elements;
-- Will deal with alignment on allocation
- Subpool : aliased Holder_Subpool :=
- (Root_Subpool with Start => Element_Start)
- with Address => Subpool_Start;
- -- We depend here on the type Holder_Subpool not having nontrivial
- -- finalization (if it did then this local object would be
- -- finalized earlier than what we want).
+ Subpool : aliased Holder_Subpool
+ with Address => Subpool_Start, Import;
+ -- Import is specified to avoid unwanted early finalization.
+ -- But that also prevents initialization (via either default
+ -- initialization or an explicit initial value expression) ...
begin
+ -- ... so instead initialize Subpool via overlays. But that
+ -- assumes a representation where copying bytes works, and that
+ -- assumption doesn't hold for self-referential pointers.
+ -- So we also call Subpools._Adjust_Clone (sic). Ugly.
+
+ declare
+ use System;
+
+ Subpool_Init_Source : aliased Holder_Subpool :=
+ (Root_Subpool with Start => Element_Start);
+
+ pragma Assert (Holder_Subpool'Size mod Storage_Unit = 0);
+
+ subtype Holder_Subpool_Storage is
+ Storage_Array (1 .. Holder_Subpool'Size / Storage_Unit);
+ Source : Holder_Subpool_Storage with Import,
+ Address => Subpool_Init_Source'Address;
+ Target : Holder_Subpool_Storage with Import,
+ Address => Subpool'Address;
+ begin
+ Target := Source;
+ -- leading underscore is deliberate
+ _Adjust_Clone (Root_Subpool (Subpool));
+ end;
+
Set_Pool_Of_Subpool (Subpool'Unchecked_Access, Pool);
-- Return the handle
return Subpool'Unchecked_Access;
diff --git a/gcc/ada/libgnat/s-stposu.adb b/gcc/ada/libgnat/s-stposu.adb
index bc55665e0e3..c6d941af0a0 100644
--- a/gcc/ada/libgnat/s-stposu.adb
+++ b/gcc/ada/libgnat/s-stposu.adb
@@ -695,4 +695,13 @@ package body System.Storage_Pools.Subpools is
Attach (N_Ptr, To.Subpools'Unchecked_Access);
end Set_Pool_Of_Subpool;
+ -------------------
+ -- _Adjust_Clone --
+ -------------------
+
+ procedure _Adjust_Clone (Subpool : in out Root_Subpool) is
+ begin
+ Finalization_Primitives.Initialize (Subpool.Collection);
+ end _Adjust_Clone;
+
end System.Storage_Pools.Subpools;
diff --git a/gcc/ada/libgnat/s-stposu.ads b/gcc/ada/libgnat/s-stposu.ads
index b5ef2a0e9fe..13d7889471a 100644
--- a/gcc/ada/libgnat/s-stposu.ads
+++ b/gcc/ada/libgnat/s-stposu.ads
@@ -131,6 +131,18 @@ package System.Storage_Pools.Subpools is
is
(System.Storage_Elements.Storage_Count'Last);
+ procedure _Adjust_Clone (Subpool : in out Root_Subpool);
+ -- After copying the value of an initialized (but otherwise unused)
+ -- Root_Subpool object into another subpool object using unchecked
+ -- techniques (an assignment statement would be illegal), this
+ -- procedure is called to fixup the copy (in particular, it fixes up
+ -- self-referential access values contained therein).
+ --
+ -- The leading underscore is intentional. We don't want a user-visible
+ -- declaration that is not mentioned in the spec for this package that
+ -- is given in the Ada RM. This subprogram is called only from the body
+ -- of Ada.Containers.Bounded_Indefinite_Holders.
+
private
-- SP_Nodes are created on the heap, while collection nodes and associated
-- objects are created on the pool_with_subpools.