Commit 0e0eecec by Ed Schonberg Committed by Arnaud Charlet

sem_ch4.adb (Remove_Abstract_Operations): Do not apply preference rule…

sem_ch4.adb (Remove_Abstract_Operations): Do not apply preference rule prematurely when operands are universal...

2005-12-05  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch4.adb (Remove_Abstract_Operations): Do not apply preference
	rule prematurely when operands are universal, remaining ambiguities
	will be removed during resolution.
	Code cleanup.

	* sem_type.adb (Disambiguate): In Ada95 mode, discard interpretations
	that are Ada 2005 functions.
	(Has_Abstract_Interpretation): Subsidiary to
	Remove_Conversions, to remove ambiguities caused by abstract operations
	on numeric types when operands are universal.

From-SVN: r108302
parent b5bd964f
...@@ -4379,9 +4379,9 @@ package body Sem_Ch4 is ...@@ -4379,9 +4379,9 @@ package body Sem_Ch4 is
-- If either operand is a junk operand (e.g. package name), then -- If either operand is a junk operand (e.g. package name), then
-- post appropriate error messages, but do not complain further. -- post appropriate error messages, but do not complain further.
-- Note that the use of OR in this test instead of OR ELSE -- Note that the use of OR in this test instead of OR ELSE is
-- is quite deliberate, we may as well check both operands -- quite deliberate, we may as well check both operands in the
-- in the binary operator case. -- binary operator case.
elsif Junk_Operand (R) elsif Junk_Operand (R)
or (Nkind (N) in N_Binary_Op and then Junk_Operand (L)) or (Nkind (N) in N_Binary_Op and then Junk_Operand (L))
...@@ -4389,10 +4389,10 @@ package body Sem_Ch4 is ...@@ -4389,10 +4389,10 @@ package body Sem_Ch4 is
return; return;
-- If we have a logical operator, one of whose operands is -- If we have a logical operator, one of whose operands is
-- Boolean, then we know that the other operand cannot resolve -- Boolean, then we know that the other operand cannot resolve to
-- to Boolean (since we got no interpretations), but in that -- Boolean (since we got no interpretations), but in that case we
-- case we pretty much know that the other operand should be -- pretty much know that the other operand should be Boolean, so
-- Boolean, so resolve it that way (generating an error) -- resolve it that way (generating an error)
elsif Nkind (N) = N_Op_And elsif Nkind (N) = N_Op_And
or else or else
...@@ -4476,10 +4476,10 @@ package body Sem_Ch4 is ...@@ -4476,10 +4476,10 @@ package body Sem_Ch4 is
return; return;
end if; end if;
-- If we fall through then just give general message. Note -- If we fall through then just give general message. Note that in
-- that in the following messages, if the operand is overloaded -- the following messages, if the operand is overloaded we choose
-- we choose an arbitrary type to complain about, but that is -- an arbitrary type to complain about, but that is probably more
-- probably more useful than not giving a type at all. -- useful than not giving a type at all.
if Nkind (N) in N_Unary_Op then if Nkind (N) in N_Unary_Op then
Error_Msg_Node_2 := Etype (R); Error_Msg_Node_2 := Etype (R);
...@@ -4543,23 +4543,21 @@ package body Sem_Ch4 is ...@@ -4543,23 +4543,21 @@ package body Sem_Ch4 is
It : Interp; It : Interp;
Abstract_Op : Entity_Id := Empty; Abstract_Op : Entity_Id := Empty;
-- AI-310: If overloaded, remove abstract non-dispatching -- AI-310: If overloaded, remove abstract non-dispatching operations. We
-- operations. We activate this if either extensions are -- activate this if either extensions are enabled, or if the abstract
-- enabled, or if the abstract operation in question comes -- operation in question comes from a predefined file. This latter test
-- from a predefined file. This latter test allows us to -- allows us to use abstract to make operations invisible to users. In
-- use abstract to make operations invisible to users. In -- particular, if type Address is non-private and abstract subprograms
-- particular, if type Address is non-private and abstract -- are used to hide its operators, they will be truly hidden.
-- subprograms are used to hide its operators, they will be
-- truly hidden.
type Operand_Position is (First_Op, Second_Op); type Operand_Position is (First_Op, Second_Op);
Univ_Type : constant Entity_Id := Universal_Interpretation (N); Univ_Type : constant Entity_Id := Universal_Interpretation (N);
procedure Remove_Address_Interpretations (Op : Operand_Position); procedure Remove_Address_Interpretations (Op : Operand_Position);
-- Ambiguities may arise when the operands are literal and the -- Ambiguities may arise when the operands are literal and the address
-- address operations in s-auxdec are visible. In that case, remove -- operations in s-auxdec are visible. In that case, remove the
-- the interpretation of a literal as Address, to retain the semantics -- interpretation of a literal as Address, to retain the semantics of
-- of Address as a private type. -- Address as a private type.
------------------------------------ ------------------------------------
-- Remove_Address_Interpretations -- -- Remove_Address_Interpretations --
...@@ -4627,10 +4625,11 @@ package body Sem_Ch4 is ...@@ -4627,10 +4625,11 @@ package body Sem_Ch4 is
Present (Universal_Interpretation (Left_Opnd (N))); Present (Universal_Interpretation (Left_Opnd (N)));
begin begin
if U1 and then not U2 then if U1 then
Remove_Address_Interpretations (Second_Op); Remove_Address_Interpretations (Second_Op);
end if;
elsif U2 and then not U1 then if U2 then
Remove_Address_Interpretations (First_Op); Remove_Address_Interpretations (First_Op);
end if; end if;
...@@ -4655,15 +4654,17 @@ package body Sem_Ch4 is ...@@ -4655,15 +4654,17 @@ package body Sem_Ch4 is
and then Present (Univ_Type) and then Present (Univ_Type)
then then
-- If both operands have a universal interpretation, -- If both operands have a universal interpretation,
-- select the predefined operator and discard others. -- it is still necessary to remove interpretations that
-- yield Address. Any remaining ambiguities will be
-- removed in Disambiguate.
Get_First_Interp (N, I, It); Get_First_Interp (N, I, It);
while Present (It.Nam) loop while Present (It.Nam) loop
if Scope (It.Nam) = Standard_Standard then if Is_Descendent_Of_Address (It.Typ) then
Set_Etype (N, Univ_Type); Remove_Interp (I);
elsif not Is_Type (It.Nam) then
Set_Entity (N, It.Nam); Set_Entity (N, It.Nam);
Set_Is_Overloaded (N, False);
exit;
end if; end if;
Get_Next_Interp (I, It); Get_Next_Interp (I, It);
...@@ -4690,10 +4691,11 @@ package body Sem_Ch4 is ...@@ -4690,10 +4691,11 @@ package body Sem_Ch4 is
Present (Universal_Interpretation (Next (Arg1))); Present (Universal_Interpretation (Next (Arg1)));
begin begin
if U1 and then not U2 then if U1 then
Remove_Address_Interpretations (First_Op); Remove_Address_Interpretations (First_Op);
end if;
elsif U2 and then not U1 then if U2 then
Remove_Address_Interpretations (Second_Op); Remove_Address_Interpretations (Second_Op);
end if; end if;
......
...@@ -1019,6 +1019,10 @@ package body Sem_Type is ...@@ -1019,6 +1019,10 @@ package body Sem_Type is
-- pathology in the other direction with calls whose multiple overloaded -- pathology in the other direction with calls whose multiple overloaded
-- actuals make them truly unresolvable. -- actuals make them truly unresolvable.
-- The new rules concerning abstract operations create additional
-- for special handling of expressions with universal operands, See
-- comments to Has_Abstract_Interpretation below.
------------------------ ------------------------
-- In_Generic_Actual -- -- In_Generic_Actual --
------------------------ ------------------------
...@@ -1105,12 +1109,43 @@ package body Sem_Type is ...@@ -1105,12 +1109,43 @@ package body Sem_Type is
Act1 : Node_Id; Act1 : Node_Id;
Act2 : Node_Id; Act2 : Node_Id;
function Has_Abstract_Interpretation (N : Node_Id) return Boolean;
-- If an operation has universal operands the universal operation
-- is present among its interpretations. If there is an abstract
-- interpretation for the operator, with a numeric result, this
-- interpretation was already removed in sem_ch4, but the universal
-- one is still visible. We must rescan the list of operators and
-- remove the universal interpretation to resolve the ambiguity.
---------------------------------
-- Has_Abstract_Interpretation --
---------------------------------
function Has_Abstract_Interpretation (N : Node_Id) return Boolean is
E : Entity_Id;
begin
E := Current_Entity (N);
while Present (E) loop
if Is_Abstract (E)
and then Is_Numeric_Type (Etype (E))
then
return True;
else
E := Homonym (E);
end if;
end loop;
return False;
end Has_Abstract_Interpretation;
-- Start of processing for Remove_ConversionsMino
begin begin
It1 := No_Interp; It1 := No_Interp;
Get_First_Interp (N, I, It); Get_First_Interp (N, I, It);
while Present (It.Typ) loop while Present (It.Typ) loop
if not Is_Overloadable (It.Nam) then if not Is_Overloadable (It.Nam) then
return No_Interp; return No_Interp;
end if; end if;
...@@ -1185,6 +1220,19 @@ package body Sem_Type is ...@@ -1185,6 +1220,19 @@ package body Sem_Type is
else else
It1 := It; It1 := It;
end if; end if;
elsif Nkind (Act1) in N_Op
and then Is_Overloaded (Act1)
and then Present (Universal_Interpretation (Act1))
and then Is_Numeric_Type (Etype (F1))
and then Ada_Version >= Ada_05
and then Has_Abstract_Interpretation (Act1)
then
if It = Disambiguate.It1 then
return Disambiguate.It2;
elsif It = Disambiguate.It2 then
return Disambiguate.It1;
end if;
end if; end if;
end if; end if;
...@@ -1267,6 +1315,19 @@ package body Sem_Type is ...@@ -1267,6 +1315,19 @@ package body Sem_Type is
It2 := It; It2 := It;
Nam2 := It.Nam; Nam2 := It.Nam;
if Ada_Version < Ada_05 then
-- Check whether one of the entities is an Ada 2005 entity and we are
-- operating in an earlier mode, in which case we discard the Ada
-- 2005 entity, so that we get proper Ada 95 overload resolution.
if Is_Ada_2005 (Nam1) then
return It2;
elsif Is_Ada_2005 (Nam2) then
return It1;
end if;
end if;
-- If the context is universal, the predefined operator is preferred. -- If the context is universal, the predefined operator is preferred.
-- This includes bounds in numeric type declarations, and expressions -- This includes bounds in numeric type declarations, and expressions
-- in type conversions. If no interpretation yields a universal type, -- in type conversions. If no interpretation yields a universal type,
...@@ -1912,6 +1973,7 @@ package body Sem_Type is ...@@ -1912,6 +1973,7 @@ package body Sem_Type is
if Present (Interface_List (Parent (Target_Typ))) then if Present (Interface_List (Parent (Target_Typ))) then
declare declare
AI : Node_Id; AI : Node_Id;
begin begin
AI := First (Interface_List (Parent (Target_Typ))); AI := First (Interface_List (Parent (Target_Typ)));
while Present (AI) loop while Present (AI) loop
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment