This patch updates the instantiation machinery to properly preserve a reference
to a global type in a qualified expression used to convert a universal literal
to a specific type, and propagate it to the instantiated template.

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

--  types.ads

package Types is
   type Uint is private;
   type Int is range -2**31 .. +2**31 - 1;

   function "+" (Left : Uint; Right : Uint) return Uint;
   function "+" (Left : Int;  Right : Uint) return Uint;
   function "+" (Left : Uint; Right : Int)  return Uint;

   function "*" (Left : Uint; Right : Uint) return Uint;
   function "*" (Left : Int;  Right : Uint) return Uint;
   function "*" (Left : Uint; Right : Int)  return Uint;

private
   Uint_Low_Bound  : constant := 600_000_000;
   Uint_High_Bound : constant := 2_099_999_999;

   type Uint is new Int range Uint_Low_Bound .. Uint_High_Bound;
   No_Uint : constant Uint := Uint (Uint_Low_Bound);
end Types;

--  types.adb

package body Types is
   function "+" (Left : Uint; Right : Uint) return Uint is
   begin return No_Uint; end "+";
   function "+" (Left : Int;  Right : Uint) return Uint is
   begin return No_Uint; end "+";
   function "+" (Left : Uint; Right : Int)  return Uint is
   begin return No_Uint; end "+";

   function "*" (Left : Uint; Right : Uint) return Uint is
   begin return No_Uint; end "+";
   function "*" (Left : Int;  Right : Uint) return Uint is
   begin return No_Uint; end "+";
   function "*" (Left : Uint; Right : Int)  return Uint is
   begin return No_Uint; end "+";
end Types;

--  types_gen.ads

generic
package Types_Gen is
   procedure Compute;
end Types_Gen;

--  types_gen.adb

with Types; use Types;

package body Types_Gen is
   procedure Compute is
      UI_Int_Value : Uint;
   begin
      UI_Int_Value := UI_Int_Value * 10 + 20;
   end Compute;
end Types_Gen;

--  types_inst.ads

with Types_Gen;

package Types_Inst is new Types_Gen;

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

$ gcc -c -gnatct types_inst.ads

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

2016-04-20  Hristian Kirtchev  <kirtc...@adacore.com>

        * sem_ch12.adb (Copy_Generic_Node): Handle the special
        qualification installed for universal literals that act as
        operands in binary or unary operators.  (Qualify_Operand): Mark
        the qualification to signal the instantiation mechanism how to
        handle global reference propagation.
        * sinfo.adb (Is_Qualified_Universal_Literal): New routine.
        (Set_Is_Qualified_Universal_Literal): New routine.
        * sinfo.ads New attribute Is_Qualified_Universal_Literal along
        with occurrences in nodes.
        (Is_Qualified_Universal_Literal):
        New routine along with pragma Inline.
        (Set_Is_Qualified_Universal_Literal): New routine along with
        pragma Inline.

Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb        (revision 235254)
+++ sem_ch12.adb        (working copy)
@@ -7293,6 +7293,20 @@
                      Set_Entity (New_N, Entity (Assoc));
                      Check_Private_View (N);
 
+                  --  The node is a reference to a global type and acts as the
+                  --  subtype mark of a qualified expression created in order
+                  --  to aid resolution of accidental overloading in instances.
+                  --  Since N is a reference to a type, the Associated_Node of
+                  --  N denotes an entity rather than another identifier. See
+                  --  Qualify_Universal_Operands for details.
+
+                  elsif Nkind (N) = N_Identifier
+                    and then Nkind (Parent (N)) = N_Qualified_Expression
+                    and then Subtype_Mark (Parent (N)) = N
+                    and then Is_Qualified_Universal_Literal (Parent (N))
+                  then
+                     Set_Entity (New_N, Assoc);
+
                   --  The name in the call may be a selected component if the
                   --  call has not been analyzed yet, as may be the case for
                   --  pre/post conditions in a generic unit.
@@ -13982,6 +13996,7 @@
             Loc  : constant Source_Ptr := Sloc (Opnd);
             Typ  : constant Entity_Id  := Etype (Actual);
             Mark : Node_Id;
+            Qual : Node_Id;
 
          begin
             --  Qualify the operand when it is of a universal type. Note that
@@ -14007,10 +14022,19 @@
                   Mark := Qualify_Type (Loc, Typ);
                end if;
 
