This patch updates the library graph augmentation mechanism of the
elaboration order v4.0 to emulate a particular behavior of the v3.0
scheme involving generic instantiations. If a unit without any
elaboration code instantiates a generic without any elaboration code,
the invocation edge from the instance to the generic body is not
considered for library graph augmentation.

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

--  gen_pack1.ads

generic
   type Element_Type is private;

package Gen_Pack1 is
   procedure Read;
end Gen_Pack1;

--  gen_pack1.adb

with Types1;

package body Gen_Pack1 is
   procedure Read is null;
end Gen_Pack1;

--  types1.ads

with Gen_Pack1;

package Types1 is
   procedure Read;

   package Optional_Numbers is new Gen_Pack1 (Positive);
end Types1;

--  main1.adb

with Types1;

procedure Main1 is
begin
   Types1.Optional_Numbers.Read;
end Main1;

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

$ gnatmake -q main1.adb

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

2019-07-09  Hristian Kirtchev  <kirtc...@adacore.com>

gcc/ada/

        * bindo-augmentors.adb (Visit_Elaboration_Root): Do not start a
        DFS from an elaboration root whose corresponding unit lacks
        elaboration code. This behavior mimics that of the old
        elaboration order mechanism.
        * bindo-graphs.adb (Find_All_Cycles_Through_Vertex): Move the
        vertex tracing within the functional branches of the routine.
        This prevents spurious trace output.
        (Has_No_Elaboration_Code): New routine.
        (Trace_Cycle, Trace_Edge): Update the various Ids to use the
        "standard" trace format.
        * bindo-graphs.ads (Has_No_Elaboration_Code): New routine.
        * bindo-units.ads, bindo-units.adb (Has_No_Elaboration_Code):
        New routine.
--- gcc/ada/bindo-augmentors.adb
+++ gcc/ada/bindo-augmentors.adb
@@ -152,6 +152,17 @@ package body Bindo.Augmentors is
          Visited : IGV_Sets.Membership_Set;
 
       begin
+         --  Nothing to do when the unit where the elaboration root resides
+         --  lacks elaboration code. This implies that any invocation edges
+         --  going out of the unit are unwanted. This behavior emulates the
+         --  old elaboration order mechanism.
+
+         if Has_No_Elaboration_Code (Lib_Graph, Root_Vertex) then
+            return;
+         end if;
+
+         --  Prepare the global data
+
          Visited := IGV_Sets.Create (Number_Of_Vertices (Inv_Graph));
 
          Visit_Vertex

--- gcc/ada/bindo-graphs.adb
+++ gcc/ada/bindo-graphs.adb
@@ -2356,13 +2356,13 @@ package body Bindo.Graphs is
             return;
          end if;
 
-         Trace_Vertex (G, Vertex, Indent);
-
          --  The current vertex denotes the end vertex of the cycle and closes
          --  the circuit. Normalize the cycle such that it is rotated with its
          --  most significant edge first, and record it for diagnostics.
 
          if LGV_Sets.Contains (End_Vertices, Vertex) then
