[Ada] Spurious ambiguity in instances

Message ID 20110829082651.GA28515@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Aug. 29, 2011, 8:26 a.m.
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

The following must compile quietly:

function Cutdown (A1, B1, A2, B2 : Boolean) return Boolean is
     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
       with function Eq (X2, Y2 : T2) return Boolean;
     function G2 return Boolean;
  end G1;

  package body G1 is
     function G2 return Boolean is
         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 ("=");
  return I2;
 end Cutdown;

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

2011-08-29  Ed Schonberg  <schonberg@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)
                         All_Interp.Table (All_Interp.Last) :=