diff mbox series

[Ada] Crash on compilation unit instance

Message ID 20180524130514.GA61968@adacore.com
State New
Headers show
Series [Ada] Crash on compilation unit instance | expand

Commit Message

Pierre-Marie de Rodat May 24, 2018, 1:05 p.m. UTC
Do not generate a variable marker for a reference which appears within the
formal part of an instantiation which acts as a compilation unit because
there is no suitable insertion context.

------------
-- Source --
------------

--  gnat.adc

pragma SPARK_Mode (On);

--  gen.ads

generic
   Val_1 : Integer;
   Val_2 : Integer;
package Gen is
end Gen;

--  pack.ads

package Pack is
   Val : Integer := 123;

   function Get_Val return Integer;
end Pack;

--  inst.ads

with Gen;
with Pack; use Pack;

package Inst is new Gen (Val, Get_Val);

--  proc.adb

with Pack; use Pack;

procedure Proc (Val_1 : Integer := Val; Val_2 : Integer := Get_Val) is
begin null; end Proc;

-----------------
-- Compilation --
-----------------

$ gcc -c inst.ads
$ gcc -c inst.ads -gnatd.F
$ gcc -c proc.adb
$ gcc -c proc.adb -gnatd.F

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

2018-05-24  Hristian Kirtchev  <kirtchev@adacore.com>

gcc/ada/

	* sem_elab.adb (Build_Variable_Reference_Marker): Do not create a
	variable marker when the reference appears in the formal part of a
	compilation unit instance because there is no place to insert it.
	(In_Compilation_Instance_Formal_Part): New routine.
diff mbox series

Patch

--- gcc/ada/sem_elab.adb
+++ gcc/ada/sem_elab.adb
@@ -2274,9 +2274,44 @@  package body Sem_Elab is
       Read  : Boolean;
       Write : Boolean)
    is
+      function In_Compilation_Instance_Formal_Part
+        (Nod : Node_Id) return Boolean;
+      --  Determine whether arbitrary node Nod appears within the formal part
+      --  of an instantiation which acts as a compilation unit.
+
       function In_Pragma (Nod : Node_Id) return Boolean;
       --  Determine whether arbitrary node Nod appears within a pragma
 
+      -----------------------------------------
+      -- In_Compilation_Instance_Formal_Part --
+      -----------------------------------------
+
+      function In_Compilation_Instance_Formal_Part
+        (Nod : Node_Id) return Boolean
+      is
+         Par : Node_Id;
+
+      begin
+         Par := Nod;
+         while Present (Par) loop
+            if Nkind (Par) = N_Generic_Association
+              and then Nkind (Parent (Par)) in N_Generic_Instantiation
+              and then Nkind (Parent (Parent (Par))) = N_Compilation_Unit
+            then
+               return True;
+
+            --  Prevent the search from going too far
+
+            elsif Is_Body_Or_Package_Declaration (Par) then
+               exit;
+            end if;
+
+            Par := Parent (Par);
+         end loop;
+
+         return False;
+      end In_Compilation_Instance_Formal_Part;
+
       ---------------
       -- In_Pragma --
       ---------------
@@ -2349,6 +2384,15 @@  package body Sem_Elab is
                   and then Entity (N) /= Any_Id)
       then
          return;
+
+      --  Nothing to do when the reference appears within the formal part of
+      --  an instantiation which acts as compilation unit because there is no
+      --  proper context for the insertion of the marker.
+
+      --  Performance note: parent traversal
+
+      elsif In_Compilation_Instance_Formal_Part (N) then
+         return;
       end if;
 
       Extract_Variable_Reference_Attributes