[Ada] Fix assertion failure on nested formal packages with box notation

Eric Botcazou <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <3434296.44csPzL39Z@arcturus>
The compiler is trying to instantiate a generic body for an instantiation 
present in a transient package that it has discarded.

Tested on x86-64/Linux, applied on the mainline and 16 branch.


2026-08-19  Eric Botcazou  <[email protected]>

	PR ada/126928
	* sem_ch12.adb (In_Local_Package_Of_Formal_Package): New predicate.
	(Analyze_Package_Instantiation): Do not register the instantiation
	of the body if it is present in the local package of a formal one.
	(Need_Subprogram_Instance_Body): Likewise.


2026-08-19  Eric Botcazou  <[email protected]>

	* gnat.dg/specs/generic_inst10.ads: New test.
	* gnat.dg/specs/generic_inst10_g1.ads: New helper.
	* gnat.dg/specs/generic_inst10_g2.ads: Likewise.
	* gnat.dg/specs/generic_inst10_g3.ads: Likewise.
	* gnat.dg/specs/generic_inst10_pkg.ads: Likewise.

-- 
Eric Botcazou
pr126928.diff (text/x-patch, 2.5 KB)
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index e2be3f59f25..a87dde1868b 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -776,6 +776,11 @@ package body Sem_Ch12 is
    --  not done for the instantiation of the bodies, which only require the
    --  instances of the generic parents to be in scope.
 
+   function In_Local_Package_Of_Formal_Package (N : Node_Id) return Boolean;
+   --  Return whether N is present in the local package created during the
+   --  analysis of a formal package (see Analyze_Formal_Package_Declaration).
+   --  Used to avoid instantiating generic bodies in such a local package.
+
    function In_Main_Context (E : Entity_Id) return Boolean;
    --  Check whether an instantiation is in the context of the main unit.
    --  Used to determine whether its body should be elaborated to allow
@@ -5438,6 +5443,7 @@ package body Sem_Ch12 is
                and then Needs_Body_Instantiated (Gen_Unit)
                and then not Is_Abbrev
                and then not Inline_Now
+               and then not In_Local_Package_Of_Formal_Package (N)
                and then (Operating_Mode = Generate_Code
                           or else (Operating_Mode = Check_Semantics
                                     and then GNATprove_Mode));
@@ -6592,6 +6598,10 @@ package body Sem_Ch12 is
         and then (not Is_Generic_Unit (Cunit_Entity (Main_Unit))
                    or else Parent (N) = Aux_Decls_Node (Cunit (Main_Unit)))
 
+        --  Likewise in the local package built for formal packages
+
+        and then not In_Local_Package_Of_Formal_Package (N)
+
         --  Must be generating code or analyzing code in GNATprove mode
 
         and then (Operating_Mode = Generate_Code
@@ -11285,6 +11295,26 @@ package body Sem_Ch12 is
         (Current_Scope, Current_Scope, Assoc_Null);
    end Init_Env;
 
+   ----------------------------------------
+   -- In_Local_Package_Of_Formal_Package --
+   ----------------------------------------
+
+   function In_Local_Package_Of_Formal_Package (N : Node_Id) return Boolean is
+      Par : Node_Id;
+
+   begin
+      Par := Parent (N);
+      while Present (Par) and then Nkind (Par) /= N_Compilation_Unit loop
+         if Nkind (Original_Node (Par)) = N_Formal_Package_Declaration then
+            return True;
+         end if;
+
+         Par := Parent (Par);
+      end loop;
+
+      return False;
+   end In_Local_Package_Of_Formal_Package;
+
    ---------------------
    -- In_Main_Context --
    ---------------------
generic_inst10.ads (text/x-adasrc, 120 B)
with Generic_Inst10_G3;
with Generic_Inst10_Pkg;

package Generic_Inst10 is new Generic_Inst10_G3 (Generic_Inst10_Pkg);
generic_inst10_g1.ads (text/x-adasrc, 60 B)
generic
package Generic_Inst10_G1 is
end Generic_Inst10_G1;
generic_inst10_g2.ads (text/x-adasrc, 681 B)
with Ada.Containers.Indefinite_Ordered_Maps;
with Generic_Inst10_G1;

generic
package Generic_Inst10_G2 is

  generic
    with package Actual_Types is new Generic_Inst10_G1;
  package Holder is
  private
    package Maps is new Ada.Containers.Indefinite_Ordered_Maps
      (Integer, Integer);
  end Holder;

  generic
    with package Actual_Types is new Generic_Inst10_G1;
    with package Actual_Holder is new Holder (Actual_Types);
  package User is
  end User;

  generic
    with package Actual_Types is new Generic_Inst10_G1;
    with package Actual_User is
      new User (Actual_Types => Actual_Types, others => <>);
  package Final is
  end Final;

end Generic_Inst10_G2;
generic_inst10_g3.ads (text/x-adasrc, 446 B)
with Generic_Inst10_G1;
with Generic_Inst10_G2;

generic
   with package Actual_Types is new Generic_Inst10_G1;
package Generic_Inst10_G3 is
   package Actual_Root is new Generic_Inst10_G2;
   package Actual_Holder is new Actual_Root.Holder (Actual_Types);
   package Actual_User is new
     Actual_Root.User (Actual_Types, Actual_Holder);
   package Actual_Final is new
     Actual_Root.Final (Actual_Types, Actual_User);
end Generic_Inst10_G3;
generic_inst10_pkg.ads (text/x-adasrc, 78 B)
with Generic_Inst10_G1;

package Generic_Inst10_Pkg is new Generic_Inst10_G1;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.