aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_elab.adb
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/ada/sem_elab.adb
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-devel/autopar_devel.zip
gcc-devel/autopar_devel.tar.gz
gcc-devel/autopar_devel.tar.bz2
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/ada/sem_elab.adb')
-rw-r--r--gcc/ada/sem_elab.adb458
1 files changed, 239 insertions, 219 deletions
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index f3cac46..78108e9 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1997-2019, Free Software Foundation, Inc. --
+-- Copyright (C) 1997-2020, 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- --
@@ -75,8 +75,8 @@ package body Sem_Elab is
-- The access-before-elaboration (ABE) mechanism implemented in this unit
-- has the following objectives:
--
- -- * Diagnose at compile-time or install run-time checks to prevent ABE
- -- access to data and behaviour.
+ -- * Diagnose at compile time or install run-time checks to prevent ABE
+ -- access to data and behavior.
--
-- The high-level idea is to accurately diagnose ABE issues within a
-- single unit because the ABE mechanism can inspect the whole unit.
@@ -111,7 +111,7 @@ package body Sem_Elab is
-- * Dynamic model - This is the most permissive of the three models.
-- When the dynamic model is in effect, the mechanism diagnoses and
-- installs run-time checks to detect ABE issues in the main unit.
- -- The behaviour of this model is identical to that specified by the
+ -- The behavior of this model is identical to that specified by the
-- Ada RM. This model is enabled with switch -gnatE.
--
-- Static model - This is the middle ground of the three models. When
@@ -122,7 +122,7 @@ package body Sem_Elab is
-- the prior elaboration of withed units. This is the default model.
--
-- * SPARK model - This is the most conservative of the three models and
- -- impelements the semantics defined in SPARK RM 7.7. The SPARK model
+ -- implements the semantics defined in SPARK RM 7.7. The SPARK model
-- is in effect only when a context resides in a SPARK_Mode On region,
-- otherwise the mechanism falls back to one of the previous models.
--
@@ -186,7 +186,7 @@ package body Sem_Elab is
--
-- * Library level - A type of enclosing level. A scenario or target is at
-- the library level if it appears in a package library unit, ignoring
- -- enclosng packages.
+ -- enclosing packages.
--
-- * Non-library-level encapsulator - A construct that cannot be elaborated
-- on its own and requires elaboration by a top-level scenario.
@@ -400,7 +400,7 @@ package body Sem_Elab is
-- capture the target and relevant attributes of the original call.
--
-- The diagnostics of the ABE mechanism depend on accurate source locations
- -- to determine the spacial relation of nodes.
+ -- to determine the spatial relation of nodes.
-----------------------------------------
-- Suppression of elaboration warnings --
@@ -590,7 +590,7 @@ package body Sem_Elab is
-- -gnatH legacy elaboration checking mode enabled
--
-- When this switch is in effect, the pre-18.x ABE model becomes
- -- the defacto ABE model. This ammounts to cutting off all entry
+ -- the de facto ABE model. This amounts to cutting off all entry
-- points into the new ABE mechanism, and giving full control to
-- the old ABE mechanism.
--
@@ -1952,6 +1952,18 @@ package body Sem_Elab is
pragma Inline (Compilation_Unit);
-- Return the N_Compilation_Unit node of unit Unit_Id
+ function Elaboration_Phase_Active return Boolean;
+ pragma Inline (Elaboration_Phase_Active);
+ -- Determine whether the elaboration phase of the compilation has started
+
+ procedure Error_Preelaborated_Call (N : Node_Id);
+ -- Give an error or warning for a non-static/non-preelaborable call in a
+ -- preelaborated unit.
+
+ procedure Finalize_All_Data_Structures;
+ pragma Inline (Finalize_All_Data_Structures);
+ -- Destroy all internal data structures
+
function Find_Enclosing_Instance (N : Node_Id) return Node_Id;
pragma Inline (Find_Enclosing_Instance);
-- Find the declaration or body of the nearest expanded instance which
@@ -1972,14 +1984,6 @@ package body Sem_Elab is
-- Return the type of subprogram Subp_Id's first formal parameter. If the
-- subprogram lacks formal parameters, return Empty.
- function Elaboration_Phase_Active return Boolean;
- pragma Inline (Elaboration_Phase_Active);
- -- Determine whether the elaboration phase of the compilation has started
-
- procedure Finalize_All_Data_Structures;
- pragma Inline (Finalize_All_Data_Structures);
- -- Destroy all internal data structures
-
function Has_Body (Pack_Decl : Node_Id) return Boolean;
pragma Inline (Has_Body);
-- Determine whether package declaration Pack_Decl has a corresponding body
@@ -2605,7 +2609,7 @@ package body Sem_Elab is
Par := Parent (Call);
while Present (Par) loop
- if Nkind_In (Par, N_Package_Body, N_Package_Declaration) then
+ if Nkind (Par) in N_Package_Body | N_Package_Declaration then
return Defining_Entity (Par);
elsif Nkind (Par) = N_Handled_Sequence_Of_Statements then
@@ -2954,11 +2958,10 @@ package body Sem_Elab is
-- task objects found in the declarations.
else
- pragma Assert (Nkind_In (Context, N_Block_Statement,
- N_Entry_Body,
- N_Protected_Body,
- N_Subprogram_Body,
- N_Task_Body));
+ pragma Assert
+ (Nkind (Context) in
+ N_Block_Statement | N_Entry_Body | N_Protected_Body |
+ N_Subprogram_Body | N_Task_Body);
Traverse_List
(List => Declarations (Context),
@@ -2981,10 +2984,9 @@ package body Sem_Elab is
-- When the name denotes an array or record component, find the whole
-- object.
- while Nkind_In (Nam, N_Explicit_Dereference,
- N_Indexed_Component,
- N_Selected_Component,
- N_Slice)
+ while Nkind (Nam) in
+ N_Explicit_Dereference | N_Indexed_Component |
+ N_Selected_Component | N_Slice
loop
Nam := Prefix (Nam);
end loop;
@@ -3294,8 +3296,8 @@ package body Sem_Elab is
elsif (Debug_Flag_Underscore_A
or else Restriction_Active
(No_Entry_Calls_In_Elaboration_Code))
- and then Nkind_In (Original_Node (Scen), N_Accept_Statement,
- N_Selective_Accept)
+ and then Nkind (Original_Node (Scen)) in
+ N_Accept_Statement | N_Selective_Accept
then
return Abandon;
@@ -3329,18 +3331,18 @@ package body Sem_Elab is
-- until expansion transforms the node and relocates the contents.
-- Examine these lists in case expansion is disabled.
- elsif Nkind_In (Scen, N_And_Then, N_Or_Else) then
+ elsif Nkind (Scen) in N_And_Then | N_Or_Else then
Traverse_List (Actions (Scen));
- elsif Nkind_In (Scen, N_Elsif_Part, N_Iteration_Scheme) then
+ elsif Nkind (Scen) in N_Elsif_Part | N_Iteration_Scheme then
Traverse_List (Condition_Actions (Scen));
elsif Nkind (Scen) = N_If_Expression then
Traverse_List (Then_Actions (Scen));
Traverse_List (Else_Actions (Scen));
- elsif Nkind_In (Scen, N_Component_Association,
- N_Iterated_Component_Association)
+ elsif Nkind (Scen) in
+ N_Component_Association | N_Iterated_Component_Association
then
Traverse_List (Loop_Actions (Scen));
@@ -3511,8 +3513,7 @@ package body Sem_Elab is
-- contexts because nested calls has not been relocated to their
-- final context.
- if Nkind_In (Par, N_Aspect_Specification,
- N_Generic_Association)
+ if Nkind (Par) in N_Aspect_Specification | N_Generic_Association
then
return True;
@@ -3540,9 +3541,9 @@ package body Sem_Elab is
-- To qualify, the node must appear immediately within a source call
-- which invokes a source target.
- if Nkind_In (Outer_Call, N_Entry_Call_Statement,
- N_Function_Call,
- N_Procedure_Call_Statement)
+ if Nkind (Outer_Call) in N_Entry_Call_Statement
+ | N_Function_Call
+ | N_Procedure_Call_Statement
and then Comes_From_Source (Outer_Call)
then
Outer_Nam := Call_Name (Outer_Call);
@@ -3572,9 +3573,9 @@ package body Sem_Elab is
return
Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
and then not Comes_From_Source (Subp_Decl)
- and then Nkind_In (Context, N_Function_Specification,
- N_Package_Specification,
- N_Procedure_Specification)
+ and then Nkind (Context) in N_Function_Specification
+ | N_Package_Specification
+ | N_Procedure_Specification
and then Present (Generic_Parent (Context));
end Is_Generic_Formal_Subp;
@@ -3594,12 +3595,6 @@ package body Sem_Elab is
if Legacy_Elaboration_Checks then
return;
- -- Nothing to do for ASIS because ABE checks and diagnostics are not
- -- performed in this mode.
-
- elsif ASIS_Mode then
- return;
-
-- Nothing to do when the call is being preanalyzed as the marker will
-- be inserted in the wrong place.
@@ -3614,10 +3609,10 @@ package body Sem_Elab is
-- Nothing to do when the input does not denote a call or a requeue
- elsif not Nkind_In (N, N_Entry_Call_Statement,
- N_Function_Call,
- N_Procedure_Call_Statement,
- N_Requeue_Statement)
+ elsif Nkind (N) not in N_Entry_Call_Statement
+ | N_Function_Call
+ | N_Procedure_Call_Statement
+ | N_Requeue_Statement
then
return;
@@ -3626,7 +3621,7 @@ package body Sem_Elab is
-- elaboration) is in effect.
elsif Debug_Flag_Underscore_E
- and then Nkind_In (N, N_Entry_Call_Statement, N_Requeue_Statement)
+ and then Nkind (N) in N_Entry_Call_Statement | N_Requeue_Statement
then
return;
@@ -3687,6 +3682,11 @@ package body Sem_Elab is
then
return;
+ -- Static expression functions require no ABE processing
+
+ elsif Is_Static_Function (Subp_Id) then
+ return;
+
-- Source calls to source targets are always considered because they
-- reflect the original call graph.
@@ -3737,8 +3737,9 @@ package body Sem_Elab is
(Marker, Find_Enclosing_Level (N) = Declaration_Level);
Set_Is_Dispatching_Call
- (Marker, Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement)
- and then Present (Controlling_Argument (N)));
+ (Marker,
+ Nkind (N) in N_Function_Call | N_Procedure_Call_Statement
+ and then Present (Controlling_Argument (N)));
Set_Is_Elaboration_Checks_OK_Node
(Marker, Is_Elaboration_Checks_OK_Node (N));
@@ -3751,6 +3752,15 @@ package body Sem_Elab is
Set_Is_SPARK_Mode_On_Node (Marker, Is_SPARK_Mode_On_Node (N));
Set_Target (Marker, Subp_Id);
+ -- Ada 2020 (AI12-0175): Calls to certain functions that are essentially
+ -- unchecked conversions are preelaborable.
+
+ if Ada_Version >= Ada_2020 then
+ Set_Is_Preelaborable_Call (Marker, Is_Preelaborable_Construct (N));
+ else
+ Set_Is_Preelaborable_Call (Marker, False);
+ end if;
+
-- The marker is inserted prior to the original call. This placement has
-- several desirable effects:
@@ -3937,13 +3947,6 @@ package body Sem_Elab is
Finalize_All_Data_Structures;
return;
- -- Nothing to do for ASIS because ABE checks and diagnostics are not
- -- performed in this mode.
-
- elsif ASIS_Mode then
- Finalize_All_Data_Structures;
- return;
-
-- Nothing to do when the elaboration phase of the compiler is not
-- active.
@@ -4532,8 +4535,8 @@ package body Sem_Elab is
-- statement due to expansion activities.
if Nkind (Comp_Unit) = N_Null_Statement
- and then Nkind_In (Original_Node (Comp_Unit), N_Protected_Body,
- N_Task_Body)
+ and then Nkind (Original_Node (Comp_Unit)) in
+ N_Protected_Body | N_Task_Body
then
Comp_Unit := Parent (Comp_Unit);
pragma Assert (Nkind (Comp_Unit) = N_Subunit);
@@ -4549,9 +4552,8 @@ package body Sem_Elab is
-- the instantiated subprogram.
if Nkind (Comp_Unit) = N_Package_Specification
- and then Nkind_In (Original_Node (Parent (Comp_Unit)),
- N_Function_Instantiation,
- N_Procedure_Instantiation)
+ and then Nkind (Original_Node (Parent (Comp_Unit))) in
+ N_Function_Instantiation | N_Procedure_Instantiation
then
Comp_Unit := Parent (Parent (Comp_Unit));
@@ -4891,6 +4893,8 @@ package body Sem_Elab is
(Marker, Elaboration_Checks_OK (Attr_Rep));
Set_Is_Elaboration_Warnings_OK_Node
(Marker, Elaboration_Warnings_OK (Attr_Rep));
+ Set_Is_Preelaborable_Call
+ (Marker, False);
Set_Is_Source_Call
(Marker, Comes_From_Source (Attr));
Set_Is_SPARK_Mode_On_Node
@@ -5684,7 +5688,7 @@ package body Sem_Elab is
-- Ensure that the unit with the target body is elaborated prior to
-- the main unit. The implicit Elaborate[_All] is generated only when
- -- the call has elaboration checks enabled. This behaviour parallels
+ -- the call has elaboration checks enabled. This behavior parallels
-- that of the old ABE mechanism.
if Elaboration_Checks_OK (Call_Rep) then
@@ -6084,7 +6088,7 @@ package body Sem_Elab is
-- Ensure that the unit with the generic body is elaborated prior
-- to the main unit. No implicit pragma has to be generated if the
- -- instantiation has elaboration checks suppressed. This behaviour
+ -- instantiation has elaboration checks suppressed. This behavior
-- parallels that of the old ABE mechanism.
if Elaboration_Checks_OK (Inst_Rep) then
@@ -7024,7 +7028,7 @@ package body Sem_Elab is
-- Enter encapsulators by inspecting their declarations and/or
-- statements.
- if Nkind_In (Curr, N_Block_Statement, N_Package_Body) then
+ if Nkind (Curr) in N_Block_Statement | N_Package_Body then
Enter_Handled_Body (Curr);
elsif Nkind (Curr) = N_Package_Declaration then
@@ -7055,7 +7059,7 @@ package body Sem_Elab is
-- amount of work, but has the beneficial effect of computing
-- the early call regions of all preceding bodies.
- elsif Nkind_In (Curr, N_Entry_Body, N_Subprogram_Body) then
+ elsif Nkind (Curr) in N_Entry_Body | N_Subprogram_Body then
Start :=
Find_Early_Call_Region
(Body_Decl => Curr,
@@ -7091,9 +7095,9 @@ package body Sem_Elab is
-- visible declarations -> upper level
-- visible declarations -> terminate
- if Nkind_In (Context, N_Package_Specification,
- N_Protected_Definition,
- N_Task_Definition)
+ if Nkind (Context) in N_Package_Specification
+ | N_Protected_Definition
+ | N_Task_Definition
then
Transition_Spec_Declarations (Context, Curr);
@@ -7113,12 +7117,12 @@ package body Sem_Elab is
-- declarations -> corresponding package spec (Elab_Body)
-- declarations -> terminate
- elsif Nkind_In (Context, N_Block_Statement,
- N_Entry_Body,
- N_Package_Body,
- N_Protected_Body,
- N_Subprogram_Body,
- N_Task_Body)
+ elsif Nkind (Context) in N_Block_Statement
+ | N_Entry_Body
+ | N_Package_Body
+ | N_Protected_Body
+ | N_Subprogram_Body
+ | N_Task_Body
then
Transition_Body_Declarations (Context, Curr);
@@ -7423,12 +7427,14 @@ package body Sem_Elab is
-- The search must come from the statements of certain bodies or
-- statements.
- pragma Assert (Nkind_In (Bod, N_Block_Statement,
- N_Entry_Body,
- N_Package_Body,
- N_Protected_Body,
- N_Subprogram_Body,
- N_Task_Body));
+ pragma Assert
+ (Nkind (Bod) in
+ N_Block_Statement |
+ N_Entry_Body |
+ N_Package_Body |
+ N_Protected_Body |
+ N_Subprogram_Body |
+ N_Task_Body);
-- The search must come from the statements of the handled
-- sequence.
@@ -7824,7 +7830,7 @@ package body Sem_Elab is
begin
-- Nothing to do if the pragma is not related to elaboration
- if not Nam_In (Prag_Nam, Name_Elaborate, Name_Elaborate_All) then
+ if Prag_Nam not in Name_Elaborate | Name_Elaborate_All then
return;
-- Nothing to do when the pragma is illegal
@@ -7999,7 +8005,7 @@ package body Sem_Elab is
-- body -> spec
if Present (Unit_Id)
- and then Nkind_In (Unit_Id, N_Package_Body, N_Subprogram_Body)
+ and then Nkind (Unit_Id) in N_Package_Body | N_Subprogram_Body
then
Find_Elaboration_Context (Parent (Unit_Id));
@@ -8019,10 +8025,10 @@ package body Sem_Elab is
-- parent spec -> grandparent spec and so on
if Present (Unit_Id)
- and then Nkind_In (Unit_Id, N_Generic_Package_Declaration,
- N_Generic_Subprogram_Declaration,
- N_Package_Declaration,
- N_Subprogram_Declaration)
+ and then Nkind (Unit_Id) in N_Generic_Package_Declaration
+ | N_Generic_Subprogram_Declaration
+ | N_Package_Declaration
+ | N_Subprogram_Declaration
then
Find_Elaboration_Context (Parent (Unit_Id));
@@ -8103,12 +8109,12 @@ package body Sem_Elab is
Prag_Nam : Name_Id;
In_State : Processing_In_State)
is
- pragma Assert (Nam_In (Prag_Nam, Name_Elaborate, Name_Elaborate_All));
+ pragma Assert (Prag_Nam in Name_Elaborate | Name_Elaborate_All);
begin
-- Nothing to do when the need for prior elaboration came from a
-- partial finalization routine which occurs in an initialization
- -- context. This behaviour parallels that of the old ABE mechanism.
+ -- context. This behavior parallels that of the old ABE mechanism.
if In_State.Within_Partial_Finalization then
return;
@@ -8574,7 +8580,7 @@ package body Sem_Elab is
Req_Nam : Name_Id;
In_State : Processing_In_State)
is
- pragma Assert (Nam_In (Req_Nam, Name_Elaborate, Name_Elaborate_All));
+ pragma Assert (Req_Nam in Name_Elaborate | Name_Elaborate_All);
Main_Id : constant Entity_Id := Main_Unit_Entity;
Unit_Id : constant Entity_Id := Find_Top_Unit (Targ_Id);
@@ -8770,8 +8776,7 @@ package body Sem_Elab is
-- requirement.
if Present (Unit_Prag)
- and then Nam_In (Pragma_Name (Unit_Prag), Name_Elaborate_All,
- Req_Nam)
+ and then Pragma_Name (Unit_Prag) in Name_Elaborate_All | Req_Nam
then
Req_Met := True;
@@ -8851,6 +8856,29 @@ package body Sem_Elab is
return Elaboration_Phase = Active;
end Elaboration_Phase_Active;
+ ------------------------------
+ -- Error_Preelaborated_Call --
+ ------------------------------
+
+ procedure Error_Preelaborated_Call (N : Node_Id) is
+ begin
+ -- This is a warning in GNAT mode allowing such calls to be used in the
+ -- predefined library units with appropriate care.
+
+ Error_Msg_Warn := GNAT_Mode;
+
+ -- Ada 2020 (AI12-0175): Calls to certain functions that are essentially
+ -- unchecked conversions are preelaborable.
+
+ if Ada_Version >= Ada_2020 then
+ Error_Msg_N
+ ("<<non-preelaborable call not allowed in preelaborated unit", N);
+ else
+ Error_Msg_N
+ ("<<non-static call not allowed in preelaborated unit", N);
+ end if;
+ end Error_Preelaborated_Call;
+
----------------------------------
-- Finalize_All_Data_Structures --
----------------------------------
@@ -8877,10 +8905,10 @@ package body Sem_Elab is
Par := N;
while Present (Par) loop
- if Nkind_In (Par, N_Package_Body,
- N_Package_Declaration,
- N_Subprogram_Body,
- N_Subprogram_Declaration)
+ if Nkind (Par) in N_Package_Body
+ | N_Package_Declaration
+ | N_Subprogram_Body
+ | N_Subprogram_Declaration
and then Is_Generic_Instance (Unique_Defining_Entity (Par))
then
return Par;
@@ -8953,10 +8981,10 @@ package body Sem_Elab is
-- but are later relocated in a different context retain their original
-- declaration level.
- if Nkind_In (N, N_Call_Marker,
- N_Function_Instantiation,
- N_Package_Instantiation,
- N_Procedure_Instantiation)
+ if Nkind (N) in N_Call_Marker
+ | N_Function_Instantiation
+ | N_Package_Instantiation
+ | N_Procedure_Instantiation
and then Is_Declaration_Level_Node (N)
then
return Declaration_Level;
@@ -8977,7 +9005,7 @@ package body Sem_Elab is
-- they are always elaborated when the enclosing context is invoked
-- or elaborated.
- elsif Nkind_In (Curr, N_Package_Body, N_Package_Declaration) then
+ elsif Nkind (Curr) in N_Package_Body | N_Package_Declaration then
null;
-- The current construct is a block statement
@@ -9009,9 +9037,8 @@ package body Sem_Elab is
-- The current construct is a declaration-level encapsulator
- elsif Nkind_In (Curr, N_Entry_Body,
- N_Subprogram_Body,
- N_Task_Body)
+ elsif Nkind (Curr) in
+ N_Entry_Body | N_Subprogram_Body | N_Task_Body
then
-- If the traversal came from the handled sequence of statments,
-- then the node cannot possibly appear at any level. This is
@@ -9099,8 +9126,8 @@ package body Sem_Elab is
-- that of the "related instance".
elsif Nkind (N) = N_Package_Declaration
- and then Nkind_In (Orig_N, N_Function_Instantiation,
- N_Procedure_Instantiation)
+ and then Nkind (Orig_N) in
+ N_Function_Instantiation | N_Procedure_Instantiation
and then Nkind (Context) = N_Compilation_Unit
then
return Related_Instance (Defining_Entity (N));
@@ -9111,8 +9138,8 @@ package body Sem_Elab is
elsif Nkind (N) = N_Subunit
and then Nkind (Proper_Body (N)) = N_Null_Statement
- and then Nkind_In (Original_Node (Proper_Body (N)), N_Protected_Body,
- N_Task_Body)
+ and then Nkind (Original_Node (Proper_Body (N))) in
+ N_Protected_Body | N_Task_Body
then
return Defining_Entity (Original_Node (Proper_Body (N)));
@@ -9138,7 +9165,7 @@ package body Sem_Elab is
-- Handle various combinations of concurrent and private types
loop
- if Ekind_In (Typ, E_Protected_Type, E_Task_Type)
+ if Ekind (Typ) in E_Protected_Type | E_Task_Type
and then Present (Anonymous_Object (Typ))
then
Typ := Anonymous_Object (Typ);
@@ -9216,10 +9243,11 @@ package body Sem_Elab is
Target_Decl : Node_Id;
Target_Body : Node_Id) return Boolean
is
+ Spec : Node_Id;
begin
-- Avoid cascaded errors if there were previous serious infractions.
-- As a result the scenario will not be treated as a guaranteed ABE.
- -- This behaviour parallels that of the old ABE mechanism.
+ -- This behavior parallels that of the old ABE mechanism.
if Serious_Errors_Detected > 0 then
return False;
@@ -9236,12 +9264,20 @@ package body Sem_Elab is
return Earlier_In_Extended_Unit (N, Target_Body);
-- Otherwise the body has not been encountered yet. The scenario
- -- is a guaranteed ABE since the body will appear later. It is
- -- assumed that the caller has already ensured that the scenario
- -- is ABE-safe because optional bodies are not considered here.
+ -- is a guaranteed ABE since the body will appear later, unless
+ -- this is a null specification, which can occur if expansion is
+ -- disabled (e.g. -gnatc or GNATprove mode). It is assumed that
+ -- the caller has already ensured that the scenario is ABE-safe
+ -- because optional bodies are not considered here.
else
- return True;
+ Spec := Specification (Target_Decl);
+
+ if Nkind (Spec) /= N_Procedure_Specification
+ or else not Null_Present (Spec)
+ then
+ return True;
+ end if;
end if;
end if;
@@ -9544,7 +9580,7 @@ package body Sem_Elab is
Error_Msg_N ("\Program_Error will be raised at run time", Call);
end if;
- -- Mark the call as a guarnateed ABE
+ -- Mark the call as a guaranteed ABE
Set_Is_Known_Guaranteed_ABE (Call);
@@ -10872,13 +10908,10 @@ package body Sem_Elab is
elsif Is_Task_Type (Id) then
Rec := Create_Task_Rep (Id);
- elsif Ekind_In (Id, E_Constant, E_Variable) then
+ elsif Ekind (Id) in E_Constant | E_Variable then
Rec := Create_Variable_Rep (Id);
- elsif Ekind_In (Id, E_Entry,
- E_Function,
- E_Operator,
- E_Procedure)
+ elsif Ekind (Id) in E_Entry | E_Function | E_Operator | E_Procedure
then
Rec := Create_Subprogram_Rep (Id);
@@ -11907,6 +11940,7 @@ package body Sem_Elab is
Set_Is_Elaboration_Checks_OK_Node (Marker, False);
Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
Set_Is_Ignored_Ghost_Node (Marker, False);
+ Set_Is_Preelaborable_Call (Marker, False);
Set_Is_Source_Call (Marker, False);
Set_Is_SPARK_Mode_On_Node (Marker, False);
@@ -11946,6 +11980,7 @@ package body Sem_Elab is
Set_Is_Elaboration_Checks_OK_Node (Marker, False);
Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
Set_Is_Ignored_Ghost_Node (Marker, False);
+ Set_Is_Preelaborable_Call (Marker, False);
Set_Is_Source_Call (Marker, False);
Set_Is_SPARK_Mode_On_Node (Marker, False);
@@ -12053,14 +12088,13 @@ package body Sem_Elab is
-- The main unit is a body
- if Ekind_In (Main_Unit_Id, E_Package_Body,
- E_Subprogram_Body)
+ if Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
then
return In_Body;
-- The main unit is a stand-alone subprogram body
- elsif Ekind_In (Main_Unit_Id, E_Function, E_Procedure)
+ elsif Ekind (Main_Unit_Id) in E_Function | E_Procedure
and then Nkind (Unit_Declaration_Node (Main_Unit_Id)) =
N_Subprogram_Body
then
@@ -12075,8 +12109,7 @@ package body Sem_Elab is
-- Otherwise the node is in the complementary unit of the main
-- unit. The main unit is a body, the node is in the spec.
- elsif Ekind_In (Main_Unit_Id, E_Package_Body,
- E_Subprogram_Body)
+ elsif Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
then
return In_Spec;
@@ -12301,8 +12334,8 @@ package body Sem_Elab is
-- Protected type
- elsif Nkind_In (Decl, N_Protected_Type_Declaration,
- N_Single_Protected_Declaration)
+ elsif Nkind (Decl) in N_Protected_Type_Declaration
+ | N_Single_Protected_Declaration
then
Process_Protected_Type_Declaration
(Prot_Decl => Decl,
@@ -12310,8 +12343,8 @@ package body Sem_Elab is
-- Subprogram or entry
- elsif Nkind_In (Decl, N_Entry_Declaration,
- N_Subprogram_Declaration)
+ elsif Nkind (Decl) in N_Entry_Declaration
+ | N_Subprogram_Declaration
then
Process_Subprogram_Declaration
(Subp_Decl => Decl,
@@ -12335,8 +12368,8 @@ package body Sem_Elab is
-- Task type
- elsif Nkind_In (Decl, N_Single_Task_Declaration,
- N_Task_Type_Declaration)
+ elsif Nkind (Decl) in N_Single_Task_Declaration
+ | N_Task_Type_Declaration
then
Process_Task_Type_Declaration
(Task_Decl => Decl,
@@ -12456,7 +12489,7 @@ package body Sem_Elab is
-- Nothing to do for an abstract subprogram because it has no body to
-- examine.
- elsif Ekind_In (Subp_Id, E_Function, E_Procedure)
+ elsif Ekind (Subp_Id) in E_Function | E_Procedure
and then Is_Abstract_Subprogram (Subp_Id)
then
return;
@@ -12472,7 +12505,7 @@ package body Sem_Elab is
-- DFS traversal into its barrier function and body.
if In_Extended_Main_Code_Unit (Subp_Id) then
- if Ekind_In (Subp_Id, E_Entry, E_Entry_Family, E_Procedure) then
+ if Ekind (Subp_Id) in E_Entry | E_Entry_Family | E_Procedure then
Traverse_Invocation_Body
(N => Barrier_Body_Declaration (Subp_Rep),
In_State => In_State);
@@ -12852,8 +12885,8 @@ package body Sem_Elab is
-- Process the entries of the task type because they represent valid
-- entry points into the task body.
- if Nkind_In (Task_Decl, N_Single_Task_Declaration,
- N_Task_Type_Declaration)
+ if Nkind (Task_Decl) in N_Single_Task_Declaration
+ | N_Task_Type_Declaration
then
Task_Def := Task_Definition (Task_Decl);
@@ -13151,10 +13184,8 @@ package body Sem_Elab is
-- Entry, operator, or subprogram call. This case must come last
-- because most invocations above are variations of this case.
- elsif Ekind_In (Targ_Id, E_Entry,
- E_Function,
- E_Operator,
- E_Procedure)
+ elsif Ekind (Targ_Id) in
+ E_Entry | E_Function | E_Operator | E_Procedure
then
Extra := Empty;
Kind := Call;
@@ -13771,6 +13802,11 @@ package body Sem_Elab is
if not Is_Source_Call (Call) then
return;
+ -- Nothing to do when the call is preelaborable by definition
+
+ elsif Is_Preelaborable_Call (Call) then
+ return;
+
-- Library-level calls are always considered because they are part of
-- the associated unit's elaboration actions.
@@ -13792,13 +13828,10 @@ package body Sem_Elab is
return;
end if;
- -- The call appears within a preelaborated unit. Emit a warning only
- -- for internal uses, otherwise this is an error.
+ -- If the call appears within a preelaborated unit, give an error
if In_Preelaborated_Context (Call) then
- Error_Msg_Warn := GNAT_Mode;
- Error_Msg_N
- ("<<non-static call not allowed in preelaborated unit", Call);
+ Error_Preelaborated_Call (Call);
end if;
end Check_Preelaborated_Call;
@@ -13826,7 +13859,7 @@ package body Sem_Elab is
-- be on another machine.
if Ekind (Body_Id) = E_Package_Body
- and then Ekind_In (Spec_Id, E_Generic_Package, E_Package)
+ and then Is_Package_Or_Generic_Package (Spec_Id)
and then (Is_Remote_Call_Interface (Spec_Id)
or else Is_Remote_Types (Spec_Id))
then
@@ -14030,12 +14063,6 @@ package body Sem_Elab is
if Legacy_Elaboration_Checks then
return;
- -- Nothing to do for ASIS because ABE checks and diagnostics are not
- -- performed in this mode.
-
- elsif ASIS_Mode then
- return;
-
-- Nothing to do when the scenario is being preanalyzed
elsif Preanalysis_Active then
@@ -14423,9 +14450,7 @@ package body Sem_Elab is
begin
-- An abstract subprogram does not have a body
- if Ekind_In (Subp_Id, E_Function,
- E_Operator,
- E_Procedure)
+ if Ekind (Subp_Id) in E_Function | E_Operator | E_Procedure
and then Is_Abstract_Subprogram (Subp_Id)
then
return True;
@@ -14473,9 +14498,8 @@ package body Sem_Elab is
Formal_Id : Entity_Id;
begin
- pragma Assert (Nam_In (Subp_Nam, Name_Adjust,
- Name_Finalize,
- Name_Initialize));
+ pragma Assert
+ (Subp_Nam in Name_Adjust | Name_Finalize | Name_Initialize);
-- To qualify, the subprogram must denote a source procedure with
-- name Adjust, Finalize, or Initialize where the sole formal is
@@ -14663,7 +14687,7 @@ package body Sem_Elab is
-- protected type.
return
- Ekind_In (Id, E_Function, E_Procedure)
+ Ekind (Id) in E_Function | E_Procedure
and then Is_Protected_Type (Non_Private_View (Scope (Id)));
end Is_Protected_Subp;
@@ -14677,7 +14701,7 @@ package body Sem_Elab is
-- Protected_Subprogram set.
return
- Ekind_In (Id, E_Function, E_Procedure)
+ Ekind (Id) in E_Function | E_Procedure
and then Present (Protected_Subprogram (Id));
end Is_Protected_Body_Subp;
@@ -14729,7 +14753,7 @@ package body Sem_Elab is
-- is hidden within an anonymous package, and is a generic instance.
return
- Ekind_In (Id, E_Function, E_Procedure)
+ Ekind (Id) in E_Function | E_Procedure
and then Is_Hidden (Id)
and then Is_Generic_Instance (Id);
end Is_Subprogram_Inst;
@@ -14798,7 +14822,7 @@ package body Sem_Elab is
-- The attribute name must be one of the 'Access forms. Note that
-- 'Unchecked_Access cannot apply to a subprogram.
- and then Nam_In (Nam, Name_Access, Name_Unrestricted_Access);
+ and then Nam in Name_Access | Name_Unrestricted_Access;
end Is_Suitable_Access_Taken;
----------------------
@@ -14926,7 +14950,7 @@ package body Sem_Elab is
return False;
-- Assignments are ignored in GNAT mode on the assumption that
- -- they are ABE-safe. This behaviour parallels that of the old
+ -- they are ABE-safe. This behavior parallels that of the old
-- ABE mechanism.
elsif GNAT_Mode then
@@ -15832,10 +15856,10 @@ package body Sem_Elab is
-- Bodies
- if Nkind_In (N, N_Package_Body,
- N_Protected_Body,
- N_Subprogram_Body,
- N_Task_Body)
+ if Nkind (N) in N_Package_Body
+ | N_Protected_Body
+ | N_Subprogram_Body
+ | N_Task_Body
then
Spec_Id := Corresponding_Spec (N);
@@ -15855,13 +15879,13 @@ package body Sem_Elab is
-- Declarations
- elsif Nkind_In (N, N_Entry_Declaration,
- N_Generic_Package_Declaration,
- N_Generic_Subprogram_Declaration,
- N_Package_Declaration,
- N_Protected_Type_Declaration,
- N_Subprogram_Declaration,
- N_Task_Type_Declaration)
+ elsif Nkind (N) in N_Entry_Declaration
+ | N_Generic_Package_Declaration
+ | N_Generic_Subprogram_Declaration
+ | N_Package_Declaration
+ | N_Protected_Type_Declaration
+ | N_Subprogram_Declaration
+ | N_Task_Type_Declaration
then
Spec_Decl := N;
@@ -15935,12 +15959,12 @@ package body Sem_Elab is
begin
return
- Nkind_In (Decl, N_Generic_Package_Declaration,
- N_Generic_Subprogram_Declaration,
- N_Package_Declaration,
- N_Protected_Type_Declaration,
- N_Subprogram_Declaration,
- N_Task_Type_Declaration)
+ Nkind (Decl) in N_Generic_Package_Declaration
+ | N_Generic_Subprogram_Declaration
+ | N_Package_Declaration
+ | N_Protected_Type_Declaration
+ | N_Subprogram_Declaration
+ | N_Task_Type_Declaration
and then Present (Corresponding_Body (Decl))
and then Nkind (Parent (Unit_Declaration_Node
(Corresponding_Body (Decl)))) = N_Subunit;
@@ -16809,8 +16833,8 @@ package body Sem_Elab is
if Nkind (Decl) = N_Subprogram_Body then
Body_Acts_As_Spec := True;
- elsif Nkind_In (Decl, N_Subprogram_Declaration,
- N_Subprogram_Body_Stub)
+ elsif Nkind (Decl) in
+ N_Subprogram_Declaration | N_Subprogram_Body_Stub
or else Inst_Case
then
Body_Acts_As_Spec := False;
@@ -17486,8 +17510,7 @@ package body Sem_Elab is
P := Parent (N);
while Present (P) loop
- if Nkind_In (P, N_Parameter_Specification,
- N_Component_Declaration)
+ if Nkind (P) in N_Parameter_Specification | N_Component_Declaration
then
return;
@@ -17525,17 +17548,17 @@ package body Sem_Elab is
-- Complain if ref that comes from source in preelaborated unit
-- and we are not inside a subprogram (i.e. we are in elab code).
+ -- Ada 2020 (AI12-0175): Calls to certain functions that are
+ -- essentially unchecked conversions are preelaborable.
+
if Comes_From_Source (N)
and then In_Preelaborated_Unit
and then not In_Inlined_Body
and then Nkind (N) /= N_Attribute_Reference
+ and then not (Ada_Version >= Ada_2020
+ and then Is_Preelaborable_Construct (N))
then
- -- This is a warning in GNAT mode allowing such calls to be
- -- used in the predefined library with appropriate care.
-
- Error_Msg_Warn := GNAT_Mode;
- Error_Msg_N
- ("<<non-static call not allowed in preelaborated unit", N);
+ Error_Preelaborated_Call (N);
return;
end if;
@@ -17582,8 +17605,8 @@ package body Sem_Elab is
-- Filter out case of default expressions, where we do not
-- do the check at this stage.
- if Nkind_In (P, N_Parameter_Specification,
- N_Component_Declaration)
+ if Nkind (P) in
+ N_Parameter_Specification | N_Component_Declaration
then
return;
end if;
@@ -17594,10 +17617,10 @@ package body Sem_Elab is
if Nkind (P) = N_Protected_Body then
return;
- elsif Nkind_In (P, N_Subprogram_Body,
- N_Task_Body,
- N_Block_Statement,
- N_Entry_Body)
+ elsif Nkind (P) in N_Subprogram_Body
+ | N_Task_Body
+ | N_Block_Statement
+ | N_Entry_Body
then
if L = Declarations (P) then
exit;
@@ -17820,10 +17843,7 @@ package body Sem_Elab is
-- then there is nothing to do (we do not know what is being assigned),
-- but otherwise this is an assignment to the prefix.
- if Nkind_In (N, N_Indexed_Component,
- N_Selected_Component,
- N_Slice)
- then
+ if Nkind (N) in N_Indexed_Component | N_Selected_Component | N_Slice then
if not Is_Access_Type (Etype (Prefix (N))) then
Check_Elab_Assign (Prefix (N));
end if;
@@ -18248,9 +18268,9 @@ package body Sem_Elab is
-- If not function or procedure call, instantiation, or 'Access, then
-- ignore call (this happens in some error cases and rewriting cases).
- elsif not Nkind_In (N, N_Attribute_Reference,
- N_Function_Call,
- N_Procedure_Call_Statement)
+ elsif Nkind (N) not in N_Attribute_Reference
+ | N_Function_Call
+ | N_Procedure_Call_Statement
and then not Inst_Case
then
return;
@@ -18350,8 +18370,8 @@ package body Sem_Elab is
-- code, do not trace past an accept statement, because the rendez-
-- vous will happen after elaboration.
- if Nkind_In (Original_Node (N), N_Accept_Statement,
- N_Selective_Accept)
+ if Nkind (Original_Node (N)) in
+ N_Accept_Statement | N_Selective_Accept
and then Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
then
return Abandon;
@@ -18384,8 +18404,8 @@ package body Sem_Elab is
elsif not Debug_Flag_Dot_UU
and then Nkind (N) = N_Attribute_Reference
- and then Nam_In (Attribute_Name (N), Name_Access,
- Name_Unrestricted_Access)
+ and then
+ Attribute_Name (N) in Name_Access | Name_Unrestricted_Access
and then Is_Entity_Name (Prefix (N))
and then Is_Subprogram (Entity (Prefix (N)))
then
@@ -18466,7 +18486,7 @@ package body Sem_Elab is
Sbody := Unit_Declaration_Node (E);
- if not Nkind_In (Sbody, N_Subprogram_Body, N_Package_Body) then
+ if Nkind (Sbody) not in N_Subprogram_Body | N_Package_Body then
Ebody := Corresponding_Body (Sbody);
if No (Ebody) then
@@ -18560,7 +18580,7 @@ package body Sem_Elab is
-- Check we have an If statement or a null statement (happens
-- when the If has been expanded to be True).
- exit when not Nkind_In (P, N_If_Statement, N_Null_Statement);
+ exit when Nkind (P) not in N_If_Statement | N_Null_Statement;
-- Our special case will be indicated either by the pragma
-- coming from an aspect ...
@@ -18721,9 +18741,9 @@ package body Sem_Elab is
-- A rather specific check. For Finalize/Adjust/Initialize, if
-- the type has Warnings_Off set, suppress the warning.
- if Nam_In (Chars (E), Name_Adjust,
- Name_Finalize,
- Name_Initialize)
+ if Chars (E) in Name_Adjust
+ | Name_Finalize
+ | Name_Initialize
and then Present (First_Formal (E))
then
declare
@@ -18813,7 +18833,7 @@ package body Sem_Elab is
Comp := First_Component (Typ);
while Present (Comp) loop
Add_Task_Proc (Etype (Comp));
- Comp := Next_Component (Comp);
+ Next_Component (Comp);
end loop;
end if;
@@ -19341,7 +19361,7 @@ package body Sem_Elab is
function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean is
begin
- return Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement)
+ return Nkind (N) in N_Function_Call | N_Procedure_Call_Statement
-- Always return False if debug flag -gnatd.G is set
@@ -19508,7 +19528,7 @@ package body Sem_Elab is
S1 := Scop1;
while S1 /= Standard_Standard
and then not Is_Compilation_Unit (S1)
- and then Ekind_In (S1, E_Package, E_Protected_Type, E_Block)
+ and then Ekind (S1) in E_Package | E_Protected_Type | E_Block
loop
S1 := Scope (S1);
end loop;
@@ -19518,7 +19538,7 @@ package body Sem_Elab is
S2 := Scop2;
while S2 /= Standard_Standard
and then not Is_Compilation_Unit (S2)
- and then Ekind_In (S2, E_Package, E_Protected_Type, E_Block)
+ and then Ekind (S2) in E_Package | E_Protected_Type | E_Block
loop
S2 := Scope (S2);
end loop;
@@ -19643,7 +19663,7 @@ package body Sem_Elab is
-- Check for case of body entity
-- Why is the check for E_Void needed???
- if Ekind_In (E, E_Void, E_Subprogram_Body, E_Package_Body) then
+ if Ekind (E) in E_Void | E_Subprogram_Body | E_Package_Body then
Decl := E;
loop