From: Javier Miranda <[email protected]>
Adjust previous patch to improve the support for AI05-0151-1/08.
gcc/ada/ChangeLog:
* exp_attr.adb (Rewrite_Attribute_Proc_Call): Add new parameter
to calls to Create_Extra_Formals.
(Expand_N_Attribute_Reference): Ditto.
* exp_ch3.adb (Expand_Freeze_Record_Type): Ditto.
* exp_ch6.adb (Expand_Call_Helper): Ditto.
* exp_disp.adb (Expand_Dispatching_Call): Ditto.
* freeze.adb (Check_Itype): Ditto.
(Freeze_Expression): Ditto.
* sem_ch6.adb (Analyze_Subprogram_Body_Helper): Ditto.
(Create_Extra_Formals): Add new formal, and use it to determine
if the creation of the extra formals can be deferred. Add the
new parameter to calls to Create_Extra_Formals.
(Is_Unsupported_Extra_Actuals_Call): Adjust the code to improve
its performance when the result is known.
(Is_Unsupported_Extra_Formals_Entity): Ditto. Add new formal
* sem_ch6.ads (Create_Extra_Formals): Add new formal.
(Is_Unsupported_Extra_Formals_Entity): Ditto.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_attr.adb | 8 ++++----
gcc/ada/exp_ch3.adb | 4 ++--
gcc/ada/exp_ch6.adb | 8 ++++----
gcc/ada/exp_disp.adb | 2 +-
gcc/ada/freeze.adb | 4 ++--
gcc/ada/sem_ch6.adb | 41 +++++++++++++++++++++++++++--------------
gcc/ada/sem_ch6.ads | 19 ++++++++++++++++---
7 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 4bc6006454b..4eb0a6720f7 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -2171,7 +2171,7 @@ package body Exp_Attr is
-- that it has the necessary extra formals.
if not Is_Frozen (Pname) then
- Create_Extra_Formals (Pname);
+ Create_Extra_Formals (Pname, Related_Nod => N);
end if;
-- And now rewrite the call
@@ -2648,7 +2648,7 @@ package body Exp_Attr is
Set_Extra_Formal (Extra, Empty);
end if;
- Create_Extra_Formals (Subp_Typ);
+ Create_Extra_Formals (Subp_Typ, Related_Nod => N);
Set_Directly_Designated_Type (Typ, Subp_Typ);
end;
end if;
@@ -2679,13 +2679,13 @@ package body Exp_Attr is
if not Is_Frozen (Entity (Pref))
or else From_Limited_With (Etype (Entity (Pref)))
then
- Create_Extra_Formals (Entity (Pref));
+ Create_Extra_Formals (Entity (Pref), Related_Nod => N);
end if;
if not Is_Frozen (Btyp_DDT)
or else From_Limited_With (Etype (Btyp_DDT))
then
- Create_Extra_Formals (Btyp_DDT);
+ Create_Extra_Formals (Btyp_DDT, Related_Nod => N);
end if;
pragma Assert
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index e83b0e392db..c6ef88faca2 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6592,7 +6592,7 @@ package body Exp_Ch3 is
Elmt := First_Elmt (Primitive_Operations (Typ));
while Present (Elmt) loop
- Create_Extra_Formals (Node (Elmt));
+ Create_Extra_Formals (Node (Elmt), Related_Nod => N);
Next_Elmt (Elmt);
end loop;
@@ -6609,7 +6609,7 @@ package body Exp_Ch3 is
and then Find_Dispatching_Type (E) = Typ
and then not Contains (Primitive_Operations (Typ), E)
then
- Create_Extra_Formals (E);
+ Create_Extra_Formals (E, Related_Nod => N);
end if;
Next_Entity (E);
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 19812ad7cc1..a7b694270d8 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -4716,7 +4716,7 @@ package body Exp_Ch6 is
-- of init procs were added when they were built.
if not Extra_Formals_Known (Subp) then
- Create_Extra_Formals (Subp);
+ Create_Extra_Formals (Subp, Related_Nod => Call_Node);
-- If the previous call to Create_Extra_Formals could not add the
-- extra formals, then we must defer adding the extra actuals of
@@ -4785,7 +4785,7 @@ package body Exp_Ch6 is
and then Extra_Formals_Known (Subp)
and then Present (Extra_Formals (Subp))
then
- Create_Extra_Actuals (N);
+ Create_Extra_Actuals (Call_Node);
-- Mark the call as an expanded build-in-place call; required
-- to avoid adding the extra formals twice.
@@ -5228,10 +5228,10 @@ package body Exp_Ch6 is
null;
elsif not Defer_Extra_Actuals then
- Create_Extra_Formals (Subp);
+ Create_Extra_Formals (Subp, Related_Nod => Call_Node);
if Extra_Formals_Known (Subp) then
- Create_Extra_Actuals (N);
+ Create_Extra_Actuals (Call_Node);
end if;
end if;
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 1c09e204275..0f6bef17ecf 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -971,7 +971,7 @@ package body Exp_Disp is
pragma Assert (Is_Frozen (Typ));
if Extra_Formals_Known (Subp) then
- Create_Extra_Formals (Subp_Typ);
+ Create_Extra_Formals (Subp_Typ, Related_Nod => Call_Node);
-- Extra formals were previously deferred
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 2ebffff7a5f..f383b57ae23 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -5180,7 +5180,7 @@ package body Freeze is
and then Convention (Desig) /= Convention_Protected
then
Set_Is_Frozen (Desig);
- Create_Extra_Formals (Desig);
+ Create_Extra_Formals (Desig, Related_Nod => Rec);
end if;
end Check_Itype;
@@ -8786,7 +8786,7 @@ package body Freeze is
and then Nkind (Parent (N)) = N_Function_Call
and then not Has_Foreign_Convention (Nam)
then
- Create_Extra_Formals (Nam);
+ Create_Extra_Formals (Nam, Related_Nod => N);
end if;
when others =>
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 55c5e026ea0..a427c7a86b0 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -3864,7 +3864,7 @@ package body Sem_Ch6 is
-- Separate spec is not present
if No (Spec_Id) then
- Create_Extra_Formals (Body_Id);
+ Create_Extra_Formals (Body_Id, Related_Nod => N);
-- Separate spec is present; deal with freezing issues
@@ -3883,7 +3883,7 @@ package body Sem_Ch6 is
and then Is_Build_In_Place_Function (Spec_Id)
and then not Has_BIP_Formals (Spec_Id)
then
- Create_Extra_Formals (Spec_Id);
+ Create_Extra_Formals (Spec_Id, Related_Nod => N);
pragma Assert (not Expander_Active
or else Extra_Formals_Known (Spec_Id));
Compute_Returns_By_Ref (Spec_Id);
@@ -3933,7 +3933,7 @@ package body Sem_Ch6 is
and then Serious_Errors_Detected = 0
then
Set_Has_Delayed_Freeze (Spec_Id);
- Create_Extra_Formals (Spec_Id);
+ Create_Extra_Formals (Spec_Id, Related_Nod => N);
Freeze_Before (N, Spec_Id);
end if;
end if;
@@ -8550,7 +8550,10 @@ package body Sem_Ch6 is
-- Create_Extra_Formals --
--------------------------
- procedure Create_Extra_Formals (E : Entity_Id) is
+ procedure Create_Extra_Formals
+ (E : Entity_Id;
+ Related_Nod : Node_Id := Empty)
+ is
First_Extra : Entity_Id := Empty;
Formal : Entity_Id;
Last_Extra : Entity_Id := Empty;
@@ -8824,7 +8827,8 @@ package body Sem_Ch6 is
use Deferred_Extra_Formals_Support;
Can_Be_Deferred : constant Boolean :=
- not Is_Unsupported_Extra_Formals_Entity (E);
+ not Is_Unsupported_Extra_Formals_Entity (E,
+ Related_Nod);
Alias_Formal : Entity_Id := Empty;
Alias_Subp : Entity_Id := Empty;
Formal_Type : Entity_Id;
@@ -8907,7 +8911,7 @@ package body Sem_Ch6 is
pragma Assert (Is_Generic_Instance (E)
= Is_Generic_Instance (Ultimate_Alias (E)));
- Create_Extra_Formals (Ultimate_Alias (E));
+ Create_Extra_Formals (Ultimate_Alias (E), Related_Nod);
pragma Assert (not Expander_Active
or else Extra_Formals_Known (Ultimate_Alias (E)));
@@ -9080,7 +9084,7 @@ package body Sem_Ch6 is
-- function Parent_Subprogram).
if Ultimate_Alias (Parent_Subp) /= Ref_E then
- Create_Extra_Formals (Parent_Subp);
+ Create_Extra_Formals (Parent_Subp, Related_Nod);
end if;
Parent_Formal := First_Formal (Parent_Subp);
@@ -9115,7 +9119,7 @@ package body Sem_Ch6 is
-- Ensure that the ultimate alias has all its extra formals
elsif Present (Alias_Subp) then
- Create_Extra_Formals (Alias_Subp);
+ Create_Extra_Formals (Alias_Subp, Related_Nod);
Alias_Formal := First_Formal (Alias_Subp);
end if;
@@ -13114,8 +13118,8 @@ package body Sem_Ch6 is
-- formals of the enclosing scope are available before
-- adding the extra actuals of this call.
- Create_Extra_Formals (Scop_Id);
- Create_Extra_Formals (Call_Id);
+ Create_Extra_Formals (Scop_Id, Related_Nod => Call_Node);
+ Create_Extra_Formals (Call_Id, Related_Nod => Call_Node);
pragma Assert (Extra_Formals_Known (Scop_Id));
pragma Assert (Extra_Formals_Known (Call_Id));
@@ -13288,8 +13292,11 @@ package body Sem_Ch6 is
is
Comp_Unit : constant Entity_Id :=
Cunit_Entity (Get_Source_Unit (Call_Node));
+
begin
- return not Underlying_Types_Available (Id)
+ return Expander_Active
+ and then not Extra_Formals_Known (Id)
+ and then not Underlying_Types_Available (Id)
and then Is_Compilation_Unit (Comp_Unit)
and then Ekind (Comp_Unit) in E_Package
| E_Package_Body
@@ -13308,12 +13315,18 @@ package body Sem_Ch6 is
-- (AI05-0151-1/08).
function Is_Unsupported_Extra_Formals_Entity
- (Id : Entity_Id) return Boolean
+ (Id : Entity_Id;
+ Related_Nod : Node_Id := Empty) return Boolean
is
+ Ref_Node : constant Node_Id := (if Present (Related_Nod) then
+ Related_Nod
+ else Id);
Comp_Unit : constant Entity_Id :=
- Cunit_Entity (Get_Source_Unit (Id));
+ Cunit_Entity (Get_Source_Unit (Ref_Node));
begin
- return not Underlying_Types_Available (Id)
+ return Expander_Active
+ and then not Extra_Formals_Known (Id)
+ and then not Underlying_Types_Available (Id)
and then Is_Compilation_Unit (Comp_Unit)
and then Ekind (Comp_Unit) in E_Package_Body
| E_Subprogram_Body;
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads
index 4ef5b654bb0..3c6de705097 100644
--- a/gcc/ada/sem_ch6.ads
+++ b/gcc/ada/sem_ch6.ads
@@ -160,13 +160,23 @@ package Sem_Ch6 is
-- True when this is a check against a formal access-to-subprogram type,
-- indicating that mapping of types is needed.
- procedure Create_Extra_Formals (E : Entity_Id);
+ procedure Create_Extra_Formals
+ (E : Entity_Id;
+ Related_Nod : Node_Id := Empty);
-- For each parameter of a subprogram or entry that requires an additional
-- formal (such as for access parameters and indefinite discriminated
-- parameters), creates the appropriate formal and attach it to its
-- associated parameter. Each extra formal will also be appended to
-- the end of Subp's parameter list (with each subsequent extra formal
-- being attached to the preceding extra formal).
+ --
+ -- Related_Nod is the node motivating the frontend call to create the
+ -- extra formals; it is not passed when the node causing the call is E
+ -- (for example, as part of freezing E). Related_Nod provides the context
+ -- where the extra formals are created, and it is used to determine if
+ -- the creation of the extra formals can be deferred when the underlying
+ -- type of some formal (or its return type) is not available, and thus
+ -- improve the support for AI05-0151-1/08.
function Extra_Formals_Match_OK
(E : Entity_Id;
@@ -432,12 +442,15 @@ package Sem_Ch6 is
-- been registered to defer the addition of its extra formals.
function Is_Unsupported_Extra_Formals_Entity
- (Id : Entity_Id) return Boolean;
+ (Id : Entity_Id;
+ Related_Nod : Node_Id := Empty) return Boolean;
-- Id is a subprogram, subprogram type, or entry. Return True if Id is
-- unsupported for deferring the addition of its extra formals; that is,
-- it is defined in a compilation unit that is a package body or a
-- subprogram body, and the underlying type of some of its parameters
- -- or result type is not available.
+ -- or result type is not available. Related_Nod is the node where this
+ -- check is performed (it is generally a subprogram call); if it is not
+ -- available then the location of entity Id is used as its related node.
--
-- The context for this case is an unsupported case of AI05-0151-1/08
-- that allows incomplete tagged types as parameter and result types.
--
2.43.0