[Ada] Resolving spurious ambiguities within instantiations

Message ID 20110829133122.GA29653@adacore.com
State New
Headers show

Commit Message

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.


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)
                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);
                            return Report_Overload;
                         end if;
+                     --  If not within an instance, ambiguity is real.
                         return Report_Overload;
                      end if;