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.
Tested on x86_64-pc-linux-gnu, committed on trunk
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.
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
--- 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
--- 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