[Ada] Illegal call on abstract operator
Arnaud Charlet
charlet@adacore.com
Mon Dec 12 11:53:00 GMT 2011
This patch fixes an obscure bug where gnat was failing to detect an illegal
call on an abstract operator. In particular, when the operands are of a
universal numeric type. This bug occurred only in Ada 2005 mode (and higher).
The following test should get an error:
illegal_abst_func.adb:5:24: cannot call abstract subprogram "+"
procedure Illegal_Abst_Func is
type My_Integer is new Integer;
function "+" (Left, Right: My_Integer) return My_Integer is abstract;
X : My_Integer := 2 + 2; -- Illegal!
begin
null;
end Illegal_Abst_Func;
Tested on x86_64-pc-linux-gnu, committed on trunk
2011-12-12 Bob Duff <duff@adacore.com>
* sem_res.adb (Resolve): Deal with the case where an abstract
operator is called with operands of type universal_integer.
-------------- next part --------------
Index: sem_res.adb
===================================================================
--- sem_res.adb (revision 182223)
+++ sem_res.adb (working copy)
@@ -1989,6 +1989,9 @@
end if;
Debug_A_Entry ("resolving ", N);
+ if Debug_Flag_V then
+ Write_Overloads (N);
+ end if;
if Comes_From_Source (N) then
if Is_Fixed_Point_Type (Typ) then
@@ -2033,6 +2036,11 @@
Get_First_Interp (N, I, It);
Interp_Loop : while Present (It.Typ) loop
+ if Debug_Flag_V then
+ Write_Str ("Interp: ");
+ Write_Interp (It);
+ end if;
+
-- We are only interested in interpretations that are compatible
-- with the expected type, any other interpretations are ignored.
@@ -2054,6 +2062,10 @@
and then Typ /= Universal_Real
and then Present (It.Abstract_Op)
then
+ if Debug_Flag_V then
+ Write_Line ("Skip.");
+ end if;
+
goto Continue;
end if;
@@ -2572,9 +2584,36 @@
Resolution_Failed;
return;
- -- Here we have an acceptable interpretation for the context
+ else
+ -- In Ada 2005, if we have something like "X : T := 2 + 2;", where
+ -- the "+" on T is abstract, and the operands are of universal type,
+ -- the above code will have (incorrectly) resolved the "+" to the
+ -- universal one in Standard. Therefore, we check for this case, and
+ -- give an error. We can't do this earlier, because it would cause
+ -- legal cases to get errors (when some other type has an abstract
+ -- "+").
- else
+ if Ada_Version >= Ada_2005 and then
+ Nkind (N) in N_Op and then
+ Is_Overloaded (N) and then
+ Is_Universal_Numeric_Type (Etype (Entity (N)))
+ then
+ Get_First_Interp (N, I, It);
+ while Present (It.Typ) loop
+ if Present (It.Abstract_Op) and then
+ Etype (It.Abstract_Op) = Typ
+ then
+ Error_Msg_NE
+ ("cannot call abstract subprogram &!", N, It.Abstract_Op);
+ return;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end if;
+
+ -- Here we have an acceptable interpretation for the context
+
-- Propagate type information and normalize tree for various
-- predefined operations. If the context only imposes a class of
-- types, rather than a specific type, propagate the actual type
More information about the Gcc-patches
mailing list