From 4e8310b33c37d1eaaa4ffd08aca404a787252cf5 Mon Sep 17 00:00:00 2001 From: Eric Botcazou <ebotcazou@adacore.com> Date: Mon, 9 May 2022 08:56:27 +0200 Subject: [PATCH] [Ada] Do not freeze subprogram body without spec too early This fixes a small oddity whereby a subprogram body declared without a spec would be frozen before its entity is fully processed as an overloaded name. Now the latter step computes useful information, for example whether the body is a (late) primitive of a tagged type, which can be required during the freezing process. The change also adjusts Check_Dispatching_Operation accordingly. No functional changes. gcc/ada/ * sem_ch6.adb (Analyze_Subprogram_Body_Helper): For the case where there is no previous declaration, freeze the body entity only after it has been processed as a new overloaded name. Use Was_Expression_Function to recognize expression functions. * sem_disp.adb (Check_Dispatching_Operation): Do not require a body which is the last primitive to be frozen here. --- gcc/ada/sem_ch6.adb | 43 ++++++++++++++++++++++++------------------- gcc/ada/sem_disp.adb | 5 ++--- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 5a3692cc9145..cfe396ec1dd7 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -4389,25 +4389,15 @@ package body Sem_Ch6 is end if; -- A subprogram body should cause freezing of its own declaration, - -- but if there was no previous explicit declaration, then the - -- subprogram will get frozen too late (there may be code within - -- the body that depends on the subprogram having been frozen, - -- such as uses of extra formals), so we force it to be frozen - -- here. Same holds if the body and spec are compilation units. - -- Finally, if the return type is an anonymous access to protected - -- subprogram, it must be frozen before the body because its - -- expansion has generated an equivalent type that is used when - -- elaborating the body. - - -- An exception in the case of Ada 2012, AI05-177: The bodies - -- created for expression functions do not freeze. - - if No (Spec_Id) - and then Nkind (Original_Node (N)) /= N_Expression_Function + -- so, if the body and spec are compilation units, we must do it + -- manually here. Moreover, if the return type is anonymous access + -- to protected subprogram, it must be frozen before the body + -- because its expansion has generated an equivalent type that is + -- used when elaborating the body. + + if Present (Spec_Id) + and then Nkind (Parent (N)) = N_Compilation_Unit then - Freeze_Before (N, Body_Id); - - elsif Nkind (Parent (N)) = N_Compilation_Unit then Freeze_Before (N, Spec_Id); elsif Is_Access_Subprogram_Type (Etype (Body_Id)) then @@ -4775,13 +4765,28 @@ package body Sem_Ch6 is -- No warnings for expression functions - and then Nkind (Original_Node (N)) /= N_Expression_Function + and then (Nkind (N) /= N_Subprogram_Body + or else not Was_Expression_Function (N)) then Style.Body_With_No_Spec (N); end if; New_Overloaded_Entity (Body_Id); + -- A subprogram body should cause freezing of its own declaration, + -- but if there was no previous explicit declaration, then the + -- subprogram will get frozen too late (there may be code within + -- the body that depends on the subprogram having been frozen, + -- such as uses of extra formals), so we force it to be frozen here. + -- An exception in Ada 2012 is that the body created for expression + -- functions does not freeze. + + if Nkind (N) /= N_Subprogram_Body + or else not Was_Expression_Function (N) + then + Freeze_Before (N, Body_Id); + end if; + if Nkind (N) /= N_Subprogram_Body_Stub then Set_Acts_As_Spec (N); Generate_Definition (Body_Id); diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb index 79af10a81f05..d5893914f275 100644 --- a/gcc/ada/sem_disp.adb +++ b/gcc/ada/sem_disp.adb @@ -1516,11 +1516,10 @@ package body Sem_Disp is ("\spec should appear immediately after the type!", Subp); - elsif Is_Frozen (Subp) then + else -- The subprogram body declares a primitive operation. - -- If the subprogram is already frozen, we must update - -- its dispatching information explicitly here. The + -- We must update its dispatching information here. The -- information is taken from the overridden subprogram. -- We must also generate a cross-reference entry because -- references to other primitives were already created -- GitLab