[Ada] Crash on imported object with deep initialization and No_Aborts

Message ID 20210507093823.GA140643@adacore.com
State New
Headers show
  • [Ada] Crash on imported object with deep initialization and No_Aborts
Related show

Commit Message

Pierre-Marie de Rodat May 7, 2021, 9:38 a.m.
Compiler aborts on an object declaration without an expression, when the
type of the object includes controlled components and thus requires deep
initialization, there are various restrictions in effect that prevent
Abort statements, and there is a later Import pragma that applies to
the object being declared.

Tested on x86_64-pc-linux-gnu, committed on trunk


	* exp_util.adb (Remove_Init_Call): If a simple initialization
	call is present, and the next statement is an initialization
	block (that contains a call to a Deep_ Initialize routine),
	remove the block as well, and insert the first initialization
	call in it, in case it is needed for later relocation.


diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -11382,6 +11382,26 @@  package body Exp_Util is
       end if;
       if Present (Init_Call) then
+         --  If restrictions have forbidden Aborts, the initialization call
+         --  for objects that require deep initialization has not been wrapped
+         --  into the following block (see Exp_Ch3, Default_Initialize_Object)
+         --  so if present remove it as well, and include the IP call in it,
+         --  in the rare case the caller may need to simply displace the
+         --  initialization, as is done for a later address specification.
+         if Nkind (Next (Init_Call)) = N_Block_Statement
+           and then Is_Initialization_Block (Next (Init_Call))
+         then
+            declare
+               IP_Call : constant Node_Id := Init_Call;
+            begin
+               Init_Call := Next (IP_Call);
+               Remove (IP_Call);
+               Prepend (IP_Call,
+                 Statements (Handled_Statement_Sequence (Init_Call)));
+            end;
+         end if;
          Remove (Init_Call);
       end if;