Commit 2d9c4206 by Javier Miranda Committed by Pierre-Marie de Rodat

[Ada] Spurious error on interface conversion under ZFP

The frontend reports an error under ZFP when performing the type
conversion of a tagged object to one of its covered interface types.

2018-09-26  Javier Miranda  <miranda@adacore.com>

gcc/ada/

	* exp_disp.adb (Expand_Interface_Conversion): No displacement of
	the pointer needed when the type of the operand is an interface
	type that maches the target type and we are compiling under
	configurable runtime. Adding also documentation explaining why
	this cannot be done when compiling with the full runtime.
	* exp_intr.adb: Update comment.

gcc/testsuite/

	* gnat.dg/interface8.adb, gnat.dg/interface8.ads: New testcase.

From-SVN: r264628
parent 9d951866
2018-09-26 Javier Miranda <miranda@adacore.com>
* exp_disp.adb (Expand_Interface_Conversion): No displacement of
the pointer needed when the type of the operand is an interface
type that maches the target type and we are compiling under
configurable runtime. Adding also documentation explaining why
this cannot be done when compiling with the full runtime.
* exp_intr.adb: Update comment.
2018-09-26 Hristian Kirtchev <kirtchev@adacore.com> 2018-09-26 Hristian Kirtchev <kirtchev@adacore.com>
* sem_ch5.adb (Wrap_Loop_Statement): Annotate as No_Return. * sem_ch5.adb (Wrap_Loop_Statement): Annotate as No_Return.
......
...@@ -1339,11 +1339,39 @@ package body Exp_Disp is ...@@ -1339,11 +1339,39 @@ package body Exp_Disp is
Opnd := Designated_Type (Opnd); Opnd := Designated_Type (Opnd);
end if; end if;
Opnd := Underlying_Record_Type (Opnd);
if not Is_Interface (Opnd) if not Is_Interface (Opnd)
and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True) and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
then then
return; return;
end if; end if;
-- When the type of the operand and the target interface type match,
-- it is generally safe to skip generating code to displace the
-- pointer to the object to reference the secondary dispatch table
-- associated with the target interface type. The exception to this
-- general rule is when the underlying object of the type conversion
-- is an object built by means of a dispatching constructor (since in
-- such case the expansion of the constructor call is a direct call
-- to an object primitive, i.e. without thunks, and the expansion of
-- the constructor call adds an explicit conversion to the target
-- interface type to force the displacement of the pointer to the
-- object to reference the corresponding secondary dispatch table
-- (cf. Make_DT and Expand_Dispatching_Constructor_Call)).
-- At this stage we cannot identify whether the underlying object is
-- a BIP object and hence we cannot skip generating the code to try
-- displacing the pointer to the object. However, under configurable
-- runtime it is safe to skip generating code to displace the pointer
-- to the object, because generic dispatching constructors are not
-- supported.
if Opnd = Iface_Typ
and then not RTE_Available (RE_Displace)
then
return;
end if;
end; end;
-- Evaluate if we can statically displace the pointer to the object -- Evaluate if we can statically displace the pointer to the object
......
...@@ -402,7 +402,10 @@ package body Exp_Intr is ...@@ -402,7 +402,10 @@ package body Exp_Intr is
end if; end if;
-- Rewrite and analyze the call to the instance as a class-wide -- Rewrite and analyze the call to the instance as a class-wide
-- conversion of the call to the actual constructor. -- conversion of the call to the actual constructor. When the result
-- type is a class-wide interface type this conversion is required to
-- force the displacement of the pointer to the object to reference the
-- corresponding dispatch table.
Rewrite (N, Convert_To (Result_Typ, Cnstr_Call)); Rewrite (N, Convert_To (Result_Typ, Cnstr_Call));
......
2018-09-26 Javier Miranda <miranda@adacore.com>
* gnat.dg/interface8.adb, gnat.dg/interface8.ads: New testcase.
2018-09-26 Ed Schonberg <schonberg@adacore.com> 2018-09-26 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/predicate2-containers.ads, * gnat.dg/predicate2-containers.ads,
......
-- { dg-do compile }
package body Interface8 is
function Get_Iface (This : Child) return not null access Iface'Class
is
begin
return This.Interface_1;
end;
end;
package Interface8 is
type Iface is interface;
type Root is abstract tagged null record;
type Child is new Root and Iface with record
Interface_1 : access Iface'Class;
end record;
function Get_Iface (This : Child) return not null access Iface'Class;
end;
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