aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch6.adb
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/ada/sem_ch6.adb
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-e252b51ccde010cbd2a146485d8045103cd99533.zip
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/ada/sem_ch6.adb')
-rw-r--r--gcc/ada/sem_ch6.adb635
1 files changed, 396 insertions, 239 deletions
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 7bab772..304dc19 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -23,70 +23,73 @@
-- --
------------------------------------------------------------------------------
-with Aspects; use Aspects;
-with Atree; use Atree;
-with Checks; use Checks;
-with Contracts; use Contracts;
-with Debug; use Debug;
-with Einfo; use Einfo;
-with Elists; use Elists;
-with Errout; use Errout;
-with Expander; use Expander;
-with Exp_Ch3; use Exp_Ch3;
-with Exp_Ch6; use Exp_Ch6;
-with Exp_Ch7; use Exp_Ch7;
-with Exp_Ch9; use Exp_Ch9;
-with Exp_Dbug; use Exp_Dbug;
-with Exp_Tss; use Exp_Tss;
-with Exp_Util; use Exp_Util;
-with Freeze; use Freeze;
-with Ghost; use Ghost;
-with Inline; use Inline;
-with Itypes; use Itypes;
-with Lib.Xref; use Lib.Xref;
-with Layout; use Layout;
-with Namet; use Namet;
-with Lib; use Lib;
-with Nlists; use Nlists;
-with Nmake; use Nmake;
-with Opt; use Opt;
-with Output; use Output;
-with Restrict; use Restrict;
-with Rtsfind; use Rtsfind;
-with Sem; use Sem;
-with Sem_Aux; use Sem_Aux;
-with Sem_Cat; use Sem_Cat;
-with Sem_Ch3; use Sem_Ch3;
-with Sem_Ch4; use Sem_Ch4;
-with Sem_Ch5; use Sem_Ch5;
-with Sem_Ch8; use Sem_Ch8;
-with Sem_Ch9; use Sem_Ch9;
-with Sem_Ch10; use Sem_Ch10;
-with Sem_Ch12; use Sem_Ch12;
-with Sem_Ch13; use Sem_Ch13;
-with Sem_Dim; use Sem_Dim;
-with Sem_Disp; use Sem_Disp;
-with Sem_Dist; use Sem_Dist;
-with Sem_Elim; use Sem_Elim;
-with Sem_Eval; use Sem_Eval;
-with Sem_Mech; use Sem_Mech;
-with Sem_Prag; use Sem_Prag;
-with Sem_Res; use Sem_Res;
-with Sem_Util; use Sem_Util;
-with Sem_Type; use Sem_Type;
-with Sem_Warn; use Sem_Warn;
-with Sinput; use Sinput;
-with Stand; use Stand;
-with Sinfo; use Sinfo;
-with Sinfo.CN; use Sinfo.CN;
-with Snames; use Snames;
-with Stringt; use Stringt;
+with Aspects; use Aspects;
+with Atree; use Atree;
+with Checks; use Checks;
+with Contracts; use Contracts;
+with Debug; use Debug;
+with Einfo; use Einfo;
+with Einfo.Entities; use Einfo.Entities;
+with Einfo.Utils; use Einfo.Utils;
+with Elists; use Elists;
+with Errout; use Errout;
+with Expander; use Expander;
+with Exp_Ch3; use Exp_Ch3;
+with Exp_Ch6; use Exp_Ch6;
+with Exp_Ch9; use Exp_Ch9;
+with Exp_Dbug; use Exp_Dbug;
+with Exp_Tss; use Exp_Tss;
+with Exp_Util; use Exp_Util;
+with Freeze; use Freeze;
+with Ghost; use Ghost;
+with Inline; use Inline;
+with Itypes; use Itypes;
+with Lib.Xref; use Lib.Xref;
+with Layout; use Layout;
+with Namet; use Namet;
+with Lib; use Lib;
+with Nlists; use Nlists;
+with Nmake; use Nmake;
+with Opt; use Opt;
+with Output; use Output;
+with Restrict; use Restrict;
+with Rtsfind; use Rtsfind;
+with Sem; use Sem;
+with Sem_Aux; use Sem_Aux;
+with Sem_Cat; use Sem_Cat;
+with Sem_Ch3; use Sem_Ch3;
+with Sem_Ch4; use Sem_Ch4;
+with Sem_Ch5; use Sem_Ch5;
+with Sem_Ch8; use Sem_Ch8;
+with Sem_Ch9; use Sem_Ch9;
+with Sem_Ch10; use Sem_Ch10;
+with Sem_Ch12; use Sem_Ch12;
+with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
+with Sem_Disp; use Sem_Disp;
+with Sem_Dist; use Sem_Dist;
+with Sem_Elim; use Sem_Elim;
+with Sem_Eval; use Sem_Eval;
+with Sem_Mech; use Sem_Mech;
+with Sem_Prag; use Sem_Prag;
+with Sem_Res; use Sem_Res;
+with Sem_Util; use Sem_Util;
+with Sem_Type; use Sem_Type;
+with Sem_Warn; use Sem_Warn;
+with Sinput; use Sinput;
+with Stand; use Stand;
+with Sinfo; use Sinfo;
+with Sinfo.Nodes; use Sinfo.Nodes;
+with Sinfo.Utils; use Sinfo.Utils;
+with Sinfo.CN; use Sinfo.CN;
+with Snames; use Snames;
+with Stringt; use Stringt;
with Style;
-with Stylesw; use Stylesw;
-with Tbuild; use Tbuild;
-with Uintp; use Uintp;
-with Urealp; use Urealp;
-with Validsw; use Validsw;
+with Stylesw; use Stylesw;
+with Tbuild; use Tbuild;
+with Uintp; use Uintp;
+with Urealp; use Urealp;
+with Validsw; use Validsw;
package body Sem_Ch6 is
@@ -128,9 +131,6 @@ package body Sem_Ch6 is
-- Does all the real work of Analyze_Subprogram_Body. This is split out so
-- that we can use RETURN but not skip the debug output at the end.
- function Can_Override_Operator (Subp : Entity_Id) return Boolean;
- -- Returns true if Subp can override a predefined operator.
-
procedure Check_Conformance
(New_Id : Entity_Id;
Old_Id : Entity_Id;
@@ -298,8 +298,9 @@ package body Sem_Ch6 is
Asp : Node_Id;
New_Body : Node_Id;
New_Spec : Node_Id;
- Orig_N : Node_Id;
+ Orig_N : Node_Id := Empty;
Ret : Node_Id;
+ Typ : Entity_Id := Empty;
Def_Id : Entity_Id := Empty;
Prev : Entity_Id;
@@ -333,6 +334,8 @@ package body Sem_Ch6 is
Def_Id := Analyze_Subprogram_Specification (Spec);
Prev := Find_Corresponding_Spec (N);
+ Typ := Etype (Def_Id);
+
-- The previous entity may be an expression function as well, in
-- which case the redeclaration is illegal.
@@ -406,7 +409,7 @@ package body Sem_Ch6 is
if not Inside_A_Generic then
Freeze_Expr_Types
(Def_Id => Def_Id,
- Typ => Etype (Def_Id),
+ Typ => Typ,
Expr => Expr,
N => N);
end if;
@@ -496,6 +499,8 @@ package body Sem_Ch6 is
Def_Id := Defining_Entity (N);
Set_Is_Inlined (Def_Id);
+ Typ := Etype (Def_Id);
+
-- Establish the linkages between the spec and the body. These are
-- used when the expression function acts as the prefix of attribute
-- 'Access in order to freeze the original expression which has been
@@ -517,107 +522,99 @@ package body Sem_Ch6 is
Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id));
Push_Scope (Def_Id);
Install_Formals (Def_Id);
- Preanalyze_Spec_Expression (Expr, Etype (Def_Id));
+ Preanalyze_Spec_Expression (Expr, Typ);
+ End_Scope;
+ else
+ Push_Scope (Def_Id);
+ Install_Formals (Def_Id);
+ Preanalyze_Formal_Expression (Expr, Typ);
+ Check_Limited_Return (Orig_N, Expr, Typ);
End_Scope;
end if;
+ -- If this is a wrapper created in an instance for a formal
+ -- subprogram, insert body after declaration, to be analyzed when the
+ -- enclosing instance is analyzed.
+
+ if GNATprove_Mode
+ and then Is_Generic_Actual_Subprogram (Def_Id)
+ then
+ Insert_After (N, New_Body);
+
-- To prevent premature freeze action, insert the new body at the end
-- of the current declarations, or at the end of the package spec.
-- However, resolve usage names now, to prevent spurious visibility
-- on later entities. Note that the function can now be called in
- -- the current declarative part, which will appear to be prior to
- -- the presence of the body in the code. There are nevertheless no
- -- order of elaboration issues because all name resolution has taken
- -- place at the point of declaration.
-
- declare
- Decls : List_Id := List_Containing (N);
- Expr : constant Node_Id := Expression (Ret);
- Par : constant Node_Id := Parent (Decls);
- Typ : constant Entity_Id := Etype (Def_Id);
-
- begin
- -- If this is a wrapper created for in an instance for a formal
- -- subprogram, insert body after declaration, to be analyzed when
- -- the enclosing instance is analyzed.
+ -- the current declarative part, which will appear to be prior to the
+ -- presence of the body in the code. There are nevertheless no order
+ -- of elaboration issues because all name resolution has taken place
+ -- at the point of declaration.
- if GNATprove_Mode
- and then Is_Generic_Actual_Subprogram (Def_Id)
- then
- Insert_After (N, New_Body);
+ else
+ declare
+ Decls : List_Id := List_Containing (N);
+ Par : constant Node_Id := Parent (Decls);
- else
+ begin
if Nkind (Par) = N_Package_Specification
and then Decls = Visible_Declarations (Par)
- and then Present (Private_Declarations (Par))
and then not Is_Empty_List (Private_Declarations (Par))
then
Decls := Private_Declarations (Par);
end if;
Insert_After (Last (Decls), New_Body);
+ end;
+ end if;
- -- Preanalyze the expression if not already done above
-
- if not Inside_A_Generic then
- Push_Scope (Def_Id);
- Install_Formals (Def_Id);
- Preanalyze_Formal_Expression (Expr, Typ);
- Check_Limited_Return (Original_Node (N), Expr, Typ);
- End_Scope;
- end if;
-
- -- In the case of an expression function marked with the
- -- aspect Static, we need to check the requirement that the
- -- function's expression is a potentially static expression.
- -- This is done by making a full copy of the expression tree
- -- and performing a special preanalysis on that tree with
- -- the global flag Checking_Potentially_Static_Expression
- -- enabled. If the resulting expression is static, then it's
- -- OK, but if not, that means the expression violates the
- -- requirements of the Ada 202x RM in 4.9(3.2/5-3.4/5) and
- -- we flag an error.
-
- if Is_Static_Function (Def_Id) then
- if not Is_Static_Expression (Expr) then
- declare
- Exp_Copy : constant Node_Id := New_Copy_Tree (Expr);
- begin
- Set_Checking_Potentially_Static_Expression (True);
+ -- In the case of an expression function marked with the aspect
+ -- Static, we need to check the requirement that the function's
+ -- expression is a potentially static expression. This is done
+ -- by making a full copy of the expression tree and performing
+ -- a special preanalysis on that tree with the global flag
+ -- Checking_Potentially_Static_Expression enabled. If the
+ -- resulting expression is static, then it's OK, but if not, that
+ -- means the expression violates the requirements of the Ada 2022
+ -- RM in 4.9(3.2/5-3.4/5) and we flag an error.
- Preanalyze_Formal_Expression (Exp_Copy, Typ);
+ if Is_Static_Function (Def_Id) then
+ if not Is_Static_Expression (Expr) then
+ declare
+ Exp_Copy : constant Node_Id := New_Copy_Tree (Expr);
+ begin
+ Set_Checking_Potentially_Static_Expression (True);
- if not Is_Static_Expression (Exp_Copy) then
- Error_Msg_N
- ("static expression function requires "
- & "potentially static expression", Expr);
- end if;
+ Preanalyze_Formal_Expression (Exp_Copy, Typ);
- Set_Checking_Potentially_Static_Expression (False);
- end;
+ if not Is_Static_Expression (Exp_Copy) then
+ Error_Msg_N
+ ("static expression function requires "
+ & "potentially static expression", Expr);
end if;
- -- We also make an additional copy of the expression and
- -- replace the expression of the expression function with
- -- this copy, because the currently present expression is
- -- now associated with the body created for the static
- -- expression function, which will later be analyzed and
- -- possibly rewritten, and we need to have the separate
- -- unanalyzed copy available for use with later static
- -- calls.
+ Set_Checking_Potentially_Static_Expression (False);
+ end;
+ end if;
- Set_Expression
- (Original_Node (Subprogram_Spec (Def_Id)),
- New_Copy_Tree (Expr));
+ -- We also make an additional copy of the expression and
+ -- replace the expression of the expression function with
+ -- this copy, because the currently present expression is
+ -- now associated with the body created for the static
+ -- expression function, which will later be analyzed and
+ -- possibly rewritten, and we need to have the separate
+ -- unanalyzed copy available for use with later static
+ -- calls.
- -- Mark static expression functions as inlined, to ensure
- -- that even calls with nonstatic actuals will be inlined.
+ Set_Expression
+ (Original_Node (Subprogram_Spec (Def_Id)),
+ New_Copy_Tree (Expr));
- Set_Has_Pragma_Inline (Def_Id);
- Set_Is_Inlined (Def_Id);
- end if;
- end if;
- end;
+ -- Mark static expression functions as inlined, to ensure
+ -- that even calls with nonstatic actuals will be inlined.
+
+ Set_Has_Pragma_Inline (Def_Id);
+ Set_Is_Inlined (Def_Id);
+ end if;
end if;
-- Check incorrect use of dynamically tagged expression. This doesn't
@@ -626,13 +623,12 @@ package body Sem_Ch6 is
-- nodes that don't come from source.
if Present (Def_Id)
- and then Nkind (Def_Id) in N_Has_Etype
- and then Is_Tagged_Type (Etype (Def_Id))
+ and then Is_Tagged_Type (Typ)
then
Check_Dynamically_Tagged_Expression
(Expr => Expr,
- Typ => Etype (Def_Id),
- Related_Nod => Original_Node (N));
+ Typ => Typ,
+ Related_Nod => Orig_N);
end if;
-- We must enforce checks for unreferenced formals in our newly
@@ -642,9 +638,9 @@ package body Sem_Ch6 is
if Present (Parameter_Specifications (New_Spec)) then
declare
Form_New_Def : Entity_Id;
- Form_New_Spec : Entity_Id;
+ Form_New_Spec : Node_Id;
Form_Old_Def : Entity_Id;
- Form_Old_Spec : Entity_Id;
+ Form_Old_Spec : Node_Id;
begin
Form_New_Spec := First (Parameter_Specifications (New_Spec));
@@ -740,7 +736,7 @@ package body Sem_Ch6 is
-- Function result subtype
procedure Check_No_Return_Expression (Return_Expr : Node_Id);
- -- Ada 2020: Check that the return expression in a No_Return function
+ -- Ada 2022: Check that the return expression in a No_Return function
-- meets the conditions specified by RM 6.5.1(5.1/5).
procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id);
@@ -1446,13 +1442,13 @@ package body Sem_Ch6 is
Check_Return_Construct_Accessibility (N);
- -- Ada 2020 (AI12-0269): Any return statement that applies to a
+ -- Ada 2022 (AI12-0269): Any return statement that applies to a
-- nonreturning function shall be a simple_return_statement with
-- an expression that is a raise_expression, or else a call on a
-- nonreturning function, or else a parenthesized expression of
-- one of these.
- if Ada_Version >= Ada_2020
+ if Ada_Version >= Ada_2022
and then No_Return (Scope_Id)
and then Comes_From_Source (N)
then
@@ -1531,14 +1527,12 @@ package body Sem_Ch6 is
-- Check RM 6.5 (5.9/3)
if Has_Aliased then
- if Ada_Version < Ada_2012 then
-
- -- Shouldn't this test Warn_On_Ada_2012_Compatibility ???
- -- Can it really happen (extended return???)
-
+ if Ada_Version < Ada_2012
+ and then Warn_On_Ada_2012_Compatibility
+ then
Error_Msg_N
("ALIASED only allowed for limited return objects "
- & "in Ada 2012??", N);
+ & "in Ada 2012?y?", N);
elsif not Is_Limited_View (R_Type) then
Error_Msg_N
@@ -1546,10 +1540,10 @@ package body Sem_Ch6 is
end if;
end if;
- -- Ada 2020 (AI12-0269): Any return statement that applies to a
+ -- Ada 2022 (AI12-0269): Any return statement that applies to a
-- nonreturning function shall be a simple_return_statement.
- if Ada_Version >= Ada_2020
+ if Ada_Version >= Ada_2022
and then No_Return (Scope_Id)
and then Comes_From_Source (N)
then
@@ -1670,9 +1664,9 @@ package body Sem_Ch6 is
Related_Nod => N);
end if;
- -- ??? A real run-time accessibility check is needed in cases
- -- involving dereferences of access parameters. For now we just
- -- check the static cases.
+ -- Perform static accessibility checks for cases involving
+ -- dereferences of access parameters. Runtime accessibility checks
+ -- get generated elsewhere.
if (Ada_Version < Ada_2005 or else Debug_Flag_Dot_L)
and then Is_Limited_View (Etype (Scope_Id))
@@ -1770,13 +1764,13 @@ package body Sem_Ch6 is
if Kind = E_Generic_Procedure
and then Nkind (Spec) /= N_Procedure_Specification
then
- Error_Msg_N ("invalid body for generic procedure ", Body_Id);
+ Error_Msg_N ("invalid body for generic procedure", Body_Id);
return;
elsif Kind = E_Generic_Function
and then Nkind (Spec) /= N_Function_Specification
then
- Error_Msg_N ("invalid body for generic function ", Body_Id);
+ Error_Msg_N ("invalid body for generic function", Body_Id);
return;
end if;
@@ -1792,7 +1786,7 @@ package body Sem_Ch6 is
end if;
if Nkind (N) = N_Subprogram_Body_Stub then
- Set_Ekind (Defining_Entity (Specification (N)), Kind);
+ Mutate_Ekind (Defining_Entity (Specification (N)), Kind);
else
Set_Corresponding_Spec (N, Gen_Id);
end if;
@@ -1843,8 +1837,13 @@ package body Sem_Ch6 is
-- Visible generic entity is callable within its own body
- Set_Ekind (Gen_Id, Ekind (Body_Id));
- Set_Ekind (Body_Id, E_Subprogram_Body);
+ Mutate_Ekind (Gen_Id, Ekind (Body_Id));
+ Reinit_Field_To_Zero (Body_Id, F_Has_Out_Or_In_Out_Parameter,
+ Old_Ekind =>
+ (E_Function | E_Procedure |
+ E_Generic_Function | E_Generic_Procedure => True,
+ others => False));
+ Mutate_Ekind (Body_Id, E_Subprogram_Body);
Set_Convention (Body_Id, Convention (Gen_Id));
Set_Is_Obsolescent (Body_Id, Is_Obsolescent (Gen_Id));
Set_Scope (Body_Id, Scope (Gen_Id));
@@ -1855,8 +1854,8 @@ package body Sem_Ch6 is
-- No body to analyze, so restore state of generic unit
- Set_Ekind (Gen_Id, Kind);
- Set_Ekind (Body_Id, Kind);
+ Mutate_Ekind (Gen_Id, Kind);
+ Mutate_Ekind (Body_Id, Kind);
if Present (First_Ent) then
Set_First_Entity (Gen_Id, First_Ent);
@@ -1920,7 +1919,9 @@ package body Sem_Ch6 is
-- Outside of its body, unit is generic again
- Set_Ekind (Gen_Id, Kind);
+ Reinit_Field_To_Zero (Gen_Id, F_Has_Nested_Subprogram,
+ Old_Ekind => (E_Function | E_Procedure => True, others => False));
+ Mutate_Ekind (Gen_Id, Kind);
Generate_Reference (Gen_Id, Body_Id, 'b', Set_Ref => False);
if Style_Check then
@@ -2015,7 +2016,7 @@ package body Sem_Ch6 is
if Present (Prev) and then Is_Generic_Subprogram (Prev) then
Insert_Before (N, Null_Body);
- Set_Ekind (Defining_Entity (N), Ekind (Prev));
+ Mutate_Ekind (Defining_Entity (N), Ekind (Prev));
Rewrite (N, Make_Null_Statement (Loc));
Analyze_Generic_Subprogram_Body (Null_Body, Prev);
@@ -2328,7 +2329,7 @@ package body Sem_Ch6 is
if Present (Actuals) then
Analyze_Call_And_Resolve;
else
- Error_Msg_N ("missing explicit dereference in call ", N);
+ Error_Msg_N ("missing explicit dereference in call", N);
end if;
-- If not an access to subprogram, then the prefix must resolve to the
@@ -2605,6 +2606,18 @@ package body Sem_Ch6 is
Analyze_Dimension (N);
end Analyze_Return_Statement;
+ -----------------------------------
+ -- Analyze_Return_When_Statement --
+ -----------------------------------
+
+ procedure Analyze_Return_When_Statement (N : Node_Id) is
+ begin
+ -- Verify the condition is a Boolean expression
+
+ Analyze_And_Resolve (Condition (N), Any_Boolean);
+ Check_Unset_Reference (Condition (N));
+ end Analyze_Return_When_Statement;
+
-------------------------------------
-- Analyze_Simple_Return_Statement --
-------------------------------------
@@ -3416,15 +3429,13 @@ package body Sem_Ch6 is
Prag := Empty;
end if;
- if Present (Prag) then
+ if Present (Prag) and then Is_List_Member (N) then
if Present (Spec_Id) then
- if Is_List_Member (N)
- and then Is_List_Member (Unit_Declaration_Node (Spec_Id))
+ if Is_List_Member (Unit_Declaration_Node (Spec_Id))
and then In_Same_List (N, Unit_Declaration_Node (Spec_Id))
then
Analyze (Prag);
end if;
-
else
-- Create a subprogram declaration, to make treatment uniform.
-- Make the sloc of the subprogram name that of the entity in
@@ -3443,7 +3454,12 @@ package body Sem_Ch6 is
-- Link the body and the generated spec
Set_Corresponding_Body (Decl, Body_Id);
- Set_Corresponding_Spec (N, Subp);
+
+ if Nkind (N) = N_Subprogram_Body_Stub then
+ Set_Corresponding_Spec_Of_Stub (N, Subp);
+ else
+ Set_Corresponding_Spec (N, Subp);
+ end if;
Set_Defining_Unit_Name (Specification (Decl), Subp);
@@ -3818,7 +3834,8 @@ package body Sem_Ch6 is
Result : Elist_Id := No_Elist;
function Mask_Type_Refs (Node : Node_Id) return Traverse_Result;
- -- Mask all types referenced in the subtree rooted at Node
+ -- Mask all types referenced in the subtree rooted at Node as
+ -- formally frozen.
--------------------
-- Mask_Type_Refs --
@@ -3826,7 +3843,8 @@ package body Sem_Ch6 is
function Mask_Type_Refs (Node : Node_Id) return Traverse_Result is
procedure Mask_Type (Typ : Entity_Id);
- -- ??? what does this do?
+ -- Mask a given type as formally frozen when outside the current
+ -- scope, or else freeze the type.
---------------
-- Mask_Type --
@@ -4061,7 +4079,7 @@ package body Sem_Ch6 is
and then Operator_Matches_Spec (Spec_Id, Spec_Id)
then
Error_Msg_NE
- ("subprogram& overrides predefined operator ",
+ ("subprogram& overrides predefined operator",
Body_Spec, Spec_Id);
-- Overriding indicators aren't allowed for protected subprogram
@@ -4568,6 +4586,17 @@ package body Sem_Ch6 is
then
Conformant := True;
+ -- Finally, a body generated for an expression function copies
+ -- the profile of the function and no check is needed either.
+ -- If the body is the completion of a previous function
+ -- declared elsewhere, the conformance check is required.
+
+ elsif Nkind (N) = N_Subprogram_Body
+ and then Was_Expression_Function (N)
+ and then Sloc (Spec_Id) = Sloc (Body_Id)
+ then
+ Conformant := True;
+
else
Check_Conformance
(Body_Id, Spec_Id,
@@ -4601,7 +4630,19 @@ package body Sem_Ch6 is
Reference_Body_Formals (Spec_Id, Body_Id);
end if;
- Set_Ekind (Body_Id, E_Subprogram_Body);
+ Reinit_Field_To_Zero (Body_Id, F_Has_Out_Or_In_Out_Parameter);
+ Reinit_Field_To_Zero (Body_Id, F_Needs_No_Actuals,
+ Old_Ekind => (E_Function | E_Procedure => True, others => False));
+ Reinit_Field_To_Zero (Body_Id, F_Is_Predicate_Function,
+ Old_Ekind => (E_Function | E_Procedure => True, others => False));
+ Reinit_Field_To_Zero (Body_Id, F_Protected_Subprogram,
+ Old_Ekind => (E_Function | E_Procedure => True, others => False));
+
+ if Ekind (Body_Id) = E_Procedure then
+ Reinit_Field_To_Zero (Body_Id, F_Receiving_Entry);
+ end if;
+
+ Mutate_Ekind (Body_Id, E_Subprogram_Body);
if Nkind (N) = N_Subprogram_Body_Stub then
Set_Corresponding_Spec_Of_Stub (N, Spec_Id);
@@ -5644,17 +5685,6 @@ package body Sem_Ch6 is
end;
end if;
- -- What is the following code for, it used to be
-
- -- ??? Set_Suppress_Elaboration_Checks
- -- ??? (Designator, Elaboration_Checks_Suppressed (Designator));
-
- -- The following seems equivalent, but a bit dubious
-
- if Elaboration_Checks_Suppressed (Designator) then
- Set_Kill_Elaboration_Checks (Designator);
- end if;
-
-- For a compilation unit, set body required. This flag will only be
-- reset if a valid Import or Interface pragma is processed later on.
@@ -5766,10 +5796,10 @@ package body Sem_Ch6 is
end if;
if Nkind (N) = N_Function_Specification then
- Set_Ekind (Designator, E_Function);
+ Mutate_Ekind (Designator, E_Function);
Set_Mechanism (Designator, Default_Mechanism);
else
- Set_Ekind (Designator, E_Procedure);
+ Mutate_Ekind (Designator, E_Procedure);
Set_Etype (Designator, Standard_Void_Type);
end if;
@@ -6255,7 +6285,9 @@ package body Sem_Ch6 is
-- Null exclusion must match
- if not Null_Exclusions_Match (Old_Formal, New_Formal) then
+ if not Relaxed_RM_Semantics
+ and then not Null_Exclusions_Match (Old_Formal, New_Formal)
+ then
Conformance_Error
("\null exclusion for& does not match", New_Formal);
@@ -6727,18 +6759,7 @@ package body Sem_Ch6 is
-- may not be known yet (for private types).
if not Has_Delayed_Freeze (Designator) and then Expander_Active then
- declare
- Typ : constant Entity_Id := Etype (Designator);
- Utyp : constant Entity_Id := Underlying_Type (Typ);
-
- begin
- if Is_Limited_View (Typ) then
- Set_Returns_By_Ref (Designator);
-
- elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
- Set_Returns_By_Ref (Designator);
- end if;
- end;
+ Compute_Returns_By_Ref (Designator);
end if;
end Check_Delayed_Subprogram;
@@ -6990,16 +7011,14 @@ package body Sem_Ch6 is
-- A limited interface that is not immutably limited is OK
if Is_Limited_Interface (R_Type)
- and then
- not (Is_Task_Interface (R_Type)
- or else Is_Protected_Interface (R_Type)
- or else Is_Synchronized_Interface (R_Type))
+ and then not Is_Concurrent_Interface (R_Type)
then
null;
elsif Is_Limited_Type (R_Type)
and then not Is_Interface (R_Type)
- and then Comes_From_Source (N)
+ and then not (Nkind (N) = N_Simple_Return_Statement
+ and then Comes_From_Extended_Return_Statement (N))
and then not In_Instance_Body
and then not OK_For_Limited_Init_In_05 (R_Type, Expr)
then
@@ -7261,10 +7280,14 @@ package body Sem_Ch6 is
then
Set_Overridden_Operation (Subp, Alias (Overridden_Subp));
Inherit_Subprogram_Contract (Subp, Alias (Overridden_Subp));
+ Set_Is_Ada_2022_Only (Subp,
+ Is_Ada_2022_Only (Alias (Overridden_Subp)));
else
Set_Overridden_Operation (Subp, Overridden_Subp);
Inherit_Subprogram_Contract (Subp, Overridden_Subp);
+ Set_Is_Ada_2022_Only (Subp,
+ Is_Ada_2022_Only (Overridden_Subp));
end if;
end if;
end if;
@@ -7293,7 +7316,7 @@ package body Sem_Ch6 is
-- predefined signature, because we know already that there is no
-- explicit overridden operation.
- elsif Nkind (Subp) = N_Defining_Operator_Symbol then
+ elsif Chars (Subp) in Any_Operator_Name then
if Must_Not_Override (Spec) then
-- If this is not a primitive or a protected subprogram, then
@@ -7307,7 +7330,7 @@ package body Sem_Ch6 is
elsif Can_Override_Operator (Subp) then
Error_Msg_NE
- ("subprogram& overrides predefined operator ", Spec, Subp);
+ ("subprogram& overrides predefined operator", Spec, Subp);
end if;
elsif Must_Override (Spec) then
@@ -8285,7 +8308,12 @@ package body Sem_Ch6 is
Typ : Entity_Id;
begin
- if Nkind (Subp) /= N_Defining_Operator_Symbol then
+ -- Return False if not an operator. We test the name rather than testing
+ -- that the Nkind is N_Defining_Operator_Symbol, because there are cases
+ -- where an operator entity can be an N_Defining_Identifier (such as for
+ -- function instantiations).
+
+ if Chars (Subp) not in Any_Operator_Name then
return False;
else
@@ -8775,7 +8803,7 @@ package body Sem_Ch6 is
return Empty;
end if;
- Set_Ekind (EF, E_In_Parameter);
+ Mutate_Ekind (EF, E_In_Parameter);
Set_Actual_Subtype (EF, Typ);
Set_Etype (EF, Typ);
Set_Scope (EF, Scope);
@@ -8874,7 +8902,7 @@ package body Sem_Ch6 is
end if;
if not Has_Discriminants (Formal_Type)
- and then Ekind (Formal_Type) in Private_Kind
+ and then Is_Private_Type (Formal_Type)
and then Present (Underlying_Type (Formal_Type))
then
Formal_Type := Underlying_Type (Formal_Type);
@@ -9021,7 +9049,7 @@ package body Sem_Ch6 is
if Needs_BIP_Task_Actuals (E) then
Discard :=
Add_Extra_Formal
- (E, RTE (RE_Master_Id),
+ (E, Standard_Integer,
E, BIP_Formal_Suffix (BIP_Task_Master));
Set_Has_Master_Entity (E);
@@ -10713,8 +10741,8 @@ package body Sem_Ch6 is
exit;
end if;
- Next_Entity (P_Formal);
- Next_Entity (N_Formal);
+ Next_Formal (P_Formal);
+ Next_Formal (N_Formal);
end loop;
-- Found a matching primitive operation belonging to the
@@ -10991,9 +11019,11 @@ package body Sem_Ch6 is
(Is_Primitive : out Boolean;
Is_Overriding : Boolean := False)
is
- Formal : Entity_Id;
- F_Typ : Entity_Id;
- B_Typ : Entity_Id;
+ procedure Add_Or_Replace_Untagged_Primitive (Typ : Entity_Id);
+ -- Either add the new subprogram to the list of primitives for
+ -- untagged type Typ, or if it overrides a primitive of Typ, then
+ -- replace the overridden primitive in Typ's primitives list with
+ -- the new subprogram.
function Visible_Part_Type (T : Entity_Id) return Boolean;
-- Returns true if T is declared in the visible part of the current
@@ -11008,6 +11038,63 @@ package body Sem_Ch6 is
-- in a private part, then it must override a function declared in
-- the visible part.
+ ---------------------------------------
+ -- Add_Or_Replace_Untagged_Primitive --
+ ---------------------------------------
+
+ procedure Add_Or_Replace_Untagged_Primitive (Typ : Entity_Id) is
+ Replaced_Overridden_Subp : Boolean := False;
+
+ begin
+ pragma Assert (not Is_Tagged_Type (Typ));
+
+ -- Anonymous access types don't have a primitives list. Normally
+ -- such types wouldn't make it here, but the case of anonymous
+ -- access-to-subprogram types can.
+
+ if not Is_Anonymous_Access_Type (Typ) then
+
+ -- If S overrides a subprogram that's a primitive of
+ -- the formal's type, then replace the overridden
+ -- subprogram with the new subprogram in the type's
+ -- list of primitives.
+
+ if Is_Overriding then
+ pragma Assert (Present (Overridden_Subp)
+ and then Overridden_Subp = E); -- Added for now
+
+ declare
+ Prim_Ops : constant Elist_Id :=
+ Primitive_Operations (Typ);
+ Elmt : Elmt_Id;
+ begin
+ if Present (Prim_Ops) then
+ Elmt := First_Elmt (Prim_Ops);
+
+ while Present (Elmt)
+ and then Node (Elmt) /= Overridden_Subp
+ loop
+ Next_Elmt (Elmt);
+ end loop;
+
+ if Present (Elmt) then
+ Replace_Elmt (Elmt, S);
+ Replaced_Overridden_Subp := True;
+ end if;
+ end if;
+ end;
+ end if;
+
+ -- If the new subprogram did not override an operation
+ -- of the formal's type, then add it to the primitives
+ -- list of the type.
+
+ if not Replaced_Overridden_Subp then
+ Append_Unique_Elmt (S, Primitive_Operations (Typ));
+ end if;
+ end if;
+ end Add_Or_Replace_Untagged_Primitive;
+
------------------------------
-- Check_Private_Overriding --
------------------------------
@@ -11163,7 +11250,7 @@ package body Sem_Ch6 is
-- If the entity is a private type, then it must be declared in a
-- visible part.
- if Ekind (T) in Private_Kind then
+ if Is_Private_Type (T) then
return True;
elsif Is_Type (T) and then Has_Private_Declaration (T) then
@@ -11180,13 +11267,29 @@ package body Sem_Ch6 is
end if;
end Visible_Part_Type;
+ -- Local variables
+
+ Formal : Entity_Id;
+ F_Typ : Entity_Id;
+ B_Typ : Entity_Id;
+
-- Start of processing for Check_For_Primitive_Subprogram
begin
Is_Primitive := False;
if not Comes_From_Source (S) then
- null;
+
+ -- Add an inherited primitive for an untagged derived type to
+ -- Derived_Type's list of primitives. Tagged primitives are dealt
+ -- with in Check_Dispatching_Operation.
+
+ if Present (Derived_Type)
+ and then Extensions_Allowed
+ and then not Is_Tagged_Type (Derived_Type)
+ then
+ Append_Unique_Elmt (S, Primitive_Operations (Derived_Type));
+ end if;
-- If subprogram is at library level, it is not primitive operation
@@ -11215,8 +11318,18 @@ package body Sem_Ch6 is
Is_Primitive := True;
Set_Has_Primitive_Operations (B_Typ);
Set_Is_Primitive (S);
- Check_Private_Overriding (B_Typ);
+ -- Add a primitive for an untagged type to B_Typ's list
+ -- of primitives. Tagged primitives are dealt with in
+ -- Check_Dispatching_Operation.
+
+ if Extensions_Allowed
+ and then not Is_Tagged_Type (B_Typ)
+ then
+ Add_Or_Replace_Untagged_Primitive (B_Typ);
+ end if;
+
+ Check_Private_Overriding (B_Typ);
-- The Ghost policy in effect at the point of declaration
-- or a tagged type and a primitive operation must match
-- (SPARK RM 6.9(16)).
@@ -11248,6 +11361,17 @@ package body Sem_Ch6 is
Is_Primitive := True;
Set_Is_Primitive (S);
Set_Has_Primitive_Operations (B_Typ);
+
+ -- Add a primitive for an untagged type to B_Typ's list
+ -- of primitives. Tagged primitives are dealt with in
+ -- Check_Dispatching_Operation.
+
+ if Extensions_Allowed
+ and then not Is_Tagged_Type (B_Typ)
+ then
+ Add_Or_Replace_Untagged_Primitive (B_Typ);
+ end if;
+
Check_Private_Overriding (B_Typ);
-- The Ghost policy in effect at the point of declaration
@@ -11681,7 +11805,7 @@ package body Sem_Ch6 is
if Inside_Freezing_Actions = 0
and then Is_Package_Or_Generic_Package (Current_Scope)
and then In_Private_Part (Current_Scope)
- and then Nkind (Parent (E)) = N_Private_Extension_Declaration
+ and then Parent_Kind (E) = N_Private_Extension_Declaration
and then Nkind (Parent (S)) = N_Full_Type_Declaration
and then Full_View (Defining_Identifier (Parent (E)))
= Defining_Identifier (Parent (S))
@@ -11878,10 +12002,13 @@ package body Sem_Ch6 is
if Present (Alias (S)) then
Set_Overridden_Operation (E, Alias (S));
Inherit_Subprogram_Contract (E, Alias (S));
+ Set_Is_Ada_2022_Only (E,
+ Is_Ada_2022_Only (Alias (S)));
else
Set_Overridden_Operation (E, S);
Inherit_Subprogram_Contract (E, S);
+ Set_Is_Ada_2022_Only (E, Is_Ada_2022_Only (S));
end if;
-- When a dispatching operation overrides an inherited
@@ -12048,6 +12175,8 @@ package body Sem_Ch6 is
then
Set_Overridden_Operation (S, Alias (E));
Inherit_Subprogram_Contract (S, Alias (E));
+ Set_Is_Ada_2022_Only (S,
+ Is_Ada_2022_Only (Alias (E)));
-- Normal case of setting entity as overridden
@@ -12059,8 +12188,22 @@ package body Sem_Ch6 is
-- must check whether the target is an init_proc.
elsif not Is_Init_Proc (S) then
- Set_Overridden_Operation (S, E);
- Inherit_Subprogram_Contract (S, E);
+
+ -- LSP wrappers must override the ultimate alias of their
+ -- wrapped dispatching primitive E; required to traverse
+ -- the chain of ancestor primitives (c.f. Map_Primitives)
+ -- They don't inherit contracts.
+
+ if Is_Wrapper (S)
+ and then Present (LSP_Subprogram (S))
+ then
+ Set_Overridden_Operation (S, Ultimate_Alias (E));
+ else
+ Set_Overridden_Operation (S, E);
+ Inherit_Subprogram_Contract (S, E);
+ end if;
+
+ Set_Is_Ada_2022_Only (S, Is_Ada_2022_Only (E));
end if;
Check_Overriding_Indicator (S, E, Is_Primitive => True);
@@ -12087,8 +12230,22 @@ package body Sem_Ch6 is
Is_Predefined_Dispatching_Operation (Alias (E)))
then
if Present (Alias (E)) then
- Set_Overridden_Operation (S, Alias (E));
- Inherit_Subprogram_Contract (S, Alias (E));
+
+ -- LSP wrappers must override the ultimate alias of
+ -- their wrapped dispatching primitive E; required to
+ -- traverse the chain of ancestor primitives (see
+ -- Map_Primitives). They don't inherit contracts.
+
+ if Is_Wrapper (S)
+ and then Present (LSP_Subprogram (S))
+ then
+ Set_Overridden_Operation (S, Ultimate_Alias (E));
+ else
+ Set_Overridden_Operation (S, Alias (E));
+ Inherit_Subprogram_Contract (S, Alias (E));
+ end if;
+
+ Set_Is_Ada_2022_Only (S, Is_Ada_2022_Only (Alias (E)));
end if;
end if;
@@ -12963,30 +13120,30 @@ package body Sem_Ch6 is
end if;
if In_Present (Spec) then
- Set_Ekind (Formal_Id, E_In_Out_Parameter);
+ Mutate_Ekind (Formal_Id, E_In_Out_Parameter);
else
- Set_Ekind (Formal_Id, E_Out_Parameter);
+ Mutate_Ekind (Formal_Id, E_Out_Parameter);
end if;
-- But not in earlier versions of Ada
else
Error_Msg_N ("functions can only have IN parameters", Spec);
- Set_Ekind (Formal_Id, E_In_Parameter);
+ Mutate_Ekind (Formal_Id, E_In_Parameter);
end if;
elsif In_Present (Spec) then
- Set_Ekind (Formal_Id, E_In_Out_Parameter);
+ Mutate_Ekind (Formal_Id, E_In_Out_Parameter);
else
- Set_Ekind (Formal_Id, E_Out_Parameter);
+ Mutate_Ekind (Formal_Id, E_Out_Parameter);
Set_Never_Set_In_Source (Formal_Id, True);
Set_Is_True_Constant (Formal_Id, False);
Set_Current_Value (Formal_Id, Empty);
end if;
else
- Set_Ekind (Formal_Id, E_In_Parameter);
+ Mutate_Ekind (Formal_Id, E_In_Parameter);
end if;
-- Set Is_Known_Non_Null for access parameters since the language