When a dispatching call is made to a primitive function with a controlling
tagged result, the call is dispatching on result and thus must return the
class-wide type of the tagged type to accommodate all possible results.
This was ensured by Expand_Dispatching_Call only in the common case where
the result type is the type of the controlling argument, which does not
cover the case of a primitive function inherited from an ancestor type.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* exp_disp.adb (Expand_Dispatching_Call): Fix detection of calls
that are dispatching on tagged result.
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -896,8 +896,14 @@ package body Exp_Disp is
Copy_Strub_Mode (Subp_Typ, Subp);
Set_Convention (Subp_Typ, Convention (Subp));
- if Etype (Subp) = Typ then
- Set_Etype (Subp_Typ, CW_Typ);
+ -- If this is a function and it has a controlling tagged result, then
+ -- the call is dispatching on result and returns the class-wide type.
+
+ if Ekind (Subp) = E_Function
+ and then Has_Controlling_Result (Subp)
+ and then Is_Tagged_Type (Etype (Subp))
+ then
+ Set_Etype (Subp_Typ, Class_Wide_Type (Etype (Subp)));
Set_Returns_By_Ref (Subp_Typ, True);
else
Set_Etype (Subp_Typ, Etype (Subp));