+            Trace_Vertex (G, Vertex, Indent);
+
             Normalize_And_Add_Cycle
               (G                     => G,
                Most_Significant_Edge => Most_Significant_Edge,
@@ -2374,6 +2374,7 @@ package body Bindo.Graphs is
          --  not been visited yet.
 
          elsif not LGV_Sets.Contains (Visited_Vertices, Vertex) then
+            Trace_Vertex (G, Vertex, Indent);
 
             --  Prepare for vertex backtracking
 
@@ -2859,6 +2860,21 @@ package body Bindo.Graphs is
          return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
       end Has_Next;
 
+      -----------------------------
+      -- Has_No_Elaboration_Code --
+      -----------------------------
+
+      function Has_No_Elaboration_Code
+        (G      : Library_Graph;
+         Vertex : Library_Graph_Vertex_Id) return Boolean
+      is
+      begin
+         pragma Assert (Present (G));
+         pragma Assert (Present (Vertex));
+
+         return Has_No_Elaboration_Code (Unit (G, Vertex));
+      end Has_No_Elaboration_Code;
+
       -----------------------------------------
       -- Hash_Library_Graph_Cycle_Attributes --
       -----------------------------------------
@@ -4878,7 +4894,7 @@ package body Bindo.Graphs is
             Next (Iter, Edge);
 
             Indent_By (Edge_Indent);
-            Write_Str ("library graph edge (Edge_");
+            Write_Str ("library graph edge (LGE_Id_");
             Write_Int (Int (Edge));
             Write_Str (")");
             Write_Eol;
@@ -4912,7 +4928,7 @@ package body Bindo.Graphs is
          end if;
 
          Indent_By (Indent);
-         Write_Str ("library graph edge (Edge_");
+         Write_Str ("library graph edge (LGE_Id_");
          Write_Int (Int (Edge));
          Write_Str (")");
          Write_Eol;
@@ -4923,14 +4939,14 @@ package body Bindo.Graphs is
          Write_Eol;
 
          Indent_By  (Attr_Indent);
-         Write_Str  ("Predecessor (Vertex_");
+         Write_Str  ("Predecessor (LGV_Id_");
          Write_Int  (Int (Pred));
          Write_Str  (") name = ");
          Write_Name (Name (G, Pred));
          Write_Eol;
 
          Indent_By  (Attr_Indent);
-         Write_Str  ("Successor   (Vertex_");
+         Write_Str  ("Successor   (LGV_Id_");
          Write_Int  (Int (Succ));
          Write_Str  (") name = ");
          Write_Name (Name (G, Succ));
@@ -4977,7 +4993,7 @@ package body Bindo.Graphs is
          end if;
 
          Indent_By (Indent);
-         Write_Str ("library graph vertex (Vertex_");
+         Write_Str ("library graph vertex (LGV_Id_");
          Write_Int (Int (Vertex));
          Write_Str (")");
          Write_Eol;

--- gcc/ada/bindo-graphs.ads
+++ gcc/ada/bindo-graphs.ads
@@ -1028,6 +1028,13 @@ package Bindo.Graphs is
       --  Determine whether library graph G contains a cycle involving pragma
       --  Elaborate_All.
 
+      function Has_No_Elaboration_Code
+        (G      : Library_Graph;
+         Vertex : Library_Graph_Vertex_Id) return Boolean;
+      pragma Inline (Has_No_Elaboration_Code);
+      --  Determine whether vertex Vertex of library graph G represents a unit
+      --  that lacks elaboration code.
+
       function In_Same_Component
         (G     : Library_Graph;
          Left  : Library_Graph_Vertex_Id;

--- gcc/ada/bindo-units.adb
+++ gcc/ada/bindo-units.adb
@@ -199,6 +199,19 @@ package body Bindo.Units is
       return Unit_Sets.Has_Next (Unit_Sets.Iterator (Iter));
    end Has_Next;
 
+   -----------------------------
+   -- Has_No_Elaboration_Code --
+   -----------------------------
+
+   function Has_No_Elaboration_Code (U_Id : Unit_Id) return Boolean is
+      pragma Assert (Present (U_Id));
+
+      U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
+
+   begin
+      return U_Rec.No_Elab;
+   end Has_No_Elaboration_Code;
+
    -------------------------------
    -- Hash_Invocation_Signature --
    -------------------------------

--- gcc/ada/bindo-units.ads
+++ gcc/ada/bindo-units.ads
@@ -81,6 +81,10 @@ package Bindo.Units is
    pragma Inline (For_Each_Unit);
    --  Invoke Processor on each unit in the bind
 
+   function Has_No_Elaboration_Code (U_Id : Unit_Id) return Boolean;
+   pragma Inline (Has_No_Elaboration_Code);
+   --  Determine whether unit U_Id lacks elaboration code
+
    function Hash_Invocation_Signature
      (IS_Id : Invocation_Signature_Id) return Bucket_Range_Type;
    pragma Inline (Hash_Invocation_Signature);

Reply via email to