aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2022-06-02 00:45:14 +0200
committerPierre-Marie de Rodat <derodat@adacore.com>2022-07-04 07:46:00 +0000
commit1f03b43fc7552fe105d33612b3b89b4f0b222798 (patch)
treef57e2570922b954aae109ca384b43db44a06eba4
parent4dab9bed7bd173e55fa44b9d8f4a01dfd8566553 (diff)
downloadgcc-1f03b43fc7552fe105d33612b3b89b4f0b222798.zip
gcc-1f03b43fc7552fe105d33612b3b89b4f0b222798.tar.gz
gcc-1f03b43fc7552fe105d33612b3b89b4f0b222798.tar.bz2
[Ada] Fix dispatching call to primitive function with controlling tagged result
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. gcc/ada/ * exp_disp.adb (Expand_Dispatching_Call): Fix detection of calls that are dispatching on tagged result.
-rw-r--r--gcc/ada/exp_disp.adb10
1 files changed, 8 insertions, 2 deletions
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 17043d1..3ac4b3b 100644
--- 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));