From: Eric Botcazou <[email protected]>
This occurs when the operator has a heterogeneous profile and the extension
is declared in the same scope as the type of a non-controlling parameter of
the operator, because Find_Dispatching_Type incorrectly returns this type.
gcc/ada/ChangeLog:
* exp_ch3.adb (Make_Controlling_Function_Wrappers): Manually set the
Has_Controlling_Result flag on the wrappers.
* sem_disp.ads (Override_Dispatching_Operation): Move to...
* sem_disp.adb (Override_Dispatching_Operation): ...here.
(Find_Dispatching_Type): Return the (controlling) result type for a
controlling function wrapper.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_ch3.adb | 1 +
gcc/ada/sem_disp.adb | 16 ++++++++++++++++
gcc/ada/sem_disp.ads | 8 --------
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 0e83b9b5854..73d37dea315 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -11693,6 +11693,7 @@ package body Exp_Ch3 is
Func_Id := Defining_Unit_Name (Specification (Func_Decl));
Mutate_Ekind (Func_Id, E_Function);
+ Set_Has_Controlling_Result (Func_Id);
Set_Is_Wrapper (Func_Id);
-- Corresponding_Spec will be set again to the same value during
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index dfcf384c7da..f69e7959ee5 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -96,6 +96,14 @@ package body Sem_Disp is
-- Check whether a primitive operation is inherited from an operation
-- declared in the visible part of its package.
+ procedure Override_Dispatching_Operation
+ (Tagged_Type : Entity_Id;
+ Prev_Op : Entity_Id;
+ New_Op : Entity_Id);
+ -- Replace an implicit dispatching operation of the type Tagged_Type
+ -- with an explicit one. Prev_Op is an inherited primitive operation which
+ -- is overridden by the explicit declaration of New_Op.
+
-------------------------------
-- Add_Dispatching_Operation --
-------------------------------
@@ -2433,6 +2441,14 @@ package body Sem_Disp is
return Empty;
end if;
+ -- Deal with controlling function wrappers
+
+ elsif Ekind (Subp) = E_Function
+ and then Has_Controlling_Result (Subp)
+ and then Is_Wrapper (Subp)
+ then
+ return Check_Controlling_Type (Etype (Subp), Subp);
+
-- General case
else
diff --git a/gcc/ada/sem_disp.ads b/gcc/ada/sem_disp.ads
index f1bf4c4ded9..31a5824bfbb 100644
--- a/gcc/ada/sem_disp.ads
+++ b/gcc/ada/sem_disp.ads
@@ -173,14 +173,6 @@ package Sem_Disp is
-- controlling operands are also indeterminate. Such a function call may
-- inherit a tag from an enclosing call.
- procedure Override_Dispatching_Operation
- (Tagged_Type : Entity_Id;
- Prev_Op : Entity_Id;
- New_Op : Entity_Id);
- -- Replace an implicit dispatching operation of the type Tagged_Type
- -- with an explicit one. Prev_Op is an inherited primitive operation which
- -- is overridden by the explicit declaration of New_Op.
-
procedure Propagate_Tag (Control : Node_Id; Actual : Node_Id);
-- If a function call given by Actual is tag-indeterminate, its controlling
-- argument is found in the context, given by Control: either from an
--
2.53.0