Patchwork [Ada] Resolving spurious ambiguities within instantiations

login
register
mail settings
Submitter Arnaud Charlet
Date Aug. 29, 2011, 1:31 p.m.
Message ID <20110829133122.GA29653@adacore.com>
Download mbox | patch
Permalink /patch/112049/
State New
Headers show

Comments

Arnaud Charlet - Aug. 29, 2011, 1:31 p.m.
The expanded code for an instantiation may contain apparent ambiguities when
two subprograms that are generic formals or that depend on formal types become
homonyms after formals are replaced with actuals. In some cases, the ambiguity
can be resolved by favoring the innermost interpretation, when both of them
are declared within the instance.
No small example available.

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

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

	* sem_ch8.adb (Find_Renamed_Entity): Within an instance, use scope
	depth of candidates to resolve a potentially spurious ambiguity between
	two visible subprograms.

Patch

Index: sem_ch8.adb
===================================================================
--- sem_ch8.adb	(revision 178191)
+++ sem_ch8.adb	(working copy)
@@ -4841,7 +4841,9 @@ 
             Set_Entity_Or_Discriminal (N, E);
 
             if Ada_Version >= Ada_2012
-              and then Nkind (Parent (N)) in N_Subexpr
+              and then
+                (Nkind (Parent (N)) in N_Subexpr
+                  or else Nkind (Parent (N)) = N_Object_Declaration)
             then
                Check_Implicit_Dereference (N, Etype (E));
             end if;
@@ -5531,13 +5533,30 @@ 
 
                      if Present (Inst) then
                         if Within (It.Nam, Inst) then
-                           return (It.Nam);
+                           if Within (Old_S, Inst) then
+
+                              --  Choose the innermost subprogram, which would
+                              --  have hidden the outer one in the generic.
+
+                              if Scope_Depth (It.Nam) <
+                                Scope_Depth (Old_S)
+                              then
+                                 return Old_S;
+
+                              else
+                                 return It.Nam;
+                              end if;
+                           end if;
+
                         elsif Within (Old_S, Inst) then
                            return (Old_S);
+
                         else
                            return Report_Overload;
                         end if;
 
+                     --  If not within an instance, ambiguity is real.
+
                      else
                         return Report_Overload;
                      end if;