-               Rewrite (Opnd,
+               Qual :=
                  Make_Qualified_Expression (Loc,
                    Subtype_Mark => Mark,
-                   Expression   => Relocate_Node (Opnd)));
+                   Expression   => Relocate_Node (Opnd));
+
+               --  Mark the qualification to distinguish it from other source
+               --  constructs and signal the instantiation mechanism that this
+               --  node requires special processing. See Copy_Generic_Node for
+               --  details.
+
+               Set_Is_Qualified_Universal_Literal (Qual);
+
+               Rewrite (Opnd, Qual);
             end if;
          end Qualify_Operand;
 
Index: sinfo.adb
===================================================================
--- sinfo.adb   (revision 235243)
+++ sinfo.adb   (working copy)
@@ -1982,6 +1982,14 @@
       return Flag7 (N);
    end Is_Protected_Subprogram_Body;
 
+   function Is_Qualified_Universal_Literal
+      (N : Node_Id) return Boolean is
+   begin
+      pragma Assert (False
+        or else NT (N).Nkind = N_Qualified_Expression);
+      return Flag4 (N);
+   end Is_Qualified_Universal_Literal;
+
    function Is_Static_Coextension
       (N : Node_Id) return Boolean is
    begin
@@ -5229,6 +5237,14 @@
       Set_Flag7 (N, Val);
    end Set_Is_Protected_Subprogram_Body;
 
+   procedure Set_Is_Qualified_Universal_Literal
+      (N : Node_Id; Val : Boolean := True) is
+   begin
+      pragma Assert (False
+        or else NT (N).Nkind = N_Qualified_Expression);
+      Set_Flag4 (N, Val);
+   end Set_Is_Qualified_Universal_Literal;
+
    procedure Set_Is_Static_Coextension
       (N : Node_Id; Val : Boolean := True) is
    begin
Index: sinfo.ads
===================================================================
--- sinfo.ads   (revision 235247)
+++ sinfo.ads   (working copy)
@@ -1710,6 +1710,12 @@
    --    handler to make sure that the associated protected object is unlocked
    --    when the subprogram completes.
 
+   --  Is_Qualified_Universal_Literal (Flag4-Sem)
+   --    Present in N_Qualified_Expression nodes. Set when the qualification is
+   --    converting a universal literal to a specific type. Such qualifiers aid
+   --    the resolution of accidental overloading of binary or unary operators
+   --    which may occur in instances.
+
    --  Is_Static_Coextension (Flag14-Sem)
    --    Present in N_Allocator nodes. Set if the allocator is a coextension
    --    of an object allocated on the stack rather than the heap.
@@ -4542,6 +4548,7 @@
       --  Subtype_Mark (Node4)
       --  Expression (Node3) expression or aggregate
       --  plus fields for expression
+      --  Is_Qualified_Universal_Literal (Flag4-Sem)
 
       --------------------
       -- 4.8  Allocator --
@@ -9399,6 +9406,9 @@
    function Is_Protected_Subprogram_Body
      (N : Node_Id) return Boolean;    -- Flag7
 
+   function Is_Qualified_Universal_Literal
+     (N : Node_Id) return Boolean;    -- Flag4
+
    function Is_Static_Coextension
      (N : Node_Id) return Boolean;    -- Flag14
 
@@ -10437,6 +10447,9 @@
    procedure Set_Is_Protected_Subprogram_Body
      (N : Node_Id; Val : Boolean := True);    -- Flag7
 
+   procedure Set_Is_Qualified_Universal_Literal
+     (N : Node_Id; Val : Boolean := True);    -- Flag4
+
    procedure Set_Is_Static_Coextension
      (N : Node_Id; Val : Boolean := True);    -- Flag14
 
@@ -12819,6 +12832,7 @@
    pragma Inline (Is_Power_Of_2_For_Shift);
    pragma Inline (Is_Prefixed_Call);
    pragma Inline (Is_Protected_Subprogram_Body);
+   pragma Inline (Is_Qualified_Universal_Literal);
    pragma Inline (Is_Static_Coextension);
    pragma Inline (Is_Static_Expression);
    pragma Inline (Is_Subprogram_Descriptor);
@@ -13160,6 +13174,7 @@
    pragma Inline (Set_Is_Power_Of_2_For_Shift);
    pragma Inline (Set_Is_Prefixed_Call);
    pragma Inline (Set_Is_Protected_Subprogram_Body);
+   pragma Inline (Set_Is_Qualified_Universal_Literal);
    pragma Inline (Set_Is_Static_Coextension);
    pragma Inline (Set_Is_Static_Expression);
    pragma Inline (Set_Is_Subprogram_Descriptor);

Reply via email to