--- gcc/ada/inline.adb
+++ gcc/ada/inline.adb
@@ -510,7 +510,6 @@ package body Inline is
 
       Inst      : Entity_Id;
       Inst_Decl : Node_Id;
-      Inst_Node : Node_Id;
       Level     : Inline_Level_Type;
 
    --  Start of processing for Add_Inlined_Body
@@ -609,48 +608,24 @@ package body Inline is
                  and then Is_Generic_Instance (Inst)
                  and then not Is_Called (Inst)
                then
-                  --  Do not add a pending instantiation if the body exits
-                  --  already, or if the instance is a compilation unit, or
-                  --  the instance node is missing.
-
                   Inst_Decl := Unit_Declaration_Node (Inst);
+
+                  --  Do not inline the instance if the body already exists,
+                  --  or if the instance is a compilation unit, or else if
+                  --  the instance node is simply missing.
+
                   if Present (Corresponding_Body (Inst_Decl))
                     or else Nkind (Parent (Inst_Decl)) = N_Compilation_Unit
                     or else No (Next (Inst_Decl))
                   then
                      Set_Is_Called (Inst);
-
                   else
-                     --  If the inlined call itself appears within an instance,
-                     --  ensure that the enclosing instance body is available.
-                     --  This is necessary because Sem_Ch12.Might_Inline_Subp
-                     --  does not recurse into nested instantiations.
-
-                     if not Is_Inlined (Inst) and then In_Instance then
-                        Set_Is_Inlined (Inst);
-
-                        --  The instantiation node usually follows the package
-                        --  declaration for the instance. If the generic unit
-                        --  has aspect specifications, they are transformed
-                        --  into pragmas in the instance, and the instance node
-                        --  appears after them.
-
-                        Inst_Node := Next (Inst_Decl);
-
-                        while Nkind (Inst_Node) /= N_Package_Instantiation loop
-                           Inst_Node := Next (Inst_Node);
-                        end loop;
-
-                        Add_Pending_Instantiation (Inst_Node, Inst_Decl);
-                     end if;
-
                      Add_Inlined_Instance (Inst);
                   end if;
                end if;
             end if;
 
-            --  If the unit containing E is an instance, then the instance body
-            --  will be analyzed in any case, see Sem_Ch12.Might_Inline_Subp.
+            --  If the unit containing E is an instance, nothing more to do
 
             if Is_Generic_Instance (Pack) then
                null;

--- gcc/ada/sem_ch12.adb
+++ gcc/ada/sem_ch12.adb
@@ -240,6 +240,10 @@ package body Sem_Ch12 is
    --  circularity is detected, and used to abandon compilation after the
    --  messages have been posted.
 
+   Circularity_Detected : Boolean := False;
+   --  It should really be reset upon encountering a new main unit, but in
+   --  practice we do not use multiple main units so this is not critical.
+
    -----------------------------------------
    -- Implementation of Generic Contracts --
    -----------------------------------------
@@ -352,10 +356,6 @@ package body Sem_Ch12 is
 
    --    Instantiate_Subprogram_Contract
 
-   Circularity_Detected : Boolean := False;
-   --  This should really be reset on encountering a new main unit, but in
-   --  practice we are not using multiple main units so it is not critical.
-
    --------------------------------------------------
    -- Formal packages and partial parameterization --
    --------------------------------------------------
@@ -380,23 +380,23 @@ package body Sem_Ch12 is
    --  the generic package, and a set of declarations that map the actuals
    --  into local renamings, just as we do for bona fide instantiations. For
    --  defaulted parameters and formals with a box, we copy directly the
-   --  declarations of the formal into this local package. The result is a
-   --  a package whose visible declarations may include generic formals. This
+   --  declarations of the formals into this local package. The result is a
+   --  package whose visible declarations may include generic formals. This
    --  package is only used for type checking and visibility analysis, and
-   --  never reaches the back-end, so it can freely violate the placement
+   --  never reaches the back end, so it can freely violate the placement
    --  rules for generic formal declarations.
 
    --  The list of declarations (renamings and copies of formals) is built
    --  by Analyze_Associations, just as for regular instantiations.
 
    --  At the point of instantiation, conformance checking must be applied only
-   --  to those parameters that were specified in the formal. We perform this
+   --  to those parameters that were specified in the formals. We perform this
    --  checking by creating another internal instantiation, this one including
    --  only the renamings and the formals (the rest of the package spec is not
    --  relevant to conformance checking). We can then traverse two lists: the
    --  list of actuals in the instance that corresponds to the formal package,
    --  and the list of actuals produced for this bogus instantiation. We apply
