From: Javier Miranda <mira...@adacore.com> 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