1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S E M _ E L A B --
-- --
-- S p e c --
-- --
-- Copyright (C) 1997-2022, 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- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING3. If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- This package contains routines which handle access-before-elaboration
-- run-time checks and compile-time diagnostics. See the body for details.
with Types; use Types;
package Sem_Elab is
-----------
-- Types --
-----------
-- The following type classifies the various enclosing levels used in ABE
-- diagnostics.
type Enclosing_Level_Kind is
(Declaration_Level,
-- A construct is at the "declaration level" when it appears within the
-- declarations of a block statement, an entry body, a subprogram body,
-- or a task body, ignoring enclosing packages. Example:
-- package Pack is
-- procedure Proc is -- subprogram body
-- package Nested is -- enclosing package ignored
-- X ... -- at declaration level
Generic_Spec_Level,
Generic_Body_Level,
-- A construct is at the "generic level" when it appears in a
-- generic package library unit, ignoring enclosing packages. Example:
-- generic
-- package Pack is -- generic package spec
-- package Nested is -- enclosing package ignored
-- X ... -- at generic library level
Instantiation_Level,
-- A construct is at the "instantiation library level" when it appears
-- in a library unit which is also an instantiation. Example:
-- package Inst is new Gen; -- at instantiation level
Library_Spec_Level,
Library_Body_Level,
-- A construct is at the "library level" when it appears in a package
-- library unit, ignoring enclosing packages. Example:
-- package body Pack is -- package body
-- package Nested is -- enclosing package ignored
-- X ... -- at library level
No_Level);
-- This value is used to indicate that none of the levels above are in
-- effect.
subtype Generic_Level is Enclosing_Level_Kind range
Generic_Spec_Level ..
Generic_Body_Level;
subtype Library_Level is Enclosing_Level_Kind range
Library_Spec_Level ..
Library_Body_Level;
subtype Library_Or_Instantiation_Level is Enclosing_Level_Kind range
Instantiation_Level ..
Library_Body_Level;
procedure Build_Call_Marker (N : Node_Id);
pragma Inline (Build_Call_Marker);
-- Create a call marker for call or requeue statement N and record it for
-- later processing by the ABE mechanism.
procedure Build_Variable_Reference_Marker
(N : Node_Id;
Read : Boolean;
Write : Boolean);
pragma Inline (Build_Variable_Reference_Marker);
-- Create a variable reference marker for arbitrary node N if it mentions a
-- variable, and record it for later processing by the ABE mechanism. Flag
-- Read should be set when the reference denotes a read. Flag Write should
-- be set when the reference denotes a write.
procedure Check_Elaboration_Scenarios;
-- Examine each scenario recorded during analysis/resolution and apply the
-- Ada or SPARK elaboration rules taking into account the model in effect.
-- This processing detects and diagnoses ABE issues, installs conditional
-- ABE checks or guaranteed ABE failures, and ensures the elaboration of
-- units.
function Find_Enclosing_Level (N : Node_Id) return Enclosing_Level_Kind;
pragma Inline (Find_Enclosing_Level);
-- Determine the enclosing level of arbitrary node N
procedure Initialize;
pragma Inline (Initialize);
-- Initialize the internal structures of this unit
procedure Kill_Elaboration_Scenario (N : Node_Id);
-- Determine whether arbitrary node N denotes a scenario which requires
-- ABE diagnostics or runtime checks and eliminate it from a region with
-- dead code.
procedure Record_Elaboration_Scenario (N : Node_Id);
pragma Inline (Record_Elaboration_Scenario);
-- Determine whether atribtray node N denotes a scenario which requires
-- ABE diagnostics or runtime checks. If this is the case, store N for
-- later processing.
---------------------------------------------------------------------------
-- --
-- L E G A C Y A C C E S S B E F O R E E L A B O R A T I O N --
-- --
-- M E C H A N I S M --
-- --
---------------------------------------------------------------------------
-- This section contains the implementation of the pre-18.x Legacy ABE
-- Mechanism. The mechanism can be activated using switch -gnatH (legacy
-- elaboration checking mode enabled).
procedure Check_Elab_Assign (N : Node_Id);
-- N is either the left side of an assignment, or a procedure argument for
-- a mode OUT or IN OUT formal. This procedure checks for a possible case
-- of access to an entity from elaboration code before the entity has been
-- initialized, and issues appropriate warnings.
procedure Check_Elab_Call
(N : Node_Id;
Outer_Scope : Entity_Id := Empty;
In_Init_Proc : Boolean := False);
-- Check a call for possible elaboration problems. The node N is either an
-- N_Function_Call or N_Procedure_Call_Statement node or an access
-- attribute reference whose prefix is a subprogram.
--
-- If SPARK_Mode is On, then N can also be a variable reference, since
-- SPARK requires the use of Elaborate_All for references to variables
-- in other packages.
-- The Outer_Scope argument indicates whether this is an outer level
-- call from Sem_Res (Outer_Scope set to Empty), or an internal recursive
-- call (Outer_Scope set to entity of outermost call, see body). The flag
-- In_Init_Proc should be set whenever the current context is a type
-- init proc.
-- Note: this might better be called Check_Elab_Reference (to recognize
-- the SPARK case), but we prefer to keep the original name, since this
-- is primarily used for checking for calls that could generate an ABE).
procedure Check_Elab_Calls;
-- Not all the processing for Check_Elab_Call can be done at the time
-- of calls to Check_Elab_Call. This is because for internal calls, we
-- need to wait to complete the check until all generic bodies have been
-- instantiated. The Check_Elab_Calls procedure cleans up these waiting
-- checks. It is called once after the completion of instantiation.
procedure Check_Elab_Instantiation
(N : Node_Id;
Outer_Scope : Entity_Id := Empty);
-- Check an instantiation for possible elaboration problems. N is an
-- instantiation node (N_Package_Instantiation, N_Function_Instantiation,
-- or N_Procedure_Instantiation), and Outer_Scope indicates if this is
-- an outer level call from Sem_Ch12 (Outer_Scope set to Empty), or an
-- internal recursive call (Outer_Scope set to scope of outermost call,
-- see body for further details). The returned value is relevant only
-- for an outer level call, and is set to False if an elaboration error
-- is bound to occur on the instantiation, and True otherwise. This is
-- used by the caller to signal that the body of the instance should
-- not be generated (see detailed description in body).
procedure Check_Task_Activation (N : Node_Id);
-- At the point at which tasks are activated in a package body, check
-- that the bodies of the tasks are elaborated.
end Sem_Elab;
|