-   --  the conformance rules to those actuals that are not defaulted (i.e.
+   --  the conformance rules to those actuals that are not defaulted, i.e.
    --  which still appear as generic formals.
 
    --  When we compile an instance body we must make the right parameters
@@ -3849,12 +3849,17 @@ package body Sem_Ch12 is
       --  Only relevant when back-end inlining is not enabled.
 
       function Might_Inline_Subp (Gen_Unit : Entity_Id) return Boolean;
-      --  If inlining is active and the generic contains inlined subprograms,
-      --  we either instantiate the body when front-end inlining is enabled,
-      --  or we add a pending instantiation when back-end inlining is enabled.
-      --  In the former case, this may cause superfluous instantiations, but
-      --  in either case we need to perform the instantiation of the body in
-      --  the context of the instance and not in that of the point of inlining.
+      --  Return True if inlining is active and Gen_Unit contains inlined
+      --  subprograms. In this case, we may either instantiate the body when
+      --  front-end inlining is enabled, or add a pending instantiation when
+      --  back-end inlining is enabled. In the former case, this may cause
+      --  superfluous instantiations, but in either case we need to perform
+      --  the instantiation of the body in the context of the instance and
+      --  not in that of the point of inlining.
+
+      function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean;
+      --  Return True if Gen_Unit needs to have its body instantiated in the
+      --  context of N. This in particular excludes generic contexts.
 
       -----------------------
       -- Might_Inline_Subp --
@@ -3892,6 +3897,52 @@ package body Sem_Ch12 is
          return False;
       end Might_Inline_Subp;
 
+      -------------------------------
+      --  Needs_Body_Instantiated  --
+      -------------------------------
+
+      function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean is
+      begin
+         --  No need to instantiate bodies in generic units
+
+         if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
+            return False;
+         end if;
+
+         --  If the instantiation is in the main unit, then the body is needed
+
+         if Is_In_Main_Unit (N) then
+            return True;
+         end if;
+
+         --  If not, then again no need to instantiate bodies in generic units
+
+         if Is_Generic_Unit (Cunit_Entity (Get_Code_Unit (N))) then
+            return False;
+         end if;
+
+         --  Here we have a special handling for back-end inlining: if the
+         --  instantiation is not a compilation unit, then we want to have
+         --  its body instantiated. The reason is that Might_Inline_Subp
+         --  does not catch all the cases (since it does not recurse into
+         --  nested packages) so this avoids the need to patch things up
+         --  at a later stage. Moreover the instantiations that are not
+         --  compilation units are only performed on demand when back-end
+         --  inlining is enabled, so this causes very little extra work.
+
+         if Nkind (Parent (N)) /= N_Compilation_Unit
+           and then Inline_Processing_Required
+           and then Back_End_Inlining
+         then
+            return True;
+         end if;
+
+         --  We want to have the bodies instantiated in non-main units if
+         --  they might contribute inlined subprograms.
+
+         return Might_Inline_Subp (Gen_Unit);
+      end Needs_Body_Instantiated;
+
       --  Local declarations
 
       Gen_Id         : constant Node_Id    := Name (N);
@@ -4256,9 +4307,7 @@ package body Sem_Ch12 is
          end if;
 
          --  Save the instantiation node for a subsequent instantiation of the
-         --  body if there is one and the main unit is not generic, and either
-         --  we are generating code for this main unit, or the instantiation
-         --  contains inlined subprograms and is not done in a generic unit.
+         --  body if there is one and it needs to be instantiated here.
 
          --  We instantiate the body only if we are generating code, or if we
          --  are generating cross-reference information, or if we are building
@@ -4354,12 +4403,7 @@ package body Sem_Ch12 is
               (Unit_Requires_Body (Gen_Unit)
                 or else Enclosing_Body_Present
                 or else Present (Corresponding_Body (Gen_Decl)))
-               and then not Is_Generic_Unit (Cunit_Entity (Main_Unit))
-               and then (Is_In_Main_Unit (N)
-                          or else (Might_Inline_Subp (Gen_Unit)
-                                    and then
-                                   not Is_Generic_Unit
-                                         (Cunit_Entity (Get_Code_Unit (N)))))
+               and then Needs_Body_Instantiated (Gen_Unit)
                and then not Is_Actual_Pack
                and then not Inline_Now
                and then (Operating_Mode = Generate_Code

