This patch fixes a compiler crash on an inlined call in a nested instantiation
when the corresponding generic unit has aspect specifications.

The following must compile quietly:

   gcc -c inst.ads -gnatn -O

---
with Pointer;
package Inst is
   package I is new Pointer (Integer);
end;
---
package body Pointer is
   function Deref (Pointer : WI.W) return P is
   begin
      return WI.Load (Pointer);
   end;
end;
---
with Wrapper;
generic
   type Any_Type;
package Pointer is
   pragma Elaborate_Body;
   type P is access Any_Type;
   package WI is new Wrapper (P);
end;
---
package body Wrapper is
   function Load (A : W) return Data_Type is
   begin
      return A.Data;
   end;
end;
---
generic
   type Data_Type is private;
package Wrapper with Preelaborate
 is
   pragma Preelaborate;
   type W is record
      Data : Data_Type;
   end record;
   function Load (A : W) return Data_Type with Inline;
end;

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

2016-05-02  Ed Schonberg  <schonb...@adacore.com>

        * exp_ch6.adb (Expand_Call): When inlining a call to a function
        declared in a package instance, locate the instance node of the
        package after the actual package declaration. skipping over
        pragmas that may have been introduced when the generic unit
        carries aspects that are transformed into pragmas.

Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb (revision 235742)
+++ exp_ch6.adb (working copy)
@@ -3970,8 +3970,9 @@
               and then Optimization_Level > 0
             then
                declare
-                  Inst : Entity_Id;
-                  Decl : Node_Id;
+                  Decl      : Node_Id;
+                  Inst      : Entity_Id;
+                  Inst_Node : Node_Id;
 
                begin
                   Inst := Scope (Subp);
@@ -4001,7 +4002,19 @@
                         null;
 
                      else
-                        Add_Pending_Instantiation (Next (Decl), Decl);
+                        --  The instantiation node follows the package
+                        --  declaration for the instance. If the generic
+                        --  unit had aspect specifications, they have
+                        --  been transformed into pragmas in the instance,
+                        --  and the instance node appears after them.
+
+                        Inst_Node := Next (Decl);
+
+                        while Nkind (Inst_Node) /= N_Package_Instantiation loop
+                           Inst_Node := Next (Inst_Node);
+                        end loop;
+
+                        Add_Pending_Instantiation (Inst_Node, Decl);
                      end if;
                   end if;
                end;

Reply via email to