[Ada] Fix internal error on inlining of renamed subprogram instantiation

Arnaud Charlet charlet@adacore.com
Fri Feb 20 10:01:00 GMT 2015


This fixes an assertion failure in gigi triggered by an order-of-elaboration
issue for the type of a parameter of a subprogram which is both the renaming
of another subprogram and marked Inline.  In this case the compiler was using
expansion (aka front-end inlining) but this doesn't always play nice with the
freezing model used for generics so the patch makes it use back-end inlining.

The following package must compile quietly with -O -gnatn:

with F;
with G;

package P is

  function Uid_Image (Uid : Integer) return String;

  package Inner is
    type Arr is array (Positive range <>) of Integer;
    function Image is new F (Integer, Positive, Arr, Uid_Image);
  end Inner;

  package Value_Set is new G (Integer);

  function Uid_Image (Uid : Integer) return String renames Value_Set.Uid_Image;
  pragma Inline (Uid_Image);

end P;
generic
  type Item_T is limited private;
  type Index_T is (<>);
  type Array_T is array (Index_T range <>) of Item_T;
  with function Image (Item : Item_T) return String;
function F (A : Array_T) return String;
with Ada.Strings.Unbounded;

function F (A : Array_T) return String is
  Result : Ada.Strings.Unbounded.Unbounded_String;
begin
  for I in A'Range loop
    Ada.Strings.Unbounded.Append (Result, Image (A (I)));
  end loop;
  return Ada.Strings.Unbounded.To_String (Result);
end;
generic

  type T is range <>;

package G is

  function Uid_Image (Uid : T) return String;

end G;
package body G is

  function Uid_Image (Uid : T) return String is
  begin
    return T'Image (Uid);
  end;

end G;

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

2015-02-20  Eric Botcazou  <ebotcazou@adacore.com>

	* inline.adb (Expand_Inlined_Call): Skip again calls to subprogram
	renamings.
	* exp_ch6.adb (Expand_Call): Use back-end inlining
	instead of expansion for simple subprogram renamings.

-------------- next part --------------
Index: inline.adb
===================================================================
--- inline.adb	(revision 220841)
+++ inline.adb	(working copy)
@@ -2694,12 +2694,11 @@
          return;
 
       --  Skip inlining if this is not a true inlining since the attribute
-      --  Body_To_Inline is also set for renamings (see sinfo.ads)
+      --  Body_To_Inline is also set for renamings (see sinfo.ads). For a
+      --  true inlining, Orig_Bod has code rather than being an entity.
 
       elsif Nkind (Orig_Bod) in N_Entity then
-         if not Has_Pragma_Inline (Subp) then
-            return;
-         end if;
+         return;
 
       --  Skip inlining if the function returns an unconstrained type using
       --  an extended return statement since this part of the new inlining
Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb	(revision 220843)
+++ exp_ch6.adb	(working copy)
@@ -3778,12 +3778,17 @@
            or else Nkind (Unit_Declaration_Node (Subp)) /=
                                                  N_Subprogram_Declaration
            or else No (Body_To_Inline (Unit_Declaration_Node (Subp)))
+           or else Nkind (Body_To_Inline (Unit_Declaration_Node (Subp))) in
+                                                                      N_Entity
          then
             Add_Inlined_Body (Subp, Call_Node);
 
          --  Front end expansion of simple functions returning unconstrained
-         --  types (see Check_And_Split_Unconstrained_Function) and simple
-         --  renamings inlined by the front end (see Build_Renamed_Body).
+         --  types (see Check_And_Split_Unconstrained_Function). Note that the
+         --  case of a simple renaming (Body_To_Inline in N_Entity above, see
+         --  also Build_Renamed_Body) cannot be expanded here because this may
+         --  give rise to order-of-elaboration issues for the types of the
+         --  parameters of the subprogram, if any.
 
          else
             Expand_Inlined_Call (Call_Node, Subp, Orig_Subp);


More information about the Gcc-patches mailing list