[Ada] Wrong management of private types covering interfaces
Arnaud Charlet
charlet@adacore.com
Fri Jul 10 09:12:00 GMT 2009
The frontend does not handle well conversions of access types
whose designated type is a private type covering interfaces.
In such case, after an interface conversion, a dispatching
call may call a wrong primitive or generate constraint error.
After this patch the following test compiles without errors
and generates the correct output:
package Pkg_1 is
type I1 is interface;
type I2 is interface and I1;
procedure Wrong_Prim (Self : access I2) is abstract;
type I3 is interface and I2;
procedure Do_Test (Self : access I3) is abstract;
type DT_1 is new I1 with null record;
procedure Dummy (Self : DT_1) is null;
type DT_2 is new DT_1 and I2 with null record;
procedure Wrong_Prim (Self : access DT_2);
type I3_Access is access all I3'Class;
end;
with Pkg_1;
package Pkg_2 is
type DT_3 is new Pkg_1.I3 with private;
procedure Do_Test (Self : access DT_3);
type DT_3_Access is access all DT_3'Class;
function Create return DT_3_Access;
private
type DT_3 is new Pkg_1.DT_2 and Pkg_1.I3 with null record;
end;
with Ada.Text_IO;
package body Pkg_1 is
procedure Wrong_Prim (Self : access DT_2) is
begin
Ada.Text_IO.Put_Line ("FAILED");
end;
end;
with Ada.Text_IO;
package body Pkg_2 is
function Create return DT_3_Access is
begin
return new DT_3;
end;
procedure Do_Test (Self : access DT_3) is
begin
Ada.Text_IO.Put_Line ("PASSED");
end;
end;
with Pkg_1, Pkg_2;
procedure Main is
Ptr : Pkg_1.I3_Access;
begin
Ptr := Pkg_1.I3_Access (Pkg_2.Create); -- test
Ptr.Do_Test;
Ptr.all.Do_Test;
Pkg_1.I3_Access (Ptr).Do_Test;
Pkg_2.DT_3_Access (Ptr).Do_Test;
end;
Command: gnatmake -gnat05 main.adb
Output:
PASSED
PASSED
PASSED
PASSED
Tested on x86_64-pc-linux-gnu, committed on trunk
2009-07-10 Javier Miranda <miranda@adacore.com>
* exp_util.adb (Find_Interface_Tag): Reorder processing of incoming
Typ argument to ensure proper management of access types.
-------------- next part --------------
Index: exp_util.adb
===================================================================
--- exp_util.adb (revision 149458)
+++ exp_util.adb (working copy)
@@ -1600,28 +1600,24 @@
begin
pragma Assert (Is_Interface (Iface));
- -- Handle private types
-
- if Has_Private_Declaration (Typ)
- and then Present (Full_View (Typ))
- then
- Typ := Full_View (Typ);
- end if;
-
-- Handle access types
if Is_Access_Type (Typ) then
Typ := Directly_Designated_Type (Typ);
end if;
- -- Handle task and protected types implementing interfaces
+ -- Handle class-wide types
- if Is_Concurrent_Type (Typ) then
- Typ := Corresponding_Record_Type (Typ);
+ if Is_Class_Wide_Type (Typ) then
+ Typ := Root_Type (Typ);
end if;
- if Is_Class_Wide_Type (Typ) then
- Typ := Etype (Typ);
+ -- Handle private types
+
+ if Has_Private_Declaration (Typ)
+ and then Present (Full_View (Typ))
+ then
+ Typ := Full_View (Typ);
end if;
-- Handle entities from the limited view
@@ -1631,6 +1627,12 @@
Typ := Non_Limited_View (Typ);
end if;
+ -- Handle task and protected types implementing interfaces
+
+ if Is_Concurrent_Type (Typ) then
+ Typ := Corresponding_Record_Type (Typ);
+ end if;
+
Find_Tag (Typ);
pragma Assert (Found);
return AI_Tag;
More information about the Gcc-patches
mailing list