Within an instance, a spurious ambiguity may arise between a local subprogram
and the actual for a formal subprogram of the enclosing instance. Previously
the code only handled spurious ambiguities between two actuals or two local
subprograms.

The following must compile quietly:

---
function Cutdown (A1, B1, A2, B2 : Boolean) return Boolean is
  generic
     type T1 is private;
     A1, B1 : T1;
     type T2 is private;
     A2, B2 : T2;
     with function Eq (X1, Y1 : T1) return Boolean;
  package G1 is
     generic
       with function Eq (X2, Y2 : T2) return Boolean;
     function G2 return Boolean;
  end G1;

  package body G1 is
     function G2 return Boolean is
     begin
         return Eq (X1 => A1, Y1 => B1) and Eq (X2 => A2, Y2 => B2);
     end G2;
  end G1;

  package I1 is new G1 (Boolean, A1, B1, Boolean, A2, B2, "=");

  function I2 is new I1.G2 ("=");
 begin
  return I2;
 end Cutdown;

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

2011-08-29  Ed Schonberg  <schonb...@adacore.com>

        * sem_type.adb (Collect_Interps): Within an instance, collect a homonym
        that comes from an enclosing scope if it is not the renaming of an
        actual, to handle properly a spurious ambiguity in an instance.

Index: sem_type.adb
===================================================================
--- sem_type.adb        (revision 178155)
+++ sem_type.adb        (working copy)
@@ -621,10 +621,15 @@
 
                      --  A homograph in the same scope can occur within an
                      --  instantiation, the resulting ambiguity has to be
-                     --  resolved later.
+                     --  resolved later. The homographs may both be local
+                     --  functions or actuals, or may be declared at different
+                     --  levels within the instance. The renaming of an actual
+                     --  within the instance must not be included.
 
-                     if Scope (H) = Scope (Ent)
+                     if (Scope (H) = Scope (Ent)
+                           or else Scope (H) = Scope (Scope (Ent)))
                         and then In_Instance
+                        and then H /= Renamed_Entity (Ent)
                         and then not Is_Inherited_Operation (H)
                      then
                         All_Interp.Table (All_Interp.Last) :=

Reply via email to