hppa: Revise REG+D address support to allow long displacements before reload
[official-gcc.git] / gcc / ada / sem_elab.adb
blob46bad04a88972eb724c29b889e96abf6d26a40a0
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S E M _ E L A B --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1997-2023, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with ALI; use ALI;
27 with Atree; use Atree;
28 with Checks; use Checks;
29 with Debug; use Debug;
30 with Einfo; use Einfo;
31 with Einfo.Entities; use Einfo.Entities;
32 with Einfo.Utils; use Einfo.Utils;
33 with Elists; use Elists;
34 with Errout; use Errout;
35 with Exp_Ch11; use Exp_Ch11;
36 with Exp_Tss; use Exp_Tss;
37 with Exp_Util; use Exp_Util;
38 with Expander; use Expander;
39 with Lib; use Lib;
40 with Lib.Load; use Lib.Load;
41 with Namet; use Namet;
42 with Nlists; use Nlists;
43 with Nmake; use Nmake;
44 with Opt; use Opt;
45 with Output; use Output;
46 with Restrict; use Restrict;
47 with Rident; use Rident;
48 with Rtsfind; use Rtsfind;
49 with Sem; use Sem;
50 with Sem_Aux; use Sem_Aux;
51 with Sem_Cat; use Sem_Cat;
52 with Sem_Ch7; use Sem_Ch7;
53 with Sem_Ch8; use Sem_Ch8;
54 with Sem_Disp; use Sem_Disp;
55 with Sem_Prag; use Sem_Prag;
56 with Sem_Util; use Sem_Util;
57 with Sinfo; use Sinfo;
58 with Sinfo.Nodes; use Sinfo.Nodes;
59 with Sinfo.Utils; use Sinfo.Utils;
60 with Sinput; use Sinput;
61 with Snames; use Snames;
62 with Stand; use Stand;
63 with Table;
64 with Tbuild; use Tbuild;
65 with Uintp; use Uintp;
66 with Uname; use Uname;
67 with Warnsw; use Warnsw;
69 with GNAT; use GNAT;
70 with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
71 with GNAT.Lists; use GNAT.Lists;
72 with GNAT.Sets; use GNAT.Sets;
74 package body Sem_Elab is
76 -----------------------------------------
77 -- Access-before-elaboration mechanism --
78 -----------------------------------------
80 -- The access-before-elaboration (ABE) mechanism implemented in this unit
81 -- has the following objectives:
83 -- * Diagnose at compile time or install run-time checks to prevent ABE
84 -- access to data and behavior.
86 -- The high-level idea is to accurately diagnose ABE issues within a
87 -- single unit because the ABE mechanism can inspect the whole unit.
88 -- As soon as the elaboration graph extends to an external unit, the
89 -- diagnostics stop because the body of the unit may not be available.
90 -- Due to control and data flow, the ABE mechanism cannot accurately
91 -- determine whether a particular scenario will be elaborated or not.
92 -- Conditional ABE checks are therefore used to verify the elaboration
93 -- status of local and external targets at run time.
95 -- * Supply implicit elaboration dependencies for a unit to binde
97 -- The ABE mechanism creates implicit dependencies in the form of with
98 -- clauses subject to pragma Elaborate[_All] when the elaboration graph
99 -- reaches into an external unit. The implicit dependencies are encoded
100 -- in the ALI file of the main unit. GNATbind and binde then use these
101 -- dependencies to augment the library item graph and determine the
102 -- elaboration order of all units in the compilation.
104 -- * Supply pieces of the invocation graph for a unit to bindo
106 -- The ABE mechanism captures paths starting from elaboration code or
107 -- top level constructs that reach into an external unit. The paths are
108 -- encoded in the ALI file of the main unit in the form of declarations
109 -- which represent nodes, and relations which represent edges. GNATbind
110 -- and bindo then build the full invocation graph in order to augment
111 -- the library item graph and determine the elaboration order of all
112 -- units in the compilation.
114 -- The ABE mechanism supports three models of elaboration:
116 -- * Dynamic model - This is the most permissive of the three models.
117 -- When the dynamic model is in effect, the mechanism diagnoses and
118 -- installs run-time checks to detect ABE issues in the main unit.
119 -- The behavior of this model is identical to that specified by the
120 -- Ada RM. This model is enabled with switch -gnatE.
122 -- Static model - This is the middle ground of the three models. When
123 -- the static model is in effect, the mechanism diagnoses and installs
124 -- run-time checks to detect ABE issues in the main unit. In addition,
125 -- the mechanism generates implicit dependencies between units in the
126 -- form of with clauses subject to pragma Elaborate[_All] to ensure
127 -- the prior elaboration of withed units. This is the default model.
129 -- * SPARK model - This is the most conservative of the three models and
130 -- implements the semantics defined in SPARK RM 7.7. The SPARK model
131 -- is in effect only when a context resides in a SPARK_Mode On region,
132 -- otherwise the mechanism falls back to one of the previous models.
134 -- The ABE mechanism consists of a "recording" phase and a "processing"
135 -- phase.
137 -----------------
138 -- Terminology --
139 -----------------
141 -- * ABE - An attempt to invoke a scenario which has not been elaborated
142 -- yet.
144 -- * Bridge target - A type of target. A bridge target is a link between
145 -- scenarios. It is usually a byproduct of expansion and does not have
146 -- any direct ABE ramifications.
148 -- * Call marker - A special node used to indicate the presence of a call
149 -- in the tree in case expansion transforms or eliminates the original
150 -- call. N_Call_Marker nodes do not have static and run-time semantics.
152 -- * Conditional ABE - A type of ABE. A conditional ABE occurs when the
153 -- invocation of a target by a scenario within the main unit causes an
154 -- ABE, but does not cause an ABE for another scenarios within the main
155 -- unit.
157 -- * Declaration level - A type of enclosing level. A scenario or target is
158 -- at the declaration level when it appears within the declarations of a
159 -- block statement, entry body, subprogram body, or task body, ignoring
160 -- enclosing packages.
162 -- * Early call region - A section of code which ends at a subprogram body
163 -- and starts from the nearest non-preelaborable construct which precedes
164 -- the subprogram body. The early call region extends from a package body
165 -- to a package spec when the spec carries pragma Elaborate_Body.
167 -- * Generic library level - A type of enclosing level. A scenario or
168 -- target is at the generic library level if it appears in a generic
169 -- package library unit, ignoring enclosing packages.
171 -- * Guaranteed ABE - A type of ABE. A guaranteed ABE occurs when the
172 -- invocation of a target by all scenarios within the main unit causes
173 -- an ABE.
175 -- * Instantiation library level - A type of enclosing level. A scenario
176 -- or target is at the instantiation library level if it appears in an
177 -- instantiation library unit, ignoring enclosing packages.
179 -- * Invocation - The act of activating a task, calling a subprogram, or
180 -- instantiating a generic.
182 -- * Invocation construct - An entry declaration, [single] protected type,
183 -- subprogram declaration, subprogram instantiation, or a [single] task
184 -- type declared in the visible, private, or body declarations of the
185 -- main unit.
187 -- * Invocation relation - A flow link between two invocation constructs
189 -- * Invocation signature - A set of attributes that uniquely identify an
190 -- invocation construct within the namespace of all ALI files.
192 -- * Library level - A type of enclosing level. A scenario or target is at
193 -- the library level if it appears in a package library unit, ignoring
194 -- enclosing packages.
196 -- * Non-library-level encapsulator - A construct that cannot be elaborated
197 -- on its own and requires elaboration by a top-level scenario.
199 -- * Scenario - A construct or context which is invoked by elaboration code
200 -- or invocation construct. The scenarios recognized by the ABE mechanism
201 -- are as follows:
203 -- - '[Unrestricted_]Access of entries, operators, and subprograms
205 -- - Assignments to variables
207 -- - Calls to entries, operators, and subprograms
209 -- - Derived type declarations
211 -- - Instantiations
213 -- - Pragma Refined_State
215 -- - Reads of variables
217 -- - Task activation
219 -- * Target - A construct invoked by a scenario. The targets recognized by
220 -- the ABE mechanism are as follows:
222 -- - For '[Unrestricted_]Access of entries, operators, and subprograms,
223 -- the target is the entry, operator, or subprogram.
225 -- - For assignments to variables, the target is the variable
227 -- - For calls, the target is the entry, operator, or subprogram
229 -- - For derived type declarations, the target is the derived type
231 -- - For instantiations, the target is the generic template
233 -- - For pragma Refined_State, the targets are the constituents
235 -- - For reads of variables, the target is the variable
237 -- - For task activation, the target is the task body
239 ------------------
240 -- Architecture --
241 ------------------
243 -- Analysis/Resolution
244 -- |
245 -- +- Build_Call_Marker
246 -- |
247 -- +- Build_Variable_Reference_Marker
248 -- |
249 -- +- | -------------------- Recording phase ---------------------------+
250 -- | v |
251 -- | Record_Elaboration_Scenario |
252 -- | | |
253 -- | +--> Check_Preelaborated_Call |
254 -- | | |
255 -- | +--> Process_Guaranteed_ABE |
256 -- | | | |
257 -- | | +--> Process_Guaranteed_ABE_Activation |
258 -- | | +--> Process_Guaranteed_ABE_Call |
259 -- | | +--> Process_Guaranteed_ABE_Instantiation |
260 -- | | |
261 -- +- | ----------------------------------------------------------------+
262 -- |
263 -- |
264 -- +--> Internal_Representation
265 -- |
266 -- +--> Scenario_Storage
267 -- |
268 -- End of Compilation
269 -- |
270 -- +- | --------------------- Processing phase -------------------------+
271 -- | v |
272 -- | Check_Elaboration_Scenarios |
273 -- | | |
274 -- | +--> Check_Conditional_ABE_Scenarios |
275 -- | | | |
276 -- | | +--> Process_Conditional_ABE <----------------------+ |
277 -- | | | | |
278 -- | | +--> Process_Conditional_ABE_Activation | |
279 -- | | | | | |
280 -- | | | +-----------------------------+ | |
281 -- | | | | | |
282 -- | | +--> Process_Conditional_ABE_Call +---> Traverse_Body |
283 -- | | | | | |
284 -- | | | +-----------------------------+ |
285 -- | | | |
286 -- | | +--> Process_Conditional_ABE_Access_Taken |
287 -- | | +--> Process_Conditional_ABE_Instantiation |
288 -- | | +--> Process_Conditional_ABE_Variable_Assignment |
289 -- | | +--> Process_Conditional_ABE_Variable_Reference |
290 -- | | |
291 -- | +--> Check_SPARK_Scenario |
292 -- | | | |
293 -- | | +--> Process_SPARK_Scenario |
294 -- | | | |
295 -- | | +--> Process_SPARK_Derived_Type |
296 -- | | +--> Process_SPARK_Instantiation |
297 -- | | +--> Process_SPARK_Refined_State_Pragma |
298 -- | | |
299 -- | +--> Record_Invocation_Graph |
300 -- | | |
301 -- | +--> Process_Invocation_Body_Scenarios |
302 -- | +--> Process_Invocation_Spec_Scenarios |
303 -- | +--> Process_Main_Unit |
304 -- | | |
305 -- | +--> Process_Invocation_Scenario <-------------+ |
306 -- | | | |
307 -- | +--> Process_Invocation_Activation | |
308 -- | | | | |
309 -- | | +------------------------+ | |
310 -- | | | | |
311 -- | +--> Process_Invocation_Call +---> Traverse_Body |
312 -- | | | |
313 -- | +------------------------+ |
314 -- | |
315 -- +--------------------------------------------------------------------+
317 ---------------------
318 -- Recording phase --
319 ---------------------
321 -- The Recording phase coincides with the analysis/resolution phase of the
322 -- compiler. It has the following objectives:
324 -- * Record all suitable scenarios for examination by the Processing
325 -- phase.
327 -- Saving only a certain number of nodes improves the performance of
328 -- the ABE mechanism. This eliminates the need to examine the whole
329 -- tree in a separate pass.
331 -- * Record certain SPARK scenarios which are not necessarily invoked
332 -- during elaboration, but still require elaboration-related checks.
334 -- Saving only a certain number of nodes improves the performance of
335 -- the ABE mechanism. This eliminates the need to examine the whole
336 -- tree in a separate pass.
338 -- * Detect and diagnose calls in preelaborable or pure units, including
339 -- generic bodies.
341 -- This diagnostic is carried out during the Recording phase because it
342 -- does not need the heavy recursive traversal done by the Processing
343 -- phase.
345 -- * Detect and diagnose guaranteed ABEs caused by instantiations, calls,
346 -- and task activation.
348 -- The issues detected by the ABE mechanism are reported as warnings
349 -- because they do not violate Ada semantics. Forward instantiations
350 -- may thus reach gigi, however gigi cannot handle certain kinds of
351 -- premature instantiations and may crash. To avoid this limitation,
352 -- the ABE mechanism must identify forward instantiations as early as
353 -- possible and suppress their bodies. Calls and task activations are
354 -- included in this category for completeness.
356 ----------------------
357 -- Processing phase --
358 ----------------------
360 -- The Processing phase is a separate pass which starts after instantiating
361 -- and/or inlining of bodies, but before the removal of Ghost code. It has
362 -- the following objectives:
364 -- * Examine all scenarios saved during the Recording phase, and perform
365 -- the following actions:
367 -- - Dynamic model
369 -- Diagnose conditional ABEs, and install run-time conditional ABE
370 -- checks for all scenarios.
372 -- - SPARK model
374 -- Enforce the SPARK elaboration rules
376 -- - Static model
378 -- Diagnose conditional ABEs, install run-time conditional ABE
379 -- checks only for scenarios are reachable from elaboration code,
380 -- and guarantee the elaboration of external units by creating
381 -- implicit with clauses subject to pragma Elaborate[_All].
383 -- * Examine library-level scenarios and invocation constructs, and
384 -- perform the following actions:
386 -- - Determine whether the flow of execution reaches into an external
387 -- unit. If this is the case, encode the path in the ALI file of
388 -- the main unit.
390 -- - Create declarations for invocation constructs in the ALI file of
391 -- the main unit.
393 ----------------------
394 -- Important points --
395 ----------------------
397 -- The Processing phase starts after the analysis, resolution, expansion
398 -- phase has completed. As a result, no current semantic information is
399 -- available. The scope stack is empty, global flags such as In_Instance
400 -- or Inside_A_Generic become useless. To remedy this, the ABE mechanism
401 -- must either save or recompute semantic information.
403 -- Expansion heavily transforms calls and to some extent instantiations. To
404 -- remedy this, the ABE mechanism generates N_Call_Marker nodes in order to
405 -- capture the target and relevant attributes of the original call.
407 -- The diagnostics of the ABE mechanism depend on accurate source locations
408 -- to determine the spatial relation of nodes.
410 -----------------------------------------
411 -- Suppression of elaboration warnings --
412 -----------------------------------------
414 -- Elaboration warnings along multiple traversal paths rooted at a scenario
415 -- are suppressed when the scenario has elaboration warnings suppressed.
417 -- Root scenario
418 -- |
419 -- +-- Child scenario 1
420 -- | |
421 -- | +-- Grandchild scenario 1
422 -- | |
423 -- | +-- Grandchild scenario N
424 -- |
425 -- +-- Child scenario N
427 -- If the root scenario has elaboration warnings suppressed, then all its
428 -- child, grandchild, etc. scenarios will have their elaboration warnings
429 -- suppressed.
431 -- In addition to switch -gnatwL, pragma Warnings may be used to suppress
432 -- elaboration-related warnings when used in the following manner:
434 -- pragma Warnings ("L");
435 -- <scenario-or-target>
437 -- <target>
438 -- pragma Warnings (Off, target);
440 -- pragma Warnings (Off);
441 -- <scenario-or-target>
443 -- * To suppress elaboration warnings for '[Unrestricted_]Access of
444 -- entries, operators, and subprograms, either:
446 -- - Suppress the entry, operator, or subprogram, or
447 -- - Suppress the attribute, or
448 -- - Use switch -gnatw.f
450 -- * To suppress elaboration warnings for calls to entries, operators,
451 -- and subprograms, either:
453 -- - Suppress the entry, operator, or subprogram, or
454 -- - Suppress the call
456 -- * To suppress elaboration warnings for instantiations, suppress the
457 -- instantiation.
459 -- * To suppress elaboration warnings for task activations, either:
461 -- - Suppress the task object, or
462 -- - Suppress the task type, or
463 -- - Suppress the activation call
465 --------------
466 -- Switches --
467 --------------
469 -- The following switches may be used to control the behavior of the ABE
470 -- mechanism.
472 -- -gnatd_a stop elaboration checks on accept or select statement
474 -- The ABE mechanism stops the traversal of a task body when it
475 -- encounters an accept or a select statement. This behavior is
476 -- equivalent to restriction No_Entry_Calls_In_Elaboration_Code,
477 -- but without penalizing actual entry calls during elaboration.
479 -- -gnatd_e ignore entry calls and requeue statements for elaboration
481 -- The ABE mechanism does not generate N_Call_Marker nodes for
482 -- protected or task entry calls as well as requeue statements.
483 -- As a result, the calls and requeues are not recorded or
484 -- processed.
486 -- -gnatdE elaboration checks on predefined units
488 -- The ABE mechanism considers scenarios which appear in internal
489 -- units (Ada, GNAT, Interfaces, System).
491 -- -gnatd_F encode full invocation paths in ALI files
493 -- The ABE mechanism encodes the full path from an elaboration
494 -- procedure or invocable construct to an external target. The
495 -- path contains all intermediate activations, instantiations,
496 -- and calls.
498 -- -gnatd.G ignore calls through generic formal parameters for elaboration
500 -- The ABE mechanism does not generate N_Call_Marker nodes for
501 -- calls which occur in expanded instances, and invoke generic
502 -- actual subprograms through generic formal subprograms. As a
503 -- result, the calls are not recorded or processed.
505 -- -gnatd_i ignore activations and calls to instances for elaboration
507 -- The ABE mechanism ignores calls and task activations when they
508 -- target a subprogram or task type defined an external instance.
509 -- As a result, the calls and task activations are not processed.
511 -- -gnatdL ignore external calls from instances for elaboration
513 -- The ABE mechanism does not generate N_Call_Marker nodes for
514 -- calls which occur in expanded instances, do not invoke generic
515 -- actual subprograms through formal subprograms, and the target
516 -- is external to the instance. As a result, the calls are not
517 -- recorded or processed.
519 -- -gnatd.o conservative elaboration order for indirect calls
521 -- The ABE mechanism treats '[Unrestricted_]Access of an entry,
522 -- operator, or subprogram as an immediate invocation of the
523 -- target. As a result, it performs ABE checks and diagnostics on
524 -- the immediate call.
526 -- -gnatd_p ignore assertion pragmas for elaboration
528 -- The ABE mechanism does not generate N_Call_Marker nodes for
529 -- calls to subprograms which verify the run-time semantics of
530 -- the following assertion pragmas:
532 -- Default_Initial_Condition
533 -- Initial_Condition
534 -- Invariant
535 -- Invariant'Class
536 -- Post
537 -- Post'Class
538 -- Postcondition
539 -- Type_Invariant
540 -- Type_Invariant_Class
542 -- As a result, the assertion expressions of the pragmas are not
543 -- processed.
545 -- -gnatd_s stop elaboration checks on synchronous suspension
547 -- The ABE mechanism stops the traversal of a task body when it
548 -- encounters a call to one of the following routines:
550 -- Ada.Synchronous_Barriers.Wait_For_Release
551 -- Ada.Synchronous_Task_Control.Suspend_Until_True
553 -- -gnatd_T output trace information on invocation relation construction
555 -- The ABE mechanism outputs text information concerning relation
556 -- construction to standard output.
558 -- -gnatd.U ignore indirect calls for static elaboration
560 -- The ABE mechanism does not consider '[Unrestricted_]Access of
561 -- entries, operators, and subprograms. As a result, the scenarios
562 -- are not recorder or processed.
564 -- -gnatd.v enforce SPARK elaboration rules in SPARK code
566 -- The ABE mechanism applies some of the SPARK elaboration rules
567 -- defined in the SPARK reference manual, chapter 7.7. Note that
568 -- certain rules are always enforced, regardless of whether the
569 -- switch is active.
571 -- -gnatd.y disable implicit pragma Elaborate_All on task bodies
573 -- The ABE mechanism does not generate implicit Elaborate_All when
574 -- the need for the pragma came from a task body.
576 -- -gnatE dynamic elaboration checking mode enabled
578 -- The ABE mechanism assumes that any scenario is elaborated or
579 -- invoked by elaboration code. The ABE mechanism performs very
580 -- little diagnostics and generates condintional ABE checks to
581 -- detect ABE issues at run-time.
583 -- -gnatel turn on info messages on generated Elaborate[_All] pragmas
585 -- The ABE mechanism produces information messages on generated
586 -- implicit Elabote[_All] pragmas along with traceback showing
587 -- why the pragma was generated. In addition, the ABE mechanism
588 -- produces information messages for each scenario elaborated or
589 -- invoked by elaboration code.
591 -- -gnateL turn off info messages on generated Elaborate[_All] pragmas
593 -- The complementary switch for -gnatel.
595 -- -gnatH legacy elaboration checking mode enabled
597 -- When this switch is in effect, the pre-18.x ABE model becomes
598 -- the de facto ABE model. This amounts to cutting off all entry
599 -- points into the new ABE mechanism, and giving full control to
600 -- the old ABE mechanism.
602 -- -gnatJ permissive elaboration checking mode enabled
604 -- This switch activates the following switches:
606 -- -gnatd_a
607 -- -gnatd_e
608 -- -gnatd.G
609 -- -gnatd_i
610 -- -gnatdL
611 -- -gnatd_p
612 -- -gnatd_s
613 -- -gnatd.U
614 -- -gnatd.y
616 -- IMPORTANT: The behavior of the ABE mechanism becomes more
617 -- permissive at the cost of accurate diagnostics and runtime
618 -- ABE checks.
620 -- -gnatw.f turn on warnings for suspicious Subp'Access
622 -- The ABE mechanism treats '[Unrestricted_]Access of an entry,
623 -- operator, or subprogram as a pseudo invocation of the target.
624 -- As a result, it performs ABE diagnostics on the pseudo call.
626 -- -gnatw.F turn off warnings for suspicious Subp'Access
628 -- The complementary switch for -gnatw.f.
630 -- -gnatwl turn on warnings for elaboration problems
632 -- The ABE mechanism produces warnings on detected ABEs along with
633 -- a traceback showing the graph of the ABE.
635 -- -gnatwL turn off warnings for elaboration problems
637 -- The complementary switch for -gnatwl.
639 --------------------------
640 -- Debugging ABE issues --
641 --------------------------
643 -- * If the issue involves a call, ensure that the call is eligible for ABE
644 -- processing and receives a corresponding call marker. The routines of
645 -- interest are
647 -- Build_Call_Marker
648 -- Record_Elaboration_Scenario
650 -- * If the issue involves an arbitrary scenario, ensure that the scenario
651 -- is either recorded, or is successfully recognized while traversing a
652 -- body. The routines of interest are
654 -- Record_Elaboration_Scenario
655 -- Process_Conditional_ABE
656 -- Process_Guaranteed_ABE
657 -- Traverse_Body
659 -- * If the issue involves a circularity in the elaboration order, examine
660 -- the ALI files and look for the following encodings next to units:
662 -- E indicates a source Elaborate
664 -- EA indicates a source Elaborate_All
666 -- AD indicates an implicit Elaborate_All
668 -- ED indicates an implicit Elaborate
670 -- If possible, compare these encodings with those generated by the old
671 -- ABE mechanism. The routines of interest are
673 -- Ensure_Prior_Elaboration
675 -----------
676 -- Kinds --
677 -----------
679 -- The following type enumerates all possible elaboration phase statutes
681 type Elaboration_Phase_Status is
682 (Inactive,
683 -- The elaboration phase of the compiler has not started yet
685 Active,
686 -- The elaboration phase of the compiler is currently in progress
688 Completed);
689 -- The elaboration phase of the compiler has finished
691 Elaboration_Phase : Elaboration_Phase_Status := Inactive;
692 -- The status of the elaboration phase. Use routine Set_Elaboration_Phase
693 -- to alter its value.
695 -- The following type enumerates all subprogram body traversal modes
697 type Body_Traversal_Kind is
698 (Deep_Traversal,
699 -- The traversal examines the internals of a subprogram
701 No_Traversal);
703 -- The following type enumerates all operation modes
705 type Processing_Kind is
706 (Conditional_ABE_Processing,
707 -- The ABE mechanism detects and diagnoses conditional ABEs for library
708 -- and declaration-level scenarios.
710 Dynamic_Model_Processing,
711 -- The ABE mechanism installs conditional ABE checks for all eligible
712 -- scenarios when the dynamic model is in effect.
714 Guaranteed_ABE_Processing,
715 -- The ABE mechanism detects and diagnoses guaranteed ABEs caused by
716 -- calls, instantiations, and task activations.
718 Invocation_Construct_Processing,
719 -- The ABE mechanism locates all invocation constructs within the main
720 -- unit and utilizes them as roots of miltiple DFS traversals aimed at
721 -- detecting transitions from the main unit to an external unit.
723 Invocation_Body_Processing,
724 -- The ABE mechanism utilizes all library-level body scenarios as roots
725 -- of miltiple DFS traversals aimed at detecting transitions from the
726 -- main unit to an external unit.
728 Invocation_Spec_Processing,
729 -- The ABE mechanism utilizes all library-level spec scenarios as roots
730 -- of miltiple DFS traversals aimed at detecting transitions from the
731 -- main unit to an external unit.
733 SPARK_Processing,
734 -- The ABE mechanism detects and diagnoses violations of the SPARK
735 -- elaboration rules for SPARK-specific scenarios.
737 No_Processing);
739 -- The following type enumerates all possible scenario kinds
741 type Scenario_Kind is
742 (Access_Taken_Scenario,
743 -- An attribute reference which takes 'Access or 'Unrestricted_Access of
744 -- an entry, operator, or subprogram.
746 Call_Scenario,
747 -- A call which invokes an entry, operator, or subprogram
749 Derived_Type_Scenario,
750 -- A declaration of a derived type. This is a SPARK-specific scenario.
752 Instantiation_Scenario,
753 -- An instantiation which instantiates a generic package or subprogram.
754 -- This scenario is also subject to SPARK-specific rules.
756 Refined_State_Pragma_Scenario,
757 -- A Refined_State pragma. This is a SPARK-specific scenario.
759 Task_Activation_Scenario,
760 -- A call which activates objects of various task types
762 Variable_Assignment_Scenario,
763 -- An assignment statement which modifies the value of some variable
765 Variable_Reference_Scenario,
766 -- A reference to a variable. This is a SPARK-specific scenario.
768 No_Scenario);
770 -- The following type enumerates all possible consistency models of target
771 -- and scenario representations.
773 type Representation_Kind is
774 (Inconsistent_Representation,
775 -- A representation is said to be "inconsistent" when it is created from
776 -- a partially analyzed tree. In such an environment, certain attributes
777 -- such as a completing body may not be available yet.
779 Consistent_Representation,
780 -- A representation is said to be "consistent" when it is created from a
781 -- fully analyzed tree, where all attributes are available.
783 No_Representation);
785 -- The following type enumerates all possible target kinds
787 type Target_Kind is
788 (Generic_Target,
789 -- A generic unit being instantiated
791 Package_Target,
792 -- The package form of an instantiation
794 Subprogram_Target,
795 -- An entry, operator, or subprogram being invoked, or aliased through
796 -- 'Access or 'Unrestricted_Access.
798 Task_Target,
799 -- A task being activated by an activation call
801 Variable_Target,
802 -- A variable being updated through an assignment statement, or read
803 -- through a variable reference.
805 No_Target);
807 -----------
808 -- Types --
809 -----------
811 procedure Destroy (NE : in out Node_Or_Entity_Id);
812 pragma Inline (Destroy);
813 -- Destroy node or entity NE
815 function Hash (NE : Node_Or_Entity_Id) return Bucket_Range_Type;
816 pragma Inline (Hash);
817 -- Obtain the hash value of key NE
819 -- The following is a general purpose list for nodes and entities
821 package NE_List is new Doubly_Linked_Lists
822 (Element_Type => Node_Or_Entity_Id,
823 "=" => "=",
824 Destroy_Element => Destroy);
826 -- The following is a general purpose map which relates nodes and entities
827 -- to lists of nodes and entities.
829 package NE_List_Map is new Dynamic_Hash_Tables
830 (Key_Type => Node_Or_Entity_Id,
831 Value_Type => NE_List.Doubly_Linked_List,
832 No_Value => NE_List.Nil,
833 Expansion_Threshold => 1.5,
834 Expansion_Factor => 2,
835 Compression_Threshold => 0.3,
836 Compression_Factor => 2,
837 "=" => "=",
838 Destroy_Value => NE_List.Destroy,
839 Hash => Hash);
841 -- The following is a general purpose membership set for nodes and entities
843 package NE_Set is new Membership_Sets
844 (Element_Type => Node_Or_Entity_Id,
845 "=" => "=",
846 Hash => Hash);
848 -- The following type captures relevant attributes which pertain to the
849 -- in state of the Processing phase.
851 type Processing_In_State is record
852 Processing : Processing_Kind := No_Processing;
853 -- Operation mode of the Processing phase. Once set, this value should
854 -- not be changed.
856 Representation : Representation_Kind := No_Representation;
857 -- Required level of scenario and target representation. Once set, this
858 -- value should not be changed.
860 Suppress_Checks : Boolean := False;
861 -- This flag is set when the Processing phase must not generate any ABE
862 -- checks.
864 Suppress_Implicit_Pragmas : Boolean := False;
865 -- This flag is set when the Processing phase must not generate any
866 -- implicit Elaborate[_All] pragmas.
868 Suppress_Info_Messages : Boolean := False;
869 -- This flag is set when the Processing phase must not emit any info
870 -- messages.
872 Suppress_Up_Level_Targets : Boolean := False;
873 -- This flag is set when the Processing phase must ignore up-level
874 -- targets.
876 Suppress_Warnings : Boolean := False;
877 -- This flag is set when the Processing phase must not emit any warnings
878 -- on elaboration problems.
880 Traversal : Body_Traversal_Kind := No_Traversal;
881 -- The subprogram body traversal mode. Once set, this value should not
882 -- be changed.
884 Within_Freezing_Actions : Boolean := False;
885 -- This flag is set when the Processing phase is currently examining a
886 -- scenario which was reached from the actions of a freeze node.
888 Within_Generic : Boolean := False;
889 -- This flag is set when the Processing phase is currently within a
890 -- generic unit.
892 Within_Initial_Condition : Boolean := False;
893 -- This flag is set when the Processing phase is currently examining a
894 -- scenario which was reached from an initial condition procedure.
896 Within_Partial_Finalization : Boolean := False;
897 -- This flag is set when the Processing phase is currently examining a
898 -- scenario which was reached from a partial finalization procedure.
900 Within_Task_Body : Boolean := False;
901 -- This flag is set when the Processing phase is currently examining a
902 -- scenario which was reached from a task body.
903 end record;
905 -- The following constants define the various operational states of the
906 -- Processing phase.
908 -- The conditional ABE state is used when processing scenarios that appear
909 -- at the declaration, instantiation, and library levels to detect errors
910 -- and install conditional ABE checks.
912 Conditional_ABE_State : constant Processing_In_State :=
913 (Processing => Conditional_ABE_Processing,
914 Representation => Consistent_Representation,
915 Traversal => Deep_Traversal,
916 others => False);
918 -- The dynamic model state is used to install conditional ABE checks when
919 -- switch -gnatE (dynamic elaboration checking mode enabled) is in effect.
921 Dynamic_Model_State : constant Processing_In_State :=
922 (Processing => Dynamic_Model_Processing,
923 Representation => Consistent_Representation,
924 Suppress_Implicit_Pragmas => True,
925 Suppress_Info_Messages => True,
926 Suppress_Up_Level_Targets => True,
927 Suppress_Warnings => True,
928 Traversal => No_Traversal,
929 others => False);
931 -- The guaranteed ABE state is used when processing scenarios that appear
932 -- at the declaration, instantiation, and library levels to detect errors
933 -- and install guarateed ABE failures.
935 Guaranteed_ABE_State : constant Processing_In_State :=
936 (Processing => Guaranteed_ABE_Processing,
937 Representation => Inconsistent_Representation,
938 Suppress_Implicit_Pragmas => True,
939 Traversal => No_Traversal,
940 others => False);
942 -- The invocation body state is used when processing scenarios that appear
943 -- at the body library level to encode paths that start from elaboration
944 -- code and ultimately reach into external units.
946 Invocation_Body_State : constant Processing_In_State :=
947 (Processing => Invocation_Body_Processing,
948 Representation => Consistent_Representation,
949 Suppress_Checks => True,
950 Suppress_Implicit_Pragmas => True,
951 Suppress_Info_Messages => True,
952 Suppress_Up_Level_Targets => True,
953 Suppress_Warnings => True,
954 Traversal => Deep_Traversal,
955 others => False);
957 -- The invocation construct state is used when processing constructs that
958 -- appear within the spec and body of the main unit and eventually reach
959 -- into external units.
961 Invocation_Construct_State : constant Processing_In_State :=
962 (Processing => Invocation_Construct_Processing,
963 Representation => Consistent_Representation,
964 Suppress_Checks => True,
965 Suppress_Implicit_Pragmas => True,
966 Suppress_Info_Messages => True,
967 Suppress_Up_Level_Targets => True,
968 Suppress_Warnings => True,
969 Traversal => Deep_Traversal,
970 others => False);
972 -- The invocation spec state is used when processing scenarios that appear
973 -- at the spec library level to encode paths that start from elaboration
974 -- code and ultimately reach into external units.
976 Invocation_Spec_State : constant Processing_In_State :=
977 (Processing => Invocation_Spec_Processing,
978 Representation => Consistent_Representation,
979 Suppress_Checks => True,
980 Suppress_Implicit_Pragmas => True,
981 Suppress_Info_Messages => True,
982 Suppress_Up_Level_Targets => True,
983 Suppress_Warnings => True,
984 Traversal => Deep_Traversal,
985 others => False);
987 -- The SPARK state is used when verying SPARK-specific semantics of certain
988 -- scenarios.
990 SPARK_State : constant Processing_In_State :=
991 (Processing => SPARK_Processing,
992 Representation => Consistent_Representation,
993 Traversal => No_Traversal,
994 others => False);
996 -- The following type identifies a scenario representation
998 type Scenario_Rep_Id is new Natural;
1000 No_Scenario_Rep : constant Scenario_Rep_Id := Scenario_Rep_Id'First;
1001 First_Scenario_Rep : constant Scenario_Rep_Id := No_Scenario_Rep + 1;
1003 -- The following type identifies a target representation
1005 type Target_Rep_Id is new Natural;
1007 No_Target_Rep : constant Target_Rep_Id := Target_Rep_Id'First;
1008 First_Target_Rep : constant Target_Rep_Id := No_Target_Rep + 1;
1010 --------------
1011 -- Services --
1012 --------------
1014 -- The following package keeps track of all active scenarios during a DFS
1015 -- traversal.
1017 package Active_Scenarios is
1019 -----------
1020 -- Types --
1021 -----------
1023 -- The following type defines the position within the active scenario
1024 -- stack.
1026 type Active_Scenario_Pos is new Natural;
1028 ---------------------
1029 -- Data structures --
1030 ---------------------
1032 -- The following table stores all active scenarios in a DFS traversal.
1033 -- This table must be maintained in a FIFO fashion.
1035 package Active_Scenario_Stack is new Table.Table
1036 (Table_Index_Type => Active_Scenario_Pos,
1037 Table_Component_Type => Node_Id,
1038 Table_Low_Bound => 1,
1039 Table_Initial => 50,
1040 Table_Increment => 200,
1041 Table_Name => "Active_Scenario_Stack");
1043 ---------
1044 -- API --
1045 ---------
1047 procedure Output_Active_Scenarios
1048 (Error_Nod : Node_Id;
1049 In_State : Processing_In_State);
1050 pragma Inline (Output_Active_Scenarios);
1051 -- Output the contents of the active scenario stack from earliest to
1052 -- latest to supplement an earlier error emitted for node Error_Nod.
1053 -- In_State denotes the current state of the Processing phase.
1055 procedure Pop_Active_Scenario (N : Node_Id);
1056 pragma Inline (Pop_Active_Scenario);
1057 -- Pop the top of the scenario stack. A check is made to ensure that the
1058 -- scenario being removed is the same as N.
1060 procedure Push_Active_Scenario (N : Node_Id);
1061 pragma Inline (Push_Active_Scenario);
1062 -- Push scenario N on top of the scenario stack
1064 function Root_Scenario return Node_Id;
1065 pragma Inline (Root_Scenario);
1066 -- Return the scenario which started a DFS traversal
1068 end Active_Scenarios;
1069 use Active_Scenarios;
1071 -- The following package provides the main entry point for task activation
1072 -- processing.
1074 package Activation_Processor is
1076 -----------
1077 -- Types --
1078 -----------
1080 type Activation_Processor_Ptr is access procedure
1081 (Call : Node_Id;
1082 Call_Rep : Scenario_Rep_Id;
1083 Obj_Id : Entity_Id;
1084 Obj_Rep : Target_Rep_Id;
1085 Task_Typ : Entity_Id;
1086 Task_Rep : Target_Rep_Id;
1087 In_State : Processing_In_State);
1088 -- Reference to a procedure that takes all attributes of an activation
1089 -- and performs a desired action. Call is the activation call. Call_Rep
1090 -- is the representation of the call. Obj_Id is the task object being
1091 -- activated. Obj_Rep is the representation of the object. Task_Typ is
1092 -- the task type whose body is being activated. Task_Rep denotes the
1093 -- representation of the task type. In_State is the current state of
1094 -- the Processing phase.
1096 ---------
1097 -- API --
1098 ---------
1100 procedure Process_Activation
1101 (Call : Node_Id;
1102 Call_Rep : Scenario_Rep_Id;
1103 Processor : Activation_Processor_Ptr;
1104 In_State : Processing_In_State);
1105 -- Find all task objects activated by activation call Call and invoke
1106 -- Processor on them. Call_Rep denotes the representation of the call.
1107 -- In_State is the current state of the Processing phase.
1109 end Activation_Processor;
1110 use Activation_Processor;
1112 -- The following package profides functionality for traversing subprogram
1113 -- bodies in DFS manner and processing of eligible scenarios within.
1115 package Body_Processor is
1117 -----------
1118 -- Types --
1119 -----------
1121 type Scenario_Predicate_Ptr is access function
1122 (N : Node_Id) return Boolean;
1123 -- Reference to a function which determines whether arbitrary node N
1124 -- denotes a suitable scenario for processing.
1126 type Scenario_Processor_Ptr is access procedure
1127 (N : Node_Id; In_State : Processing_In_State);
1128 -- Reference to a procedure which processes scenario N. In_State is the
1129 -- current state of the Processing phase.
1131 ---------
1132 -- API --
1133 ---------
1135 procedure Traverse_Body
1136 (N : Node_Id;
1137 Requires_Processing : Scenario_Predicate_Ptr;
1138 Processor : Scenario_Processor_Ptr;
1139 In_State : Processing_In_State);
1140 pragma Inline (Traverse_Body);
1141 -- Traverse the declarations and handled statements of subprogram body
1142 -- N, looking for scenarios that satisfy predicate Requires_Processing.
1143 -- Routine Processor is invoked for each such scenario.
1145 procedure Reset_Traversed_Bodies;
1146 pragma Inline (Reset_Traversed_Bodies);
1147 -- Reset the visited status of all subprogram bodies that have already
1148 -- been processed by routine Traverse_Body.
1150 -----------------
1151 -- Maintenance --
1152 -----------------
1154 procedure Finalize_Body_Processor;
1155 pragma Inline (Finalize_Body_Processor);
1156 -- Finalize all internal data structures
1158 procedure Initialize_Body_Processor;
1159 pragma Inline (Initialize_Body_Processor);
1160 -- Initialize all internal data structures
1162 end Body_Processor;
1163 use Body_Processor;
1165 -- The following package provides functionality for installing ABE-related
1166 -- checks and failures.
1168 package Check_Installer is
1170 ---------
1171 -- API --
1172 ---------
1174 function Check_Or_Failure_Generation_OK return Boolean;
1175 pragma Inline (Check_Or_Failure_Generation_OK);
1176 -- Determine whether a conditional ABE check or guaranteed ABE failure
1177 -- can be generated.
1179 procedure Install_Dynamic_ABE_Checks;
1180 pragma Inline (Install_Dynamic_ABE_Checks);
1181 -- Install conditional ABE checks for all saved scenarios when the
1182 -- dynamic model is in effect.
1184 procedure Install_Scenario_ABE_Check
1185 (N : Node_Id;
1186 Targ_Id : Entity_Id;
1187 Targ_Rep : Target_Rep_Id;
1188 Disable : Scenario_Rep_Id);
1189 pragma Inline (Install_Scenario_ABE_Check);
1190 -- Install a conditional ABE check for scenario N to ensure that target
1191 -- Targ_Id is properly elaborated. Targ_Rep is the representation of the
1192 -- target. If the check is installed, disable the elaboration checks of
1193 -- scenario Disable.
1195 procedure Install_Scenario_ABE_Check
1196 (N : Node_Id;
1197 Targ_Id : Entity_Id;
1198 Targ_Rep : Target_Rep_Id;
1199 Disable : Target_Rep_Id);
1200 pragma Inline (Install_Scenario_ABE_Check);
1201 -- Install a conditional ABE check for scenario N to ensure that target
1202 -- Targ_Id is properly elaborated. Targ_Rep is the representation of the
1203 -- target. If the check is installed, disable the elaboration checks of
1204 -- target Disable.
1206 procedure Install_Scenario_ABE_Failure
1207 (N : Node_Id;
1208 Targ_Id : Entity_Id;
1209 Targ_Rep : Target_Rep_Id;
1210 Disable : Scenario_Rep_Id);
1211 pragma Inline (Install_Scenario_ABE_Failure);
1212 -- Install a guaranteed ABE failure for scenario N with target Targ_Id.
1213 -- Targ_Rep denotes the representation of the target. If the failure is
1214 -- installed, disable the elaboration checks of scenario Disable.
1216 procedure Install_Scenario_ABE_Failure
1217 (N : Node_Id;
1218 Targ_Id : Entity_Id;
1219 Targ_Rep : Target_Rep_Id;
1220 Disable : Target_Rep_Id);
1221 pragma Inline (Install_Scenario_ABE_Failure);
1222 -- Install a guaranteed ABE failure for scenario N with target Targ_Id.
1223 -- Targ_Rep denotes the representation of the target. If the failure is
1224 -- installed, disable the elaboration checks of target Disable.
1226 procedure Install_Unit_ABE_Check
1227 (N : Node_Id;
1228 Unit_Id : Entity_Id;
1229 Disable : Scenario_Rep_Id);
1230 pragma Inline (Install_Unit_ABE_Check);
1231 -- Install a conditional ABE check for scenario N to ensure that unit
1232 -- Unit_Id is properly elaborated. If the check is installed, disable
1233 -- the elaboration checks of scenario Disable.
1235 procedure Install_Unit_ABE_Check
1236 (N : Node_Id;
1237 Unit_Id : Entity_Id;
1238 Disable : Target_Rep_Id);
1239 pragma Inline (Install_Unit_ABE_Check);
1240 -- Install a conditional ABE check for scenario N to ensure that unit
1241 -- Unit_Id is properly elaborated. If the check is installed, disable
1242 -- the elaboration checks of target Disable.
1244 end Check_Installer;
1245 use Check_Installer;
1247 -- The following package provides the main entry point for conditional ABE
1248 -- checks and diagnostics.
1250 package Conditional_ABE_Processor is
1252 ---------
1253 -- API --
1254 ---------
1256 procedure Check_Conditional_ABE_Scenarios
1257 (Iter : in out NE_Set.Iterator);
1258 pragma Inline (Check_Conditional_ABE_Scenarios);
1259 -- Perform conditional ABE checks and diagnostics for all scenarios
1260 -- available through iterator Iter.
1262 procedure Process_Conditional_ABE
1263 (N : Node_Id;
1264 In_State : Processing_In_State);
1265 pragma Inline (Process_Conditional_ABE);
1266 -- Perform conditional ABE checks and diagnostics for scenario N.
1267 -- In_State denotes the current state of the Processing phase.
1269 end Conditional_ABE_Processor;
1270 use Conditional_ABE_Processor;
1272 -- The following package provides functionality to emit errors, information
1273 -- messages, and warnings.
1275 package Diagnostics is
1277 ---------
1278 -- API --
1279 ---------
1281 procedure Elab_Msg_NE
1282 (Msg : String;
1283 N : Node_Id;
1284 Id : Entity_Id;
1285 Info_Msg : Boolean;
1286 In_SPARK : Boolean);
1287 pragma Inline (Elab_Msg_NE);
1288 -- Wrapper around Error_Msg_NE. Emit message Msg concerning arbitrary
1289 -- node N and entity. If flag Info_Msg is set, the routine emits an
1290 -- information message, otherwise it emits an error. If flag In_SPARK
1291 -- is set, then string " in SPARK" is added to the end of the message.
1293 procedure Info_Call
1294 (Call : Node_Id;
1295 Subp_Id : Entity_Id;
1296 Info_Msg : Boolean;
1297 In_SPARK : Boolean);
1298 pragma Inline (Info_Call);
1299 -- Output information concerning call Call that invokes subprogram
1300 -- Subp_Id. When flag Info_Msg is set, the routine emits an information
1301 -- message, otherwise it emits an error. When flag In_SPARK is set, " in
1302 -- SPARK" is added to the end of the message.
1304 procedure Info_Instantiation
1305 (Inst : Node_Id;
1306 Gen_Id : Entity_Id;
1307 Info_Msg : Boolean;
1308 In_SPARK : Boolean);
1309 pragma Inline (Info_Instantiation);
1310 -- Output information concerning instantiation Inst which instantiates
1311 -- generic unit Gen_Id. If flag Info_Msg is set, the routine emits an
1312 -- information message, otherwise it emits an error. If flag In_SPARK
1313 -- is set, then string " in SPARK" is added to the end of the message.
1315 procedure Info_Variable_Reference
1316 (Ref : Node_Id;
1317 Var_Id : Entity_Id);
1318 pragma Inline (Info_Variable_Reference);
1319 -- Output information concerning reference Ref which mentions variable
1320 -- Var_Id. The routine emits an error suffixed with " in SPARK".
1322 end Diagnostics;
1323 use Diagnostics;
1325 -- The following package provides functionality to locate the early call
1326 -- region of a subprogram body.
1328 package Early_Call_Region_Processor is
1330 ---------
1331 -- API --
1332 ---------
1334 function Find_Early_Call_Region
1335 (Body_Decl : Node_Id;
1336 Assume_Elab_Body : Boolean := False;
1337 Skip_Memoization : Boolean := False) return Node_Id;
1338 pragma Inline (Find_Early_Call_Region);
1339 -- Find the start of the early call region that belongs to subprogram
1340 -- body Body_Decl as defined in SPARK RM 7.7. This routine finds the
1341 -- early call region, memoizes it, and returns it, but this behavior
1342 -- can be altered. Flag Assume_Elab_Body should be set when a package
1343 -- spec may lack pragma Elaborate_Body, but the routine must still
1344 -- examine that spec. Flag Skip_Memoization should be set when the
1345 -- routine must avoid memoizing the region.
1347 -----------------
1348 -- Maintenance --
1349 -----------------
1351 procedure Finalize_Early_Call_Region_Processor;
1352 pragma Inline (Finalize_Early_Call_Region_Processor);
1353 -- Finalize all internal data structures
1355 procedure Initialize_Early_Call_Region_Processor;
1356 pragma Inline (Initialize_Early_Call_Region_Processor);
1357 -- Initialize all internal data structures
1359 end Early_Call_Region_Processor;
1360 use Early_Call_Region_Processor;
1362 -- The following package provides access to the elaboration statuses of all
1363 -- units withed by the main unit.
1365 package Elaborated_Units is
1367 ---------
1368 -- API --
1369 ---------
1371 procedure Collect_Elaborated_Units;
1372 pragma Inline (Collect_Elaborated_Units);
1373 -- Save the elaboration statuses of all units withed by the main unit
1375 procedure Ensure_Prior_Elaboration
1376 (N : Node_Id;
1377 Unit_Id : Entity_Id;
1378 Prag_Nam : Name_Id;
1379 In_State : Processing_In_State);
1380 pragma Inline (Ensure_Prior_Elaboration);
1381 -- Guarantee the elaboration of unit Unit_Id with respect to the main
1382 -- unit by either suggesting or installing an Elaborate[_All] pragma
1383 -- denoted by Prag_Nam. N denotes the related scenario. In_State is the
1384 -- current state of the Processing phase.
1386 function Has_Prior_Elaboration
1387 (Unit_Id : Entity_Id;
1388 Context_OK : Boolean := False;
1389 Elab_Body_OK : Boolean := False;
1390 Same_Unit_OK : Boolean := False) return Boolean;
1391 pragma Inline (Has_Prior_Elaboration);
1392 -- Determine whether unit Unit_Id is elaborated prior to the main unit.
1393 -- If flag Context_OK is set, the routine considers the following case
1394 -- as valid prior elaboration:
1396 -- * Unit_Id is in the elaboration context of the main unit
1398 -- If flag Elab_Body_OK is set, the routine considers the following case
1399 -- as valid prior elaboration:
1401 -- * Unit_Id has pragma Elaborate_Body and is not the main unit
1403 -- If flag Same_Unit_OK is set, the routine considers the following
1404 -- cases as valid prior elaboration:
1406 -- * Unit_Id is the main unit
1408 -- * Unit_Id denotes the spec of the main unit body
1410 procedure Meet_Elaboration_Requirement
1411 (N : Node_Id;
1412 Targ_Id : Entity_Id;
1413 Req_Nam : Name_Id;
1414 In_State : Processing_In_State);
1415 pragma Inline (Meet_Elaboration_Requirement);
1416 -- Determine whether elaboration requirement Req_Nam for scenario N with
1417 -- target Targ_Id is met by the context of the main unit using the SPARK
1418 -- rules. Req_Nam must denote either Elaborate or Elaborate_All. Emit an
1419 -- error if this is not the case. In_State denotes the current state of
1420 -- the Processing phase.
1422 -----------------
1423 -- Maintenance --
1424 -----------------
1426 procedure Finalize_Elaborated_Units;
1427 pragma Inline (Finalize_Elaborated_Units);
1428 -- Finalize all internal data structures
1430 procedure Initialize_Elaborated_Units;
1431 pragma Inline (Initialize_Elaborated_Units);
1432 -- Initialize all internal data structures
1434 end Elaborated_Units;
1435 use Elaborated_Units;
1437 -- The following package provides the main entry point for guaranteed ABE
1438 -- checks and diagnostics.
1440 package Guaranteed_ABE_Processor is
1442 ---------
1443 -- API --
1444 ---------
1446 procedure Process_Guaranteed_ABE
1447 (N : Node_Id;
1448 In_State : Processing_In_State);
1449 pragma Inline (Process_Guaranteed_ABE);
1450 -- Perform guaranteed ABE checks and diagnostics for scenario N.
1451 -- In_State is the current state of the Processing phase.
1453 end Guaranteed_ABE_Processor;
1454 use Guaranteed_ABE_Processor;
1456 -- The following package provides access to the internal representation of
1457 -- scenarios and targets.
1459 package Internal_Representation is
1461 -----------
1462 -- Types --
1463 -----------
1465 -- The following type enumerates all possible Ghost mode kinds
1467 type Extended_Ghost_Mode is
1468 (Is_Ignored,
1469 Is_Checked_Or_Not_Specified);
1471 -- The following type enumerates all possible SPARK mode kinds
1473 type Extended_SPARK_Mode is
1474 (Is_On,
1475 Is_Off_Or_Not_Specified);
1477 --------------
1478 -- Builders --
1479 --------------
1481 function Scenario_Representation_Of
1482 (N : Node_Id;
1483 In_State : Processing_In_State) return Scenario_Rep_Id;
1484 pragma Inline (Scenario_Representation_Of);
1485 -- Obtain the id of elaboration scenario N's representation. The routine
1486 -- constructs the representation if it is not available. In_State is the
1487 -- current state of the Processing phase.
1489 function Target_Representation_Of
1490 (Id : Entity_Id;
1491 In_State : Processing_In_State) return Target_Rep_Id;
1492 pragma Inline (Target_Representation_Of);
1493 -- Obtain the id of elaboration target Id's representation. The routine
1494 -- constructs the representation if it is not available. In_State is the
1495 -- current state of the Processing phase.
1497 -------------------------
1498 -- Scenario attributes --
1499 -------------------------
1501 function Activated_Task_Objects
1502 (S_Id : Scenario_Rep_Id) return NE_List.Doubly_Linked_List;
1503 pragma Inline (Activated_Task_Objects);
1504 -- For Task_Activation_Scenario S_Id, obtain the list of task objects
1505 -- the scenario is activating.
1507 function Activated_Task_Type (S_Id : Scenario_Rep_Id) return Entity_Id;
1508 pragma Inline (Activated_Task_Type);
1509 -- For Task_Activation_Scenario S_Id, obtain the currently activated
1510 -- task type.
1512 procedure Disable_Elaboration_Checks (S_Id : Scenario_Rep_Id);
1513 pragma Inline (Disable_Elaboration_Checks);
1514 -- Disable elaboration checks of scenario S_Id
1516 function Elaboration_Checks_OK (S_Id : Scenario_Rep_Id) return Boolean;
1517 pragma Inline (Elaboration_Checks_OK);
1518 -- Determine whether scenario S_Id may be subjected to elaboration
1519 -- checks.
1521 function Elaboration_Warnings_OK (S_Id : Scenario_Rep_Id) return Boolean;
1522 pragma Inline (Elaboration_Warnings_OK);
1523 -- Determine whether scenario S_Id may be subjected to elaboration
1524 -- warnings.
1526 function Ghost_Mode_Of
1527 (S_Id : Scenario_Rep_Id) return Extended_Ghost_Mode;
1528 pragma Inline (Ghost_Mode_Of);
1529 -- Obtain the Ghost mode of scenario S_Id
1531 function Is_Dispatching_Call (S_Id : Scenario_Rep_Id) return Boolean;
1532 pragma Inline (Is_Dispatching_Call);
1533 -- For Call_Scenario S_Id, determine whether the call is dispatching
1535 function Is_Read_Reference (S_Id : Scenario_Rep_Id) return Boolean;
1536 pragma Inline (Is_Read_Reference);
1537 -- For Variable_Reference_Scenario S_Id, determine whether the reference
1538 -- is a read.
1540 function Kind (S_Id : Scenario_Rep_Id) return Scenario_Kind;
1541 pragma Inline (Kind);
1542 -- Obtain the nature of scenario S_Id
1544 function Level (S_Id : Scenario_Rep_Id) return Enclosing_Level_Kind;
1545 pragma Inline (Level);
1546 -- Obtain the enclosing level of scenario S_Id
1548 procedure Set_Activated_Task_Objects
1549 (S_Id : Scenario_Rep_Id;
1550 Task_Objs : NE_List.Doubly_Linked_List);
1551 pragma Inline (Set_Activated_Task_Objects);
1552 -- For Task_Activation_Scenario S_Id, set the list of task objects
1553 -- activated by the scenario to Task_Objs.
1555 procedure Set_Activated_Task_Type
1556 (S_Id : Scenario_Rep_Id;
1557 Task_Typ : Entity_Id);
1558 pragma Inline (Set_Activated_Task_Type);
1559 -- For Task_Activation_Scenario S_Id, set the currently activated task
1560 -- type to Task_Typ.
1562 function SPARK_Mode_Of
1563 (S_Id : Scenario_Rep_Id) return Extended_SPARK_Mode;
1564 pragma Inline (SPARK_Mode_Of);
1565 -- Obtain the SPARK mode of scenario S_Id
1567 function Target (S_Id : Scenario_Rep_Id) return Entity_Id;
1568 pragma Inline (Target);
1569 -- Obtain the target of scenario S_Id
1571 -----------------------
1572 -- Target attributes --
1573 -----------------------
1575 function Barrier_Body_Declaration (T_Id : Target_Rep_Id) return Node_Id;
1576 pragma Inline (Barrier_Body_Declaration);
1577 -- For Subprogram_Target T_Id, obtain the declaration of the barrier
1578 -- function's body.
1580 function Body_Declaration (T_Id : Target_Rep_Id) return Node_Id;
1581 pragma Inline (Body_Declaration);
1582 -- Obtain the declaration of the body which belongs to target T_Id
1584 procedure Disable_Elaboration_Checks (T_Id : Target_Rep_Id);
1585 pragma Inline (Disable_Elaboration_Checks);
1586 -- Disable elaboration checks of target T_Id
1588 function Elaboration_Checks_OK (T_Id : Target_Rep_Id) return Boolean;
1589 pragma Inline (Elaboration_Checks_OK);
1590 -- Determine whether target T_Id may be subjected to elaboration checks
1592 function Elaboration_Warnings_OK (T_Id : Target_Rep_Id) return Boolean;
1593 pragma Inline (Elaboration_Warnings_OK);
1594 -- Determine whether target T_Id may be subjected to elaboration
1595 -- warnings.
1597 function Ghost_Mode_Of (T_Id : Target_Rep_Id) return Extended_Ghost_Mode;
1598 pragma Inline (Ghost_Mode_Of);
1599 -- Obtain the Ghost mode of target T_Id
1601 function Kind (T_Id : Target_Rep_Id) return Target_Kind;
1602 pragma Inline (Kind);
1603 -- Obtain the nature of target T_Id
1605 function SPARK_Mode_Of (T_Id : Target_Rep_Id) return Extended_SPARK_Mode;
1606 pragma Inline (SPARK_Mode_Of);
1607 -- Obtain the SPARK mode of target T_Id
1609 function Spec_Declaration (T_Id : Target_Rep_Id) return Node_Id;
1610 pragma Inline (Spec_Declaration);
1611 -- Obtain the declaration of the spec which belongs to target T_Id
1613 function Unit (T_Id : Target_Rep_Id) return Entity_Id;
1614 pragma Inline (Unit);
1615 -- Obtain the unit where the target is defined
1617 function Variable_Declaration (T_Id : Target_Rep_Id) return Node_Id;
1618 pragma Inline (Variable_Declaration);
1619 -- For Variable_Target T_Id, obtain the declaration of the variable
1621 -----------------
1622 -- Maintenance --
1623 -----------------
1625 procedure Finalize_Internal_Representation;
1626 pragma Inline (Finalize_Internal_Representation);
1627 -- Finalize all internal data structures
1629 procedure Initialize_Internal_Representation;
1630 pragma Inline (Initialize_Internal_Representation);
1631 -- Initialize all internal data structures
1633 end Internal_Representation;
1634 use Internal_Representation;
1636 -- The following package provides functionality for recording pieces of the
1637 -- invocation graph in the ALI file of the main unit.
1639 package Invocation_Graph is
1641 ---------
1642 -- API --
1643 ---------
1645 procedure Record_Invocation_Graph;
1646 pragma Inline (Record_Invocation_Graph);
1647 -- Process all declaration, instantiation, and library level scenarios,
1648 -- along with invocation construct within the spec and body of the main
1649 -- unit to determine whether any of these reach into an external unit.
1650 -- If such a path exists, encode in the ALI file of the main unit.
1652 -----------------
1653 -- Maintenance --
1654 -----------------
1656 procedure Finalize_Invocation_Graph;
1657 pragma Inline (Finalize_Invocation_Graph);
1658 -- Finalize all internal data structures
1660 procedure Initialize_Invocation_Graph;
1661 pragma Inline (Initialize_Invocation_Graph);
1662 -- Initialize all internal data structures
1664 end Invocation_Graph;
1665 use Invocation_Graph;
1667 -- The following package stores scenarios
1669 package Scenario_Storage is
1671 ---------
1672 -- API --
1673 ---------
1675 procedure Add_Declaration_Scenario (N : Node_Id);
1676 pragma Inline (Add_Declaration_Scenario);
1677 -- Save declaration level scenario N
1679 procedure Add_Dynamic_ABE_Check_Scenario (N : Node_Id);
1680 pragma Inline (Add_Dynamic_ABE_Check_Scenario);
1681 -- Save scenario N for conditional ABE check installation purposes when
1682 -- the dynamic model is in effect.
1684 procedure Add_Library_Body_Scenario (N : Node_Id);
1685 pragma Inline (Add_Library_Body_Scenario);
1686 -- Save library-level body scenario N
1688 procedure Add_Library_Spec_Scenario (N : Node_Id);
1689 pragma Inline (Add_Library_Spec_Scenario);
1690 -- Save library-level spec scenario N
1692 procedure Add_SPARK_Scenario (N : Node_Id);
1693 pragma Inline (Add_SPARK_Scenario);
1694 -- Save SPARK scenario N
1696 procedure Delete_Scenario (N : Node_Id);
1697 pragma Inline (Delete_Scenario);
1698 -- Delete arbitrary scenario N
1700 function Iterate_Declaration_Scenarios return NE_Set.Iterator;
1701 pragma Inline (Iterate_Declaration_Scenarios);
1702 -- Obtain an iterator over all declaration level scenarios
1704 function Iterate_Dynamic_ABE_Check_Scenarios return NE_Set.Iterator;
1705 pragma Inline (Iterate_Dynamic_ABE_Check_Scenarios);
1706 -- Obtain an iterator over all scenarios that require a conditional ABE
1707 -- check when the dynamic model is in effect.
1709 function Iterate_Library_Body_Scenarios return NE_Set.Iterator;
1710 pragma Inline (Iterate_Library_Body_Scenarios);
1711 -- Obtain an iterator over all library level body scenarios
1713 function Iterate_Library_Spec_Scenarios return NE_Set.Iterator;
1714 pragma Inline (Iterate_Library_Spec_Scenarios);
1715 -- Obtain an iterator over all library level spec scenarios
1717 function Iterate_SPARK_Scenarios return NE_Set.Iterator;
1718 pragma Inline (Iterate_SPARK_Scenarios);
1719 -- Obtain an iterator over all SPARK scenarios
1721 procedure Replace_Scenario (Old_N : Node_Id; New_N : Node_Id);
1722 pragma Inline (Replace_Scenario);
1723 -- Replace scenario Old_N with scenario New_N
1725 -----------------
1726 -- Maintenance --
1727 -----------------
1729 procedure Finalize_Scenario_Storage;
1730 pragma Inline (Finalize_Scenario_Storage);
1731 -- Finalize all internal data structures
1733 procedure Initialize_Scenario_Storage;
1734 pragma Inline (Initialize_Scenario_Storage);
1735 -- Initialize all internal data structures
1737 end Scenario_Storage;
1738 use Scenario_Storage;
1740 -- The following package provides various semantic predicates
1742 package Semantics is
1744 ---------
1745 -- API --
1746 ---------
1748 function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean;
1749 pragma Inline (Is_Accept_Alternative_Proc);
1750 -- Determine whether arbitrary entity Id denotes an internally generated
1751 -- procedure which encapsulates the statements of an accept alternative.
1753 function Is_Activation_Proc (Id : Entity_Id) return Boolean;
1754 pragma Inline (Is_Activation_Proc);
1755 -- Determine whether arbitrary entity Id denotes a runtime procedure in
1756 -- charge with activating tasks.
1758 function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean;
1759 pragma Inline (Is_Ada_Semantic_Target);
1760 -- Determine whether arbitrary entity Id denotes a source or internally
1761 -- generated subprogram which emulates Ada semantics.
1763 function Is_Assertion_Pragma_Target (Id : Entity_Id) return Boolean;
1764 pragma Inline (Is_Assertion_Pragma_Target);
1765 -- Determine whether arbitrary entity Id denotes a procedure which
1766 -- verifies the run-time semantics of an assertion pragma.
1768 function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean;
1769 pragma Inline (Is_Bodiless_Subprogram);
1770 -- Determine whether subprogram Subp_Id will never have a body
1772 function Is_Bridge_Target (Id : Entity_Id) return Boolean;
1773 pragma Inline (Is_Bridge_Target);
1774 -- Determine whether arbitrary entity Id denotes a bridge target
1776 function Is_Controlled_Proc
1777 (Subp_Id : Entity_Id;
1778 Subp_Nam : Name_Id) return Boolean;
1779 pragma Inline (Is_Controlled_Proc);
1780 -- Determine whether subprogram Subp_Id denotes controlled type
1781 -- primitives Adjust, Finalize, or Initialize as denoted by name
1782 -- Subp_Nam.
1784 function Is_Default_Initial_Condition_Proc
1785 (Id : Entity_Id) return Boolean;
1786 pragma Inline (Is_Default_Initial_Condition_Proc);
1787 -- Determine whether arbitrary entity Id denotes internally generated
1788 -- routine Default_Initial_Condition.
1790 function Is_Finalizer_Proc (Id : Entity_Id) return Boolean;
1791 pragma Inline (Is_Finalizer_Proc);
1792 -- Determine whether arbitrary entity Id denotes internally generated
1793 -- routine _Finalizer.
1795 function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean;
1796 pragma Inline (Is_Initial_Condition_Proc);
1797 -- Determine whether arbitrary entity Id denotes internally generated
1798 -- routine Initial_Condition.
1800 function Is_Initialized (Obj_Decl : Node_Id) return Boolean;
1801 pragma Inline (Is_Initialized);
1802 -- Determine whether object declaration Obj_Decl is initialized
1804 function Is_Invariant_Proc (Id : Entity_Id) return Boolean;
1805 pragma Inline (Is_Invariant_Proc);
1806 -- Determine whether arbitrary entity Id denotes an invariant procedure
1808 function Is_Non_Library_Level_Encapsulator (N : Node_Id) return Boolean;
1809 pragma Inline (Is_Non_Library_Level_Encapsulator);
1810 -- Determine whether arbitrary node N is a non-library encapsulator
1812 function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean;
1813 pragma Inline (Is_Partial_Invariant_Proc);
1814 -- Determine whether arbitrary entity Id denotes a partial invariant
1815 -- procedure.
1817 function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean;
1818 pragma Inline (Is_Preelaborated_Unit);
1819 -- Determine whether arbitrary entity Id denotes a unit which is subject
1820 -- to one of the following pragmas:
1822 -- * Preelaborable
1823 -- * Pure
1824 -- * Remote_Call_Interface
1825 -- * Remote_Types
1826 -- * Shared_Passive
1828 function Is_Protected_Entry (Id : Entity_Id) return Boolean;
1829 pragma Inline (Is_Protected_Entry);
1830 -- Determine whether arbitrary entity Id denotes a protected entry
1832 function Is_Protected_Subp (Id : Entity_Id) return Boolean;
1833 pragma Inline (Is_Protected_Subp);
1834 -- Determine whether entity Id denotes a protected subprogram
1836 function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean;
1837 pragma Inline (Is_Protected_Body_Subp);
1838 -- Determine whether entity Id denotes the protected or unprotected
1839 -- version of a protected subprogram.
1841 function Is_Scenario (N : Node_Id) return Boolean;
1842 pragma Inline (Is_Scenario);
1843 -- Determine whether attribute node N denotes a scenario. The scenario
1844 -- may not necessarily be eligible for ABE processing.
1846 function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean;
1847 pragma Inline (Is_SPARK_Semantic_Target);
1848 -- Determine whether arbitrary entity Id denotes a source or internally
1849 -- generated subprogram which emulates SPARK semantics.
1851 function Is_Subprogram_Inst (Id : Entity_Id) return Boolean;
1852 pragma Inline (Is_Subprogram_Inst);
1853 -- Determine whether arbitrary entity Id denotes a subprogram instance
1855 function Is_Suitable_Access_Taken (N : Node_Id) return Boolean;
1856 pragma Inline (Is_Suitable_Access_Taken);
1857 -- Determine whether arbitrary node N denotes a suitable attribute for
1858 -- ABE processing.
1860 function Is_Suitable_Call (N : Node_Id) return Boolean;
1861 pragma Inline (Is_Suitable_Call);
1862 -- Determine whether arbitrary node N denotes a suitable call for ABE
1863 -- processing.
1865 function Is_Suitable_Instantiation (N : Node_Id) return Boolean;
1866 pragma Inline (Is_Suitable_Instantiation);
1867 -- Determine whether arbitrary node N is a suitable instantiation for
1868 -- ABE processing.
1870 function Is_Suitable_SPARK_Derived_Type (N : Node_Id) return Boolean;
1871 pragma Inline (Is_Suitable_SPARK_Derived_Type);
1872 -- Determine whether arbitrary node N denotes a suitable derived type
1873 -- declaration for ABE processing using the SPARK rules.
1875 function Is_Suitable_SPARK_Instantiation (N : Node_Id) return Boolean;
1876 pragma Inline (Is_Suitable_SPARK_Instantiation);
1877 -- Determine whether arbitrary node N denotes a suitable instantiation
1878 -- for ABE processing using the SPARK rules.
1880 function Is_Suitable_SPARK_Refined_State_Pragma
1881 (N : Node_Id) return Boolean;
1882 pragma Inline (Is_Suitable_SPARK_Refined_State_Pragma);
1883 -- Determine whether arbitrary node N denotes a suitable Refined_State
1884 -- pragma for ABE processing using the SPARK rules.
1886 function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean;
1887 pragma Inline (Is_Suitable_Variable_Assignment);
1888 -- Determine whether arbitrary node N denotes a suitable assignment for
1889 -- ABE processing.
1891 function Is_Suitable_Variable_Reference (N : Node_Id) return Boolean;
1892 pragma Inline (Is_Suitable_Variable_Reference);
1893 -- Determine whether arbitrary node N is a suitable variable reference
1894 -- for ABE processing.
1896 function Is_Task_Entry (Id : Entity_Id) return Boolean;
1897 pragma Inline (Is_Task_Entry);
1898 -- Determine whether arbitrary entity Id denotes a task entry
1900 function Is_Up_Level_Target
1901 (Targ_Decl : Node_Id;
1902 In_State : Processing_In_State) return Boolean;
1903 pragma Inline (Is_Up_Level_Target);
1904 -- Determine whether the current root resides at the declaration level.
1905 -- If this is the case, determine whether a target with by declaration
1906 -- Target_Decl is within a context which encloses the current root or is
1907 -- in a different unit. In_State is the current state of the Processing
1908 -- phase.
1910 end Semantics;
1911 use Semantics;
1913 -- The following package provides the main entry point for SPARK-related
1914 -- checks and diagnostics.
1916 package SPARK_Processor is
1918 ---------
1919 -- API --
1920 ---------
1922 procedure Check_SPARK_Model_In_Effect;
1923 pragma Inline (Check_SPARK_Model_In_Effect);
1924 -- Determine whether a suitable elaboration model is currently in effect
1925 -- for verifying SPARK rules. Emit a warning if this is not the case.
1927 procedure Check_SPARK_Scenarios;
1928 pragma Inline (Check_SPARK_Scenarios);
1929 -- Examine SPARK scenarios which are not necessarily executable during
1930 -- elaboration, but still requires elaboration-related checks.
1932 end SPARK_Processor;
1933 use SPARK_Processor;
1935 -----------------------
1936 -- Local subprograms --
1937 -----------------------
1939 function Assignment_Target (Asmt : Node_Id) return Node_Id;
1940 pragma Inline (Assignment_Target);
1941 -- Obtain the target of assignment statement Asmt
1943 function Call_Name (Call : Node_Id) return Node_Id;
1944 pragma Inline (Call_Name);
1945 -- Obtain the name of an entry, operator, or subprogram call Call
1947 function Canonical_Subprogram (Subp_Id : Entity_Id) return Entity_Id;
1948 pragma Inline (Canonical_Subprogram);
1949 -- Obtain the uniform canonical entity of subprogram Subp_Id
1951 function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id;
1952 pragma Inline (Compilation_Unit);
1953 -- Return the N_Compilation_Unit node of unit Unit_Id
1955 function Elaboration_Phase_Active return Boolean;
1956 pragma Inline (Elaboration_Phase_Active);
1957 -- Determine whether the elaboration phase of the compilation has started
1959 procedure Error_Preelaborated_Call (N : Node_Id);
1960 -- Give an error or warning for a non-static/non-preelaborable call in a
1961 -- preelaborated unit.
1963 procedure Finalize_All_Data_Structures;
1964 pragma Inline (Finalize_All_Data_Structures);
1965 -- Destroy all internal data structures
1967 function Find_Enclosing_Instance (N : Node_Id) return Node_Id;
1968 pragma Inline (Find_Enclosing_Instance);
1969 -- Find the declaration or body of the nearest expanded instance which
1970 -- encloses arbitrary node N. Return Empty if no such instance exists.
1972 function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id;
1973 pragma Inline (Find_Top_Unit);
1974 -- Return the top unit which contains arbitrary node or entity N. The unit
1975 -- is obtained by logically unwinding instantiations and subunits when N
1976 -- resides within one.
1978 function Find_Unit_Entity (N : Node_Id) return Entity_Id;
1979 pragma Inline (Find_Unit_Entity);
1980 -- Return the entity of unit N
1982 function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id;
1983 pragma Inline (First_Formal_Type);
1984 -- Return the type of subprogram Subp_Id's first formal parameter. If the
1985 -- subprogram lacks formal parameters, return Empty.
1987 function Has_Body (Pack_Decl : Node_Id) return Boolean;
1988 pragma Inline (Has_Body);
1989 -- Determine whether package declaration Pack_Decl has a corresponding body
1990 -- or would eventually have one.
1992 function In_External_Instance
1993 (N : Node_Id;
1994 Target_Decl : Node_Id) return Boolean;
1995 pragma Inline (In_External_Instance);
1996 -- Determine whether a target desctibed by its declaration Target_Decl
1997 -- resides in a package instance which is external to scenario N.
1999 function In_Main_Context (N : Node_Id) return Boolean;
2000 pragma Inline (In_Main_Context);
2001 -- Determine whether arbitrary node N appears within the main compilation
2002 -- unit.
2004 function In_Same_Context
2005 (N1 : Node_Id;
2006 N2 : Node_Id;
2007 Nested_OK : Boolean := False) return Boolean;
2008 pragma Inline (In_Same_Context);
2009 -- Determine whether two arbitrary nodes N1 and N2 appear within the same
2010 -- context ignoring enclosing library levels. Nested_OK should be set when
2011 -- the context of N1 can enclose that of N2.
2013 procedure Initialize_All_Data_Structures;
2014 pragma Inline (Initialize_All_Data_Structures);
2015 -- Create all internal data structures
2017 function Instantiated_Generic (Inst : Node_Id) return Entity_Id;
2018 pragma Inline (Instantiated_Generic);
2019 -- Obtain the generic instantiated by instance Inst
2021 function Is_Safe_Activation
2022 (Call : Node_Id;
2023 Task_Rep : Target_Rep_Id) return Boolean;
2024 pragma Inline (Is_Safe_Activation);
2025 -- Determine whether activation call Call which activates an object of a
2026 -- task type described by representation Task_Rep is always ABE-safe.
2028 function Is_Safe_Call
2029 (Call : Node_Id;
2030 Subp_Id : Entity_Id;
2031 Subp_Rep : Target_Rep_Id) return Boolean;
2032 pragma Inline (Is_Safe_Call);
2033 -- Determine whether call Call which invokes entry, operator, or subprogram
2034 -- Subp_Id is always ABE-safe. Subp_Rep is the representation of the entry,
2035 -- operator, or subprogram.
2037 function Is_Safe_Instantiation
2038 (Inst : Node_Id;
2039 Gen_Id : Entity_Id;
2040 Gen_Rep : Target_Rep_Id) return Boolean;
2041 pragma Inline (Is_Safe_Instantiation);
2042 -- Determine whether instantiation Inst which instantiates generic Gen_Id
2043 -- is always ABE-safe. Gen_Rep is the representation of the generic.
2045 function Is_Same_Unit
2046 (Unit_1 : Entity_Id;
2047 Unit_2 : Entity_Id) return Boolean;
2048 pragma Inline (Is_Same_Unit);
2049 -- Determine whether entities Unit_1 and Unit_2 denote the same unit
2051 function Main_Unit_Entity return Entity_Id;
2052 pragma Inline (Main_Unit_Entity);
2053 -- Return the entity of the main unit
2055 function Non_Private_View (Typ : Entity_Id) return Entity_Id;
2056 pragma Inline (Non_Private_View);
2057 -- Return the full view of private type Typ if available, otherwise return
2058 -- type Typ.
2060 function Scenario (N : Node_Id) return Node_Id;
2061 pragma Inline (Scenario);
2062 -- Return the appropriate scenario node for scenario N
2064 procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status);
2065 pragma Inline (Set_Elaboration_Phase);
2066 -- Change the status of the elaboration phase of the compiler to Status
2068 procedure Spec_And_Body_From_Entity
2069 (Id : Entity_Id;
2070 Spec_Decl : out Node_Id;
2071 Body_Decl : out Node_Id);
2072 pragma Inline (Spec_And_Body_From_Entity);
2073 -- Given arbitrary entity Id representing a construct with a spec and body,
2074 -- retrieve declaration of the spec in Spec_Decl and the declaration of the
2075 -- body in Body_Decl.
2077 procedure Spec_And_Body_From_Node
2078 (N : Node_Id;
2079 Spec_Decl : out Node_Id;
2080 Body_Decl : out Node_Id);
2081 pragma Inline (Spec_And_Body_From_Node);
2082 -- Given arbitrary node N representing a construct with a spec and body,
2083 -- retrieve declaration of the spec in Spec_Decl and the declaration of
2084 -- the body in Body_Decl.
2086 function Static_Elaboration_Checks return Boolean;
2087 pragma Inline (Static_Elaboration_Checks);
2088 -- Determine whether the static model is in effect
2090 function Unit_Entity (Unit_Id : Entity_Id) return Entity_Id;
2091 pragma Inline (Unit_Entity);
2092 -- Return the entity of the initial declaration for unit Unit_Id
2094 procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id);
2095 pragma Inline (Update_Elaboration_Scenario);
2096 -- Update all relevant internal data structures when scenario Old_N is
2097 -- transformed into scenario New_N by Atree.Rewrite.
2099 ----------------------
2100 -- Active_Scenarios --
2101 ----------------------
2103 package body Active_Scenarios is
2105 -----------------------
2106 -- Local subprograms --
2107 -----------------------
2109 procedure Output_Access_Taken
2110 (Attr : Node_Id;
2111 Attr_Rep : Scenario_Rep_Id;
2112 Error_Nod : Node_Id);
2113 pragma Inline (Output_Access_Taken);
2114 -- Emit a specific diagnostic message for 'Access attribute reference
2115 -- Attr with representation Attr_Rep. The message is associated with
2116 -- node Error_Nod.
2118 procedure Output_Active_Scenario
2119 (N : Node_Id;
2120 Error_Nod : Node_Id;
2121 In_State : Processing_In_State);
2122 pragma Inline (Output_Active_Scenario);
2123 -- Top level dispatcher for outputting a scenario. Emit a specific
2124 -- diagnostic message for scenario N. The message is associated with
2125 -- node Error_Nod. In_State is the current state of the Processing
2126 -- phase.
2128 procedure Output_Call
2129 (Call : Node_Id;
2130 Call_Rep : Scenario_Rep_Id;
2131 Error_Nod : Node_Id);
2132 pragma Inline (Output_Call);
2133 -- Emit a diagnostic message for call Call with representation Call_Rep.
2134 -- The message is associated with node Error_Nod.
2136 procedure Output_Header (Error_Nod : Node_Id);
2137 pragma Inline (Output_Header);
2138 -- Emit a specific diagnostic message for the unit of the root scenario.
2139 -- The message is associated with node Error_Nod.
2141 procedure Output_Instantiation
2142 (Inst : Node_Id;
2143 Inst_Rep : Scenario_Rep_Id;
2144 Error_Nod : Node_Id);
2145 pragma Inline (Output_Instantiation);
2146 -- Emit a specific diagnostic message for instantiation Inst with
2147 -- representation Inst_Rep. The message is associated with node
2148 -- Error_Nod.
2150 procedure Output_Refined_State_Pragma
2151 (Prag : Node_Id;
2152 Prag_Rep : Scenario_Rep_Id;
2153 Error_Nod : Node_Id);
2154 pragma Inline (Output_Refined_State_Pragma);
2155 -- Emit a specific diagnostic message for Refined_State pragma Prag
2156 -- with representation Prag_Rep. The message is associated with node
2157 -- Error_Nod.
2159 procedure Output_Task_Activation
2160 (Call : Node_Id;
2161 Call_Rep : Scenario_Rep_Id;
2162 Error_Nod : Node_Id);
2163 pragma Inline (Output_Task_Activation);
2164 -- Emit a specific diagnostic message for activation call Call
2165 -- with representation Call_Rep. The message is associated with
2166 -- node Error_Nod.
2168 procedure Output_Variable_Assignment
2169 (Asmt : Node_Id;
2170 Asmt_Rep : Scenario_Rep_Id;
2171 Error_Nod : Node_Id);
2172 pragma Inline (Output_Variable_Assignment);
2173 -- Emit a specific diagnostic message for assignment statement Asmt
2174 -- with representation Asmt_Rep. The message is associated with node
2175 -- Error_Nod.
2177 procedure Output_Variable_Reference
2178 (Ref : Node_Id;
2179 Ref_Rep : Scenario_Rep_Id;
2180 Error_Nod : Node_Id);
2181 pragma Inline (Output_Variable_Reference);
2182 -- Emit a specific diagnostic message for read reference Ref with
2183 -- representation Ref_Rep. The message is associated with node
2184 -- Error_Nod.
2186 -------------------
2187 -- Output_Access --
2188 -------------------
2190 procedure Output_Access_Taken
2191 (Attr : Node_Id;
2192 Attr_Rep : Scenario_Rep_Id;
2193 Error_Nod : Node_Id)
2195 Subp_Id : constant Entity_Id := Target (Attr_Rep);
2197 begin
2198 Error_Msg_Name_1 := Attribute_Name (Attr);
2199 Error_Msg_Sloc := Sloc (Attr);
2200 Error_Msg_NE ("\\ % of & taken #", Error_Nod, Subp_Id);
2201 end Output_Access_Taken;
2203 ----------------------------
2204 -- Output_Active_Scenario --
2205 ----------------------------
2207 procedure Output_Active_Scenario
2208 (N : Node_Id;
2209 Error_Nod : Node_Id;
2210 In_State : Processing_In_State)
2212 Scen : constant Node_Id := Scenario (N);
2213 Scen_Rep : Scenario_Rep_Id;
2215 begin
2216 -- 'Access
2218 if Is_Suitable_Access_Taken (Scen) then
2219 Output_Access_Taken
2220 (Attr => Scen,
2221 Attr_Rep => Scenario_Representation_Of (Scen, In_State),
2222 Error_Nod => Error_Nod);
2224 -- Call or task activation
2226 elsif Is_Suitable_Call (Scen) then
2227 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
2229 if Kind (Scen_Rep) = Call_Scenario then
2230 Output_Call
2231 (Call => Scen,
2232 Call_Rep => Scen_Rep,
2233 Error_Nod => Error_Nod);
2235 else
2236 pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);
2238 Output_Task_Activation
2239 (Call => Scen,
2240 Call_Rep => Scen_Rep,
2241 Error_Nod => Error_Nod);
2242 end if;
2244 -- Instantiation
2246 elsif Is_Suitable_Instantiation (Scen) then
2247 Output_Instantiation
2248 (Inst => Scen,
2249 Inst_Rep => Scenario_Representation_Of (Scen, In_State),
2250 Error_Nod => Error_Nod);
2252 -- Pragma Refined_State
2254 elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
2255 Output_Refined_State_Pragma
2256 (Prag => Scen,
2257 Prag_Rep => Scenario_Representation_Of (Scen, In_State),
2258 Error_Nod => Error_Nod);
2260 -- Variable assignment
2262 elsif Is_Suitable_Variable_Assignment (Scen) then
2263 Output_Variable_Assignment
2264 (Asmt => Scen,
2265 Asmt_Rep => Scenario_Representation_Of (Scen, In_State),
2266 Error_Nod => Error_Nod);
2268 -- Variable reference
2270 elsif Is_Suitable_Variable_Reference (Scen) then
2271 Output_Variable_Reference
2272 (Ref => Scen,
2273 Ref_Rep => Scenario_Representation_Of (Scen, In_State),
2274 Error_Nod => Error_Nod);
2275 end if;
2276 end Output_Active_Scenario;
2278 -----------------------------
2279 -- Output_Active_Scenarios --
2280 -----------------------------
2282 procedure Output_Active_Scenarios
2283 (Error_Nod : Node_Id;
2284 In_State : Processing_In_State)
2286 package Scenarios renames Active_Scenario_Stack;
2288 Header_Posted : Boolean := False;
2290 begin
2291 -- Output the contents of the active scenario stack starting from the
2292 -- bottom, or the least recent scenario.
2294 for Index in Scenarios.First .. Scenarios.Last loop
2295 if not Header_Posted then
2296 Output_Header (Error_Nod);
2297 Header_Posted := True;
2298 end if;
2300 Output_Active_Scenario
2301 (N => Scenarios.Table (Index),
2302 Error_Nod => Error_Nod,
2303 In_State => In_State);
2304 end loop;
2305 end Output_Active_Scenarios;
2307 -----------------
2308 -- Output_Call --
2309 -----------------
2311 procedure Output_Call
2312 (Call : Node_Id;
2313 Call_Rep : Scenario_Rep_Id;
2314 Error_Nod : Node_Id)
2316 procedure Output_Accept_Alternative (Alt_Id : Entity_Id);
2317 pragma Inline (Output_Accept_Alternative);
2318 -- Emit a specific diagnostic message concerning accept alternative
2319 -- with entity Alt_Id.
2321 procedure Output_Call (Subp_Id : Entity_Id; Kind : String);
2322 pragma Inline (Output_Call);
2323 -- Emit a specific diagnostic message concerning a call of kind Kind
2324 -- which invokes subprogram Subp_Id.
2326 procedure Output_Type_Actions (Subp_Id : Entity_Id; Action : String);
2327 pragma Inline (Output_Type_Actions);
2328 -- Emit a specific diagnostic message concerning action Action of a
2329 -- type performed by subprogram Subp_Id.
2331 procedure Output_Verification_Call
2332 (Pred : String;
2333 Id : Entity_Id;
2334 Id_Kind : String);
2335 pragma Inline (Output_Verification_Call);
2336 -- Emit a specific diagnostic message concerning the verification of
2337 -- predicate Pred applied to related entity Id with kind Id_Kind.
2339 -------------------------------
2340 -- Output_Accept_Alternative --
2341 -------------------------------
2343 procedure Output_Accept_Alternative (Alt_Id : Entity_Id) is
2344 Entry_Id : constant Entity_Id := Receiving_Entry (Alt_Id);
2346 begin
2347 pragma Assert (Present (Entry_Id));
2349 Error_Msg_NE ("\\ entry & selected #", Error_Nod, Entry_Id);
2350 end Output_Accept_Alternative;
2352 -----------------
2353 -- Output_Call --
2354 -----------------
2356 procedure Output_Call (Subp_Id : Entity_Id; Kind : String) is
2357 begin
2358 Error_Msg_NE ("\\ " & Kind & " & called #", Error_Nod, Subp_Id);
2359 end Output_Call;
2361 -------------------------
2362 -- Output_Type_Actions --
2363 -------------------------
2365 procedure Output_Type_Actions
2366 (Subp_Id : Entity_Id;
2367 Action : String)
2369 Typ : constant Entity_Id := First_Formal_Type (Subp_Id);
2371 begin
2372 pragma Assert (Present (Typ));
2374 Error_Msg_NE
2375 ("\\ " & Action & " actions for type & #", Error_Nod, Typ);
2376 end Output_Type_Actions;
2378 ------------------------------
2379 -- Output_Verification_Call --
2380 ------------------------------
2382 procedure Output_Verification_Call
2383 (Pred : String;
2384 Id : Entity_Id;
2385 Id_Kind : String)
2387 begin
2388 pragma Assert (Present (Id));
2390 Error_Msg_NE
2391 ("\\ " & Pred & " of " & Id_Kind & " & verified #",
2392 Error_Nod, Id);
2393 end Output_Verification_Call;
2395 -- Local variables
2397 Subp_Id : constant Entity_Id := Target (Call_Rep);
2399 -- Start of processing for Output_Call
2401 begin
2402 Error_Msg_Sloc := Sloc (Call);
2404 -- Accept alternative
2406 if Is_Accept_Alternative_Proc (Subp_Id) then
2407 Output_Accept_Alternative (Subp_Id);
2409 -- Adjustment
2411 elsif Is_TSS (Subp_Id, TSS_Deep_Adjust) then
2412 Output_Type_Actions (Subp_Id, "adjustment");
2414 -- Default_Initial_Condition
2416 elsif Is_Default_Initial_Condition_Proc (Subp_Id) then
2418 -- Only do output for a normal DIC procedure, since partial DIC
2419 -- procedures are subsidiary to those.
2421 if not Is_Partial_DIC_Procedure (Subp_Id) then
2422 Output_Verification_Call
2423 (Pred => "Default_Initial_Condition",
2424 Id => First_Formal_Type (Subp_Id),
2425 Id_Kind => "type");
2426 end if;
2428 -- Entries
2430 elsif Is_Protected_Entry (Subp_Id) then
2431 Output_Call (Subp_Id, "entry");
2433 -- Task entry calls are never processed because the entry being
2434 -- invoked does not have a corresponding "body", it has a select. A
2435 -- task entry call appears in the stack of active scenarios for the
2436 -- sole purpose of checking No_Entry_Calls_In_Elaboration_Code and
2437 -- nothing more.
2439 elsif Is_Task_Entry (Subp_Id) then
2440 null;
2442 -- Finalization
2444 elsif Is_TSS (Subp_Id, TSS_Deep_Finalize) then
2445 Output_Type_Actions (Subp_Id, "finalization");
2447 -- Calls to _Finalizer procedures must not appear in the output
2448 -- because this creates confusing noise.
2450 elsif Is_Finalizer_Proc (Subp_Id) then
2451 null;
2453 -- Initial_Condition
2455 elsif Is_Initial_Condition_Proc (Subp_Id) then
2456 Output_Verification_Call
2457 (Pred => "Initial_Condition",
2458 Id => Find_Enclosing_Scope (Call),
2459 Id_Kind => "package");
2461 -- Initialization
2463 elsif Is_Init_Proc (Subp_Id)
2464 or else Is_TSS (Subp_Id, TSS_Deep_Initialize)
2465 then
2466 Output_Type_Actions (Subp_Id, "initialization");
2468 -- Invariant
2470 elsif Is_Invariant_Proc (Subp_Id) then
2471 Output_Verification_Call
2472 (Pred => "invariants",
2473 Id => First_Formal_Type (Subp_Id),
2474 Id_Kind => "type");
2476 -- Partial invariant calls must not appear in the output because this
2477 -- creates confusing noise. Note that a partial invariant is always
2478 -- invoked by the "full" invariant which is already placed on the
2479 -- stack.
2481 elsif Is_Partial_Invariant_Proc (Subp_Id) then
2482 null;
2484 -- Subprograms must come last because some of the previous cases fall
2485 -- under this category.
2487 elsif Ekind (Subp_Id) = E_Function then
2488 Output_Call (Subp_Id, "function");
2490 elsif Ekind (Subp_Id) = E_Procedure then
2491 Output_Call (Subp_Id, "procedure");
2493 else
2494 pragma Assert (False);
2495 return;
2496 end if;
2497 end Output_Call;
2499 -------------------
2500 -- Output_Header --
2501 -------------------
2503 procedure Output_Header (Error_Nod : Node_Id) is
2504 Unit_Id : constant Entity_Id := Find_Top_Unit (Root_Scenario);
2506 begin
2507 if Ekind (Unit_Id) = E_Package then
2508 Error_Msg_NE ("\\ spec of unit & elaborated", Error_Nod, Unit_Id);
2510 elsif Ekind (Unit_Id) = E_Package_Body then
2511 Error_Msg_NE ("\\ body of unit & elaborated", Error_Nod, Unit_Id);
2513 else
2514 Error_Msg_NE ("\\ in body of unit &", Error_Nod, Unit_Id);
2515 end if;
2516 end Output_Header;
2518 --------------------------
2519 -- Output_Instantiation --
2520 --------------------------
2522 procedure Output_Instantiation
2523 (Inst : Node_Id;
2524 Inst_Rep : Scenario_Rep_Id;
2525 Error_Nod : Node_Id)
2527 procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String);
2528 pragma Inline (Output_Instantiation);
2529 -- Emit a specific diagnostic message concerning an instantiation of
2530 -- generic unit Gen_Id. Kind denotes the kind of the instantiation.
2532 --------------------------
2533 -- Output_Instantiation --
2534 --------------------------
2536 procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String) is
2537 begin
2538 Error_Msg_NE
2539 ("\\ " & Kind & " & instantiated as & #", Error_Nod, Gen_Id);
2540 end Output_Instantiation;
2542 -- Local variables
2544 Gen_Id : constant Entity_Id := Target (Inst_Rep);
2546 -- Start of processing for Output_Instantiation
2548 begin
2549 Error_Msg_Node_2 := Defining_Entity (Inst);
2550 Error_Msg_Sloc := Sloc (Inst);
2552 if Nkind (Inst) = N_Function_Instantiation then
2553 Output_Instantiation (Gen_Id, "function");
2555 elsif Nkind (Inst) = N_Package_Instantiation then
2556 Output_Instantiation (Gen_Id, "package");
2558 elsif Nkind (Inst) = N_Procedure_Instantiation then
2559 Output_Instantiation (Gen_Id, "procedure");
2561 else
2562 pragma Assert (False);
2563 return;
2564 end if;
2565 end Output_Instantiation;
2567 ---------------------------------
2568 -- Output_Refined_State_Pragma --
2569 ---------------------------------
2571 procedure Output_Refined_State_Pragma
2572 (Prag : Node_Id;
2573 Prag_Rep : Scenario_Rep_Id;
2574 Error_Nod : Node_Id)
2576 pragma Unreferenced (Prag_Rep);
2578 begin
2579 Error_Msg_Sloc := Sloc (Prag);
2580 Error_Msg_N ("\\ refinement constituents read #", Error_Nod);
2581 end Output_Refined_State_Pragma;
2583 ----------------------------
2584 -- Output_Task_Activation --
2585 ----------------------------
2587 procedure Output_Task_Activation
2588 (Call : Node_Id;
2589 Call_Rep : Scenario_Rep_Id;
2590 Error_Nod : Node_Id)
2592 pragma Unreferenced (Call_Rep);
2594 function Find_Activator return Entity_Id;
2595 -- Find the nearest enclosing construct which houses call Call
2597 --------------------
2598 -- Find_Activator --
2599 --------------------
2601 function Find_Activator return Entity_Id is
2602 Par : Node_Id;
2604 begin
2605 -- Climb the parent chain looking for a package [body] or a
2606 -- construct with a statement sequence.
2608 Par := Parent (Call);
2609 while Present (Par) loop
2610 if Nkind (Par) in N_Package_Body | N_Package_Declaration then
2611 return Defining_Entity (Par);
2613 elsif Nkind (Par) = N_Handled_Sequence_Of_Statements then
2614 return Defining_Entity (Parent (Par));
2615 end if;
2617 Par := Parent (Par);
2618 end loop;
2620 return Empty;
2621 end Find_Activator;
2623 -- Local variables
2625 Activator : constant Entity_Id := Find_Activator;
2627 -- Start of processing for Output_Task_Activation
2629 begin
2630 pragma Assert (Present (Activator));
2632 Error_Msg_NE ("\\ local tasks of & activated", Error_Nod, Activator);
2633 end Output_Task_Activation;
2635 --------------------------------
2636 -- Output_Variable_Assignment --
2637 --------------------------------
2639 procedure Output_Variable_Assignment
2640 (Asmt : Node_Id;
2641 Asmt_Rep : Scenario_Rep_Id;
2642 Error_Nod : Node_Id)
2644 Var_Id : constant Entity_Id := Target (Asmt_Rep);
2646 begin
2647 Error_Msg_Sloc := Sloc (Asmt);
2648 Error_Msg_NE ("\\ variable & assigned #", Error_Nod, Var_Id);
2649 end Output_Variable_Assignment;
2651 -------------------------------
2652 -- Output_Variable_Reference --
2653 -------------------------------
2655 procedure Output_Variable_Reference
2656 (Ref : Node_Id;
2657 Ref_Rep : Scenario_Rep_Id;
2658 Error_Nod : Node_Id)
2660 Var_Id : constant Entity_Id := Target (Ref_Rep);
2662 begin
2663 Error_Msg_Sloc := Sloc (Ref);
2664 Error_Msg_NE ("\\ variable & read #", Error_Nod, Var_Id);
2665 end Output_Variable_Reference;
2667 -------------------------
2668 -- Pop_Active_Scenario --
2669 -------------------------
2671 procedure Pop_Active_Scenario (N : Node_Id) is
2672 package Scenarios renames Active_Scenario_Stack;
2673 Top : Node_Id renames Scenarios.Table (Scenarios.Last);
2675 begin
2676 pragma Assert (Top = N);
2677 Scenarios.Decrement_Last;
2678 end Pop_Active_Scenario;
2680 --------------------------
2681 -- Push_Active_Scenario --
2682 --------------------------
2684 procedure Push_Active_Scenario (N : Node_Id) is
2685 begin
2686 Active_Scenario_Stack.Append (N);
2687 end Push_Active_Scenario;
2689 -------------------
2690 -- Root_Scenario --
2691 -------------------
2693 function Root_Scenario return Node_Id is
2694 package Scenarios renames Active_Scenario_Stack;
2696 begin
2697 -- Ensure that the scenario stack has at least one active scenario in
2698 -- it. The one at the bottom (index First) is the root scenario.
2700 pragma Assert (Scenarios.Last >= Scenarios.First);
2701 return Scenarios.Table (Scenarios.First);
2702 end Root_Scenario;
2703 end Active_Scenarios;
2705 --------------------------
2706 -- Activation_Processor --
2707 --------------------------
2709 package body Activation_Processor is
2711 ------------------------
2712 -- Process_Activation --
2713 ------------------------
2715 procedure Process_Activation
2716 (Call : Node_Id;
2717 Call_Rep : Scenario_Rep_Id;
2718 Processor : Activation_Processor_Ptr;
2719 In_State : Processing_In_State)
2721 procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id);
2722 pragma Inline (Process_Task_Object);
2723 -- Invoke Processor for task object Obj_Id of type Typ
2725 procedure Process_Task_Objects
2726 (Task_Objs : NE_List.Doubly_Linked_List);
2727 pragma Inline (Process_Task_Objects);
2728 -- Invoke Processor for all task objects found in list Task_Objs
2730 procedure Traverse_List
2731 (List : List_Id;
2732 Task_Objs : NE_List.Doubly_Linked_List);
2733 pragma Inline (Traverse_List);
2734 -- Traverse declarative or statement list List while searching for
2735 -- objects of a task type, or containing task components. If such an
2736 -- object is found, first save it in list Task_Objs and then invoke
2737 -- Processor on it.
2739 -------------------------
2740 -- Process_Task_Object --
2741 -------------------------
2743 procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id) is
2744 Root_Typ : constant Entity_Id :=
2745 Non_Private_View (Root_Type (Typ));
2746 Comp_Id : Entity_Id;
2747 Obj_Rep : Target_Rep_Id;
2748 Root_Rep : Target_Rep_Id;
2750 New_In_State : Processing_In_State := In_State;
2751 -- Each step of the Processing phase constitutes a new state
2753 begin
2754 if Is_Task_Type (Typ) then
2755 Obj_Rep := Target_Representation_Of (Obj_Id, New_In_State);
2756 Root_Rep := Target_Representation_Of (Root_Typ, New_In_State);
2758 -- Warnings are suppressed when a prior scenario is already in
2759 -- that mode, or when the object, activation call, or task type
2760 -- have warnings suppressed. Update the state of the Processing
2761 -- phase to reflect this.
2763 New_In_State.Suppress_Warnings :=
2764 New_In_State.Suppress_Warnings
2765 or else not Elaboration_Warnings_OK (Call_Rep)
2766 or else not Elaboration_Warnings_OK (Obj_Rep)
2767 or else not Elaboration_Warnings_OK (Root_Rep);
2769 -- Update the state of the Processing phase to indicate that
2770 -- any further traversal is now within a task body.
2772 New_In_State.Within_Task_Body := True;
2774 -- Associate the current task type with the activation call
2776 Set_Activated_Task_Type (Call_Rep, Root_Typ);
2778 -- Process the activation of the current task object by calling
2779 -- the supplied processor.
2781 Processor.all
2782 (Call => Call,
2783 Call_Rep => Call_Rep,
2784 Obj_Id => Obj_Id,
2785 Obj_Rep => Obj_Rep,
2786 Task_Typ => Root_Typ,
2787 Task_Rep => Root_Rep,
2788 In_State => New_In_State);
2790 -- Reset the association between the current task and the
2791 -- activtion call.
2793 Set_Activated_Task_Type (Call_Rep, Empty);
2795 -- Examine the component type when the object is an array
2797 elsif Is_Array_Type (Typ) and then Has_Task (Root_Typ) then
2798 Process_Task_Object
2799 (Obj_Id => Obj_Id,
2800 Typ => Component_Type (Typ));
2802 -- Examine individual component types when the object is a record
2804 elsif Is_Record_Type (Typ) and then Has_Task (Root_Typ) then
2805 Comp_Id := First_Component (Typ);
2806 while Present (Comp_Id) loop
2807 Process_Task_Object
2808 (Obj_Id => Obj_Id,
2809 Typ => Etype (Comp_Id));
2811 Next_Component (Comp_Id);
2812 end loop;
2813 end if;
2814 end Process_Task_Object;
2816 --------------------------
2817 -- Process_Task_Objects --
2818 --------------------------
2820 procedure Process_Task_Objects
2821 (Task_Objs : NE_List.Doubly_Linked_List)
2823 Iter : NE_List.Iterator;
2824 Obj_Id : Entity_Id;
2826 begin
2827 Iter := NE_List.Iterate (Task_Objs);
2828 while NE_List.Has_Next (Iter) loop
2829 NE_List.Next (Iter, Obj_Id);
2831 Process_Task_Object
2832 (Obj_Id => Obj_Id,
2833 Typ => Etype (Obj_Id));
2834 end loop;
2835 end Process_Task_Objects;
2837 -------------------
2838 -- Traverse_List --
2839 -------------------
2841 procedure Traverse_List
2842 (List : List_Id;
2843 Task_Objs : NE_List.Doubly_Linked_List)
2845 Item : Node_Id;
2846 Item_Id : Entity_Id;
2847 Item_Typ : Entity_Id;
2849 begin
2850 -- Examine the contents of the list looking for an object
2851 -- declaration of a task type or one that contains a task
2852 -- within.
2854 Item := First (List);
2855 while Present (Item) loop
2856 if Nkind (Item) = N_Object_Declaration then
2857 Item_Id := Defining_Entity (Item);
2858 Item_Typ := Etype (Item_Id);
2860 if Has_Task (Item_Typ) then
2862 -- The object is either of a task type, or contains a
2863 -- task component. Save it in the list of task objects
2864 -- associated with the activation call.
2866 NE_List.Append (Task_Objs, Item_Id);
2868 Process_Task_Object
2869 (Obj_Id => Item_Id,
2870 Typ => Item_Typ);
2871 end if;
2872 end if;
2874 Next (Item);
2875 end loop;
2876 end Traverse_List;
2878 -- Local variables
2880 Context : Node_Id;
2881 Spec : Node_Id;
2882 Task_Objs : NE_List.Doubly_Linked_List;
2884 -- Start of processing for Process_Activation
2886 begin
2887 -- Nothing to do when the activation is a guaranteed ABE
2889 if Is_Known_Guaranteed_ABE (Call) then
2890 return;
2891 end if;
2893 Task_Objs := Activated_Task_Objects (Call_Rep);
2895 -- The activation call has been processed at least once, and all
2896 -- task objects have already been collected. Directly process the
2897 -- objects without having to reexamine the context of the call.
2899 if NE_List.Present (Task_Objs) then
2900 Process_Task_Objects (Task_Objs);
2902 -- Otherwise the activation call is being processed for the first
2903 -- time. Collect all task objects in case the call is reprocessed
2904 -- multiple times.
2906 else
2907 Task_Objs := NE_List.Create;
2908 Set_Activated_Task_Objects (Call_Rep, Task_Objs);
2910 -- Find the context of the activation call where all task objects
2911 -- being activated are declared. This is usually the parent of the
2912 -- call.
2914 Context := Parent (Call);
2916 -- Handle the case where the activation call appears within the
2917 -- handled statements of a block or a body.
2919 if Nkind (Context) = N_Handled_Sequence_Of_Statements then
2920 Context := Parent (Context);
2921 end if;
2923 -- Process all task objects in both the spec and body when the
2924 -- activation call appears in a package body.
2926 if Nkind (Context) = N_Package_Body then
2927 Spec :=
2928 Specification
2929 (Unit_Declaration_Node (Corresponding_Spec (Context)));
2931 Traverse_List
2932 (List => Visible_Declarations (Spec),
2933 Task_Objs => Task_Objs);
2935 Traverse_List
2936 (List => Private_Declarations (Spec),
2937 Task_Objs => Task_Objs);
2939 Traverse_List
2940 (List => Declarations (Context),
2941 Task_Objs => Task_Objs);
2943 -- Process all task objects in the spec when the activation call
2944 -- appears in a package spec.
2946 elsif Nkind (Context) = N_Package_Specification then
2947 Traverse_List
2948 (List => Visible_Declarations (Context),
2949 Task_Objs => Task_Objs);
2951 Traverse_List
2952 (List => Private_Declarations (Context),
2953 Task_Objs => Task_Objs);
2955 -- Otherwise the context must be a block or a body. Process all
2956 -- task objects found in the declarations.
2958 else
2959 pragma Assert
2960 (Nkind (Context) in
2961 N_Block_Statement | N_Entry_Body | N_Protected_Body |
2962 N_Subprogram_Body | N_Task_Body);
2964 Traverse_List
2965 (List => Declarations (Context),
2966 Task_Objs => Task_Objs);
2967 end if;
2968 end if;
2969 end Process_Activation;
2970 end Activation_Processor;
2972 -----------------------
2973 -- Assignment_Target --
2974 -----------------------
2976 function Assignment_Target (Asmt : Node_Id) return Node_Id is
2977 Nam : Node_Id;
2979 begin
2980 Nam := Name (Asmt);
2982 -- When the name denotes an array or record component, find the whole
2983 -- object.
2985 while Nkind (Nam) in
2986 N_Explicit_Dereference | N_Indexed_Component |
2987 N_Selected_Component | N_Slice
2988 loop
2989 Nam := Prefix (Nam);
2990 end loop;
2992 return Nam;
2993 end Assignment_Target;
2995 --------------------
2996 -- Body_Processor --
2997 --------------------
2999 package body Body_Processor is
3001 ---------------------
3002 -- Data structures --
3003 ---------------------
3005 -- The following map relates scenario lists to subprogram bodies
3007 Nested_Scenarios_Map : NE_List_Map.Dynamic_Hash_Table := NE_List_Map.Nil;
3009 -- The following set contains all subprogram bodies that have been
3010 -- processed by routine Traverse_Body.
3012 Traversed_Bodies_Set : NE_Set.Membership_Set := NE_Set.Nil;
3014 -----------------------
3015 -- Local subprograms --
3016 -----------------------
3018 function Is_Traversed_Body (N : Node_Id) return Boolean;
3019 pragma Inline (Is_Traversed_Body);
3020 -- Determine whether subprogram body N has already been traversed
3022 function Nested_Scenarios
3023 (N : Node_Id) return NE_List.Doubly_Linked_List;
3024 pragma Inline (Nested_Scenarios);
3025 -- Obtain the list of scenarios associated with subprogram body N
3027 procedure Set_Is_Traversed_Body (N : Node_Id);
3028 pragma Inline (Set_Is_Traversed_Body);
3029 -- Mark subprogram body N as traversed
3031 procedure Set_Nested_Scenarios
3032 (N : Node_Id;
3033 Scenarios : NE_List.Doubly_Linked_List);
3034 pragma Inline (Set_Nested_Scenarios);
3035 -- Associate scenario list Scenarios with subprogram body N
3037 -----------------------------
3038 -- Finalize_Body_Processor --
3039 -----------------------------
3041 procedure Finalize_Body_Processor is
3042 begin
3043 NE_List_Map.Destroy (Nested_Scenarios_Map);
3044 NE_Set.Destroy (Traversed_Bodies_Set);
3045 end Finalize_Body_Processor;
3047 -------------------------------
3048 -- Initialize_Body_Processor --
3049 -------------------------------
3051 procedure Initialize_Body_Processor is
3052 begin
3053 Nested_Scenarios_Map := NE_List_Map.Create (250);
3054 Traversed_Bodies_Set := NE_Set.Create (250);
3055 end Initialize_Body_Processor;
3057 -----------------------
3058 -- Is_Traversed_Body --
3059 -----------------------
3061 function Is_Traversed_Body (N : Node_Id) return Boolean is
3062 pragma Assert (Present (N));
3063 begin
3064 return NE_Set.Contains (Traversed_Bodies_Set, N);
3065 end Is_Traversed_Body;
3067 ----------------------
3068 -- Nested_Scenarios --
3069 ----------------------
3071 function Nested_Scenarios
3072 (N : Node_Id) return NE_List.Doubly_Linked_List
3074 pragma Assert (Present (N));
3075 pragma Assert (Nkind (N) = N_Subprogram_Body);
3077 begin
3078 return NE_List_Map.Get (Nested_Scenarios_Map, N);
3079 end Nested_Scenarios;
3081 ----------------------------
3082 -- Reset_Traversed_Bodies --
3083 ----------------------------
3085 procedure Reset_Traversed_Bodies is
3086 begin
3087 NE_Set.Reset (Traversed_Bodies_Set);
3088 end Reset_Traversed_Bodies;
3090 ---------------------------
3091 -- Set_Is_Traversed_Body --
3092 ---------------------------
3094 procedure Set_Is_Traversed_Body (N : Node_Id) is
3095 pragma Assert (Present (N));
3097 begin
3098 NE_Set.Insert (Traversed_Bodies_Set, N);
3099 end Set_Is_Traversed_Body;
3101 --------------------------
3102 -- Set_Nested_Scenarios --
3103 --------------------------
3105 procedure Set_Nested_Scenarios
3106 (N : Node_Id;
3107 Scenarios : NE_List.Doubly_Linked_List)
3109 pragma Assert (Present (N));
3110 begin
3111 NE_List_Map.Put (Nested_Scenarios_Map, N, Scenarios);
3112 end Set_Nested_Scenarios;
3114 -------------------
3115 -- Traverse_Body --
3116 -------------------
3118 procedure Traverse_Body
3119 (N : Node_Id;
3120 Requires_Processing : Scenario_Predicate_Ptr;
3121 Processor : Scenario_Processor_Ptr;
3122 In_State : Processing_In_State)
3124 Scenarios : NE_List.Doubly_Linked_List := NE_List.Nil;
3125 -- The list of scenarios that appear within the declarations and
3126 -- statement of subprogram body N. The variable is intentionally
3127 -- global because Is_Potential_Scenario needs to populate it.
3129 function In_Task_Body (Nod : Node_Id) return Boolean;
3130 pragma Inline (In_Task_Body);
3131 -- Determine whether arbitrary node Nod appears within a task body
3133 function Is_Synchronous_Suspension_Call
3134 (Nod : Node_Id) return Boolean;
3135 pragma Inline (Is_Synchronous_Suspension_Call);
3136 -- Determine whether arbitrary node Nod denotes a call to one of
3137 -- these routines:
3139 -- Ada.Synchronous_Barriers.Wait_For_Release
3140 -- Ada.Synchronous_Task_Control.Suspend_Until_True
3142 procedure Traverse_Collected_Scenarios;
3143 pragma Inline (Traverse_Collected_Scenarios);
3144 -- Traverse the already collected scenarios in list Scenarios by
3145 -- invoking Processor on each individual one.
3147 procedure Traverse_List (List : List_Id);
3148 pragma Inline (Traverse_List);
3149 -- Invoke Traverse_Potential_Scenarios on each node in list List
3151 function Traverse_Potential_Scenario
3152 (Scen : Node_Id) return Traverse_Result;
3153 pragma Inline (Traverse_Potential_Scenario);
3154 -- Determine whether arbitrary node Scen is a suitable scenario using
3155 -- predicate Is_Scenario and traverse it by invoking Processor on it.
3157 procedure Traverse_Potential_Scenarios is
3158 new Traverse_Proc (Traverse_Potential_Scenario);
3160 ------------------
3161 -- In_Task_Body --
3162 ------------------
3164 function In_Task_Body (Nod : Node_Id) return Boolean is
3165 Par : Node_Id;
3167 begin
3168 -- Climb the parent chain looking for a task body [procedure]
3170 Par := Nod;
3171 while Present (Par) loop
3172 if Nkind (Par) = N_Task_Body then
3173 return True;
3175 elsif Nkind (Par) = N_Subprogram_Body
3176 and then Is_Task_Body_Procedure (Par)
3177 then
3178 return True;
3180 -- Prevent the search from going too far. Note that this test
3181 -- shares nodes with the two cases above, and must come last.
3183 elsif Is_Body_Or_Package_Declaration (Par) then
3184 return False;
3185 end if;
3187 Par := Parent (Par);
3188 end loop;
3190 return False;
3191 end In_Task_Body;
3193 ------------------------------------
3194 -- Is_Synchronous_Suspension_Call --
3195 ------------------------------------
3197 function Is_Synchronous_Suspension_Call
3198 (Nod : Node_Id) return Boolean
3200 Subp_Id : Entity_Id;
3202 begin
3203 -- To qualify, the call must invoke one of the runtime routines
3204 -- which perform synchronous suspension.
3206 if Is_Suitable_Call (Nod) then
3207 Subp_Id := Target (Nod);
3209 return
3210 Is_RTE (Subp_Id, RE_Suspend_Until_True)
3211 or else
3212 Is_RTE (Subp_Id, RE_Wait_For_Release);
3213 end if;
3215 return False;
3216 end Is_Synchronous_Suspension_Call;
3218 ----------------------------------
3219 -- Traverse_Collected_Scenarios --
3220 ----------------------------------
3222 procedure Traverse_Collected_Scenarios is
3223 Iter : NE_List.Iterator;
3224 Scen : Node_Id;
3226 begin
3227 Iter := NE_List.Iterate (Scenarios);
3228 while NE_List.Has_Next (Iter) loop
3229 NE_List.Next (Iter, Scen);
3231 -- The current scenario satisfies the input predicate, process
3232 -- it.
3234 if Requires_Processing.all (Scen) then
3235 Processor.all (Scen, In_State);
3236 end if;
3237 end loop;
3238 end Traverse_Collected_Scenarios;
3240 -------------------
3241 -- Traverse_List --
3242 -------------------
3244 procedure Traverse_List (List : List_Id) is
3245 Scen : Node_Id;
3247 begin
3248 Scen := First (List);
3249 while Present (Scen) loop
3250 Traverse_Potential_Scenarios (Scen);
3251 Next (Scen);
3252 end loop;
3253 end Traverse_List;
3255 ---------------------------------
3256 -- Traverse_Potential_Scenario --
3257 ---------------------------------
3259 function Traverse_Potential_Scenario
3260 (Scen : Node_Id) return Traverse_Result
3262 begin
3263 -- Special cases
3265 -- Skip constructs which do not have elaboration of their own and
3266 -- need to be elaborated by other means such as invocation, task
3267 -- activation, etc.
3269 if Is_Non_Library_Level_Encapsulator (Scen) then
3270 return Skip;
3272 -- Terminate the traversal of a task body when encountering an
3273 -- accept or select statement, and
3275 -- * Entry calls during elaboration are not allowed. In this
3276 -- case the accept or select statement will cause the task
3277 -- to block at elaboration time because there are no entry
3278 -- calls to unblock it.
3280 -- or
3282 -- * Switch -gnatd_a (stop elaboration checks on accept or
3283 -- select statement) is in effect.
3285 elsif (Debug_Flag_Underscore_A
3286 or else Restriction_Active
3287 (No_Entry_Calls_In_Elaboration_Code))
3288 and then Nkind (Original_Node (Scen)) in
3289 N_Accept_Statement | N_Selective_Accept
3290 then
3291 return Abandon;
3293 -- Terminate the traversal of a task body when encountering a
3294 -- suspension call, and
3296 -- * Entry calls during elaboration are not allowed. In this
3297 -- case the suspension call emulates an entry call and will
3298 -- cause the task to block at elaboration time.
3300 -- or
3302 -- * Switch -gnatd_s (stop elaboration checks on synchronous
3303 -- suspension) is in effect.
3305 -- Note that the guard should not be checking the state of flag
3306 -- Within_Task_Body because only suspension calls which appear
3307 -- immediately within the statements of the task are supported.
3308 -- Flag Within_Task_Body carries over to deeper levels of the
3309 -- traversal.
3311 elsif (Debug_Flag_Underscore_S
3312 or else Restriction_Active
3313 (No_Entry_Calls_In_Elaboration_Code))
3314 and then Is_Synchronous_Suspension_Call (Scen)
3315 and then In_Task_Body (Scen)
3316 then
3317 return Abandon;
3319 -- Certain nodes carry semantic lists which act as repositories
3320 -- until expansion transforms the node and relocates the contents.
3321 -- Examine these lists in case expansion is disabled.
3323 elsif Nkind (Scen) in N_And_Then | N_Or_Else then
3324 Traverse_List (Actions (Scen));
3326 elsif Nkind (Scen) in N_Elsif_Part | N_Iteration_Scheme then
3327 Traverse_List (Condition_Actions (Scen));
3329 elsif Nkind (Scen) = N_If_Expression then
3330 Traverse_List (Then_Actions (Scen));
3331 Traverse_List (Else_Actions (Scen));
3333 elsif Nkind (Scen) in
3334 N_Component_Association
3335 | N_Iterated_Component_Association
3336 | N_Iterated_Element_Association
3337 then
3338 Traverse_List (Loop_Actions (Scen));
3340 -- General case
3342 -- The current node satisfies the input predicate, process it
3344 elsif Requires_Processing.all (Scen) then
3345 Processor.all (Scen, In_State);
3346 end if;
3348 -- Save a general scenario regardless of whether it satisfies the
3349 -- input predicate. This allows for quick subsequent traversals of
3350 -- general scenarios, even with different predicates.
3352 if Is_Suitable_Access_Taken (Scen)
3353 or else Is_Suitable_Call (Scen)
3354 or else Is_Suitable_Instantiation (Scen)
3355 or else Is_Suitable_Variable_Assignment (Scen)
3356 or else Is_Suitable_Variable_Reference (Scen)
3357 then
3358 NE_List.Append (Scenarios, Scen);
3359 end if;
3361 return OK;
3362 end Traverse_Potential_Scenario;
3364 -- Start of processing for Traverse_Body
3366 begin
3367 -- Nothing to do when the traversal is suppressed
3369 if In_State.Traversal = No_Traversal then
3370 return;
3372 -- Nothing to do when there is no input
3374 elsif No (N) then
3375 return;
3377 -- Nothing to do when the input is not a subprogram body
3379 elsif Nkind (N) /= N_Subprogram_Body then
3380 return;
3382 -- Nothing to do if the subprogram body was already traversed
3384 elsif Is_Traversed_Body (N) then
3385 return;
3386 end if;
3388 -- Mark the subprogram body as traversed
3390 Set_Is_Traversed_Body (N);
3392 Scenarios := Nested_Scenarios (N);
3394 -- The subprogram body has been traversed at least once, and all
3395 -- scenarios that appear within its declarations and statements
3396 -- have already been collected. Directly retraverse the scenarios
3397 -- without having to retraverse the subprogram body subtree.
3399 if NE_List.Present (Scenarios) then
3400 Traverse_Collected_Scenarios;
3402 -- Otherwise the subprogram body is being traversed for the first
3403 -- time. Collect all scenarios that appear within its declarations
3404 -- and statements in case the subprogram body has to be retraversed
3405 -- multiple times.
3407 else
3408 Scenarios := NE_List.Create;
3409 Set_Nested_Scenarios (N, Scenarios);
3411 Traverse_List (Declarations (N));
3412 Traverse_Potential_Scenarios (Handled_Statement_Sequence (N));
3413 end if;
3414 end Traverse_Body;
3415 end Body_Processor;
3417 -----------------------
3418 -- Build_Call_Marker --
3419 -----------------------
3421 procedure Build_Call_Marker (N : Node_Id) is
3422 function In_External_Context
3423 (Call : Node_Id;
3424 Subp_Id : Entity_Id) return Boolean;
3425 pragma Inline (In_External_Context);
3426 -- Determine whether entry, operator, or subprogram Subp_Id is external
3427 -- to call Call which must reside within an instance.
3429 function In_Premature_Context (Call : Node_Id) return Boolean;
3430 pragma Inline (In_Premature_Context);
3431 -- Determine whether call Call appears within a premature context
3433 function Is_Default_Expression (Call : Node_Id) return Boolean;
3434 pragma Inline (Is_Default_Expression);
3435 -- Determine whether call Call acts as the expression of a defaulted
3436 -- parameter within a source call.
3438 function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean;
3439 pragma Inline (Is_Generic_Formal_Subp);
3440 -- Determine whether subprogram Subp_Id denotes a generic formal
3441 -- subprogram which appears in the "prologue" of an instantiation.
3443 -------------------------
3444 -- In_External_Context --
3445 -------------------------
3447 function In_External_Context
3448 (Call : Node_Id;
3449 Subp_Id : Entity_Id) return Boolean
3451 Spec_Decl : constant Entity_Id := Unit_Declaration_Node (Subp_Id);
3453 Inst : Node_Id;
3454 Inst_Body : Node_Id;
3455 Inst_Spec : Node_Id;
3457 begin
3458 Inst := Find_Enclosing_Instance (Call);
3460 -- The call appears within an instance
3462 if Present (Inst) then
3464 -- The call comes from the main unit and the target does not
3466 if In_Extended_Main_Code_Unit (Call)
3467 and then not In_Extended_Main_Code_Unit (Spec_Decl)
3468 then
3469 return True;
3471 -- Otherwise the target declaration must not appear within the
3472 -- instance spec or body.
3474 else
3475 Spec_And_Body_From_Node
3476 (N => Inst,
3477 Spec_Decl => Inst_Spec,
3478 Body_Decl => Inst_Body);
3480 return not In_Subtree
3481 (N => Spec_Decl,
3482 Root1 => Inst_Spec,
3483 Root2 => Inst_Body);
3484 end if;
3485 end if;
3487 return False;
3488 end In_External_Context;
3490 --------------------------
3491 -- In_Premature_Context --
3492 --------------------------
3494 function In_Premature_Context (Call : Node_Id) return Boolean is
3495 Par : Node_Id;
3497 begin
3498 -- Climb the parent chain looking for premature contexts
3500 Par := Parent (Call);
3501 while Present (Par) loop
3503 -- Aspect specifications and generic associations are premature
3504 -- contexts because nested calls has not been relocated to their
3505 -- final context.
3507 if Nkind (Par) in N_Aspect_Specification | N_Generic_Association
3508 then
3509 return True;
3511 -- Prevent the search from going too far
3513 elsif Is_Body_Or_Package_Declaration (Par) then
3514 exit;
3515 end if;
3517 Par := Parent (Par);
3518 end loop;
3520 return False;
3521 end In_Premature_Context;
3523 ---------------------------
3524 -- Is_Default_Expression --
3525 ---------------------------
3527 function Is_Default_Expression (Call : Node_Id) return Boolean is
3528 Outer_Call : constant Node_Id := Parent (Call);
3529 Outer_Nam : Node_Id;
3531 begin
3532 -- To qualify, the node must appear immediately within a source call
3533 -- which invokes a source target.
3535 if Nkind (Outer_Call) in N_Entry_Call_Statement
3536 | N_Function_Call
3537 | N_Procedure_Call_Statement
3538 and then Comes_From_Source (Outer_Call)
3539 then
3540 Outer_Nam := Call_Name (Outer_Call);
3542 return
3543 Is_Entity_Name (Outer_Nam)
3544 and then Present (Entity (Outer_Nam))
3545 and then Is_Subprogram_Or_Entry (Entity (Outer_Nam))
3546 and then Comes_From_Source (Entity (Outer_Nam));
3547 end if;
3549 return False;
3550 end Is_Default_Expression;
3552 ----------------------------
3553 -- Is_Generic_Formal_Subp --
3554 ----------------------------
3556 function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean is
3557 Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id);
3558 Context : constant Node_Id := Parent (Subp_Decl);
3560 begin
3561 -- To qualify, the subprogram must rename a generic actual subprogram
3562 -- where the enclosing context is an instantiation.
3564 return
3565 Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
3566 and then not Comes_From_Source (Subp_Decl)
3567 and then Nkind (Context) in N_Function_Specification
3568 | N_Package_Specification
3569 | N_Procedure_Specification
3570 and then Present (Generic_Parent (Context));
3571 end Is_Generic_Formal_Subp;
3573 -- Local variables
3575 Call_Nam : Node_Id;
3576 Marker : Node_Id;
3577 Subp_Id : Entity_Id;
3579 -- Start of processing for Build_Call_Marker
3581 begin
3582 -- Nothing to do when switch -gnatH (legacy elaboration checking mode
3583 -- enabled) is in effect because the legacy ABE mechanism does not need
3584 -- to carry out this action.
3586 if Legacy_Elaboration_Checks then
3587 return;
3589 -- Nothing to do when the call is being preanalyzed as the marker will
3590 -- be inserted in the wrong place.
3592 elsif Preanalysis_Active then
3593 return;
3595 -- Nothing to do when the elaboration phase of the compiler is not
3596 -- active.
3598 elsif not Elaboration_Phase_Active then
3599 return;
3601 -- Nothing to do when the input does not denote a call or a requeue
3603 elsif Nkind (N) not in N_Entry_Call_Statement
3604 | N_Function_Call
3605 | N_Procedure_Call_Statement
3606 | N_Requeue_Statement
3607 then
3608 return;
3610 -- Nothing to do when the input denotes entry call or requeue statement,
3611 -- and switch -gnatd_e (ignore entry calls and requeue statements for
3612 -- elaboration) is in effect.
3614 elsif Debug_Flag_Underscore_E
3615 and then Nkind (N) in N_Entry_Call_Statement | N_Requeue_Statement
3616 then
3617 return;
3619 -- Nothing to do when the call is analyzed/resolved too early within an
3620 -- intermediate context. This check is saved for last because it incurs
3621 -- a performance penalty.
3623 elsif In_Premature_Context (N) then
3624 return;
3625 end if;
3627 Call_Nam := Call_Name (N);
3629 -- Nothing to do when the call is erroneous or left in a bad state
3631 if not (Is_Entity_Name (Call_Nam)
3632 and then Present (Entity (Call_Nam))
3633 and then Is_Subprogram_Or_Entry (Entity (Call_Nam)))
3634 then
3635 return;
3636 end if;
3638 Subp_Id := Canonical_Subprogram (Entity (Call_Nam));
3640 -- Nothing to do when the call invokes a generic formal subprogram and
3641 -- switch -gnatd.G (ignore calls through generic formal parameters for
3642 -- elaboration) is in effect. This check must be performed with the
3643 -- direct target of the call to avoid the side effects of mapping
3644 -- actuals to formals using renamings.
3646 if Debug_Flag_Dot_GG
3647 and then Is_Generic_Formal_Subp (Entity (Call_Nam))
3648 then
3649 return;
3651 -- Nothing to do when the call appears within the expanded spec or
3652 -- body of an instantiated generic, the call does not invoke a generic
3653 -- formal subprogram, the target is external to the instance, and switch
3654 -- -gnatdL (ignore external calls from instances for elaboration) is in
3655 -- effect. This check must be performed with the direct target of the
3656 -- call to avoid the side effects of mapping actuals to formals using
3657 -- renamings.
3659 elsif Debug_Flag_LL
3660 and then not Is_Generic_Formal_Subp (Entity (Call_Nam))
3661 and then In_External_Context
3662 (Call => N,
3663 Subp_Id => Subp_Id)
3664 then
3665 return;
3667 -- Nothing to do when the call invokes an assertion pragma procedure
3668 -- and switch -gnatd_p (ignore assertion pragmas for elaboration) is
3669 -- in effect.
3671 elsif Debug_Flag_Underscore_P
3672 and then Is_Assertion_Pragma_Target (Subp_Id)
3673 then
3674 return;
3676 -- Static expression functions require no ABE processing
3678 elsif Is_Static_Function (Subp_Id) then
3679 return;
3681 -- Source calls to source targets are always considered because they
3682 -- reflect the original call graph.
3684 elsif Comes_From_Source (N) and then Comes_From_Source (Subp_Id) then
3685 null;
3687 -- A call to a source function which acts as the default expression in
3688 -- another call requires special detection.
3690 elsif Comes_From_Source (Subp_Id)
3691 and then Nkind (N) = N_Function_Call
3692 and then Is_Default_Expression (N)
3693 then
3694 null;
3696 -- The target emulates Ada semantics
3698 elsif Is_Ada_Semantic_Target (Subp_Id) then
3699 null;
3701 -- The target acts as a link between scenarios
3703 elsif Is_Bridge_Target (Subp_Id) then
3704 null;
3706 -- The target emulates SPARK semantics
3708 elsif Is_SPARK_Semantic_Target (Subp_Id) then
3709 null;
3711 -- Otherwise the call is not suitable for ABE processing. This prevents
3712 -- the generation of call markers which will never play a role in ABE
3713 -- diagnostics.
3715 else
3716 return;
3717 end if;
3719 -- At this point it is known that the call will play some role in ABE
3720 -- checks and diagnostics. Create a corresponding call marker in case
3721 -- the original call is heavily transformed by expansion later on.
3723 Marker := Make_Call_Marker (Sloc (N));
3725 -- Inherit the attributes of the original call
3727 Set_Is_Declaration_Level_Node
3728 (Marker, Find_Enclosing_Level (N) = Declaration_Level);
3730 Set_Is_Dispatching_Call
3731 (Marker,
3732 Nkind (N) in N_Subprogram_Call
3733 and then Present (Controlling_Argument (N)));
3735 Set_Is_Elaboration_Checks_OK_Node
3736 (Marker, Is_Elaboration_Checks_OK_Node (N));
3738 Set_Is_Elaboration_Warnings_OK_Node
3739 (Marker, Is_Elaboration_Warnings_OK_Node (N));
3741 Set_Is_Ignored_Ghost_Node (Marker, Is_Ignored_Ghost_Node (N));
3742 Set_Is_Source_Call (Marker, Comes_From_Source (N));
3743 Set_Is_SPARK_Mode_On_Node (Marker, Is_SPARK_Mode_On_Node (N));
3744 Set_Target (Marker, Subp_Id);
3746 -- Ada 2022 (AI12-0175): Calls to certain functions that are essentially
3747 -- unchecked conversions are preelaborable.
3749 if Ada_Version >= Ada_2022 then
3750 Set_Is_Preelaborable_Call (Marker, Is_Preelaborable_Construct (N));
3751 else
3752 Set_Is_Preelaborable_Call (Marker, False);
3753 end if;
3755 -- The marker is inserted prior to the original call. This placement has
3756 -- several desirable effects:
3758 -- 1) The marker appears in the same context, in close proximity to
3759 -- the call.
3761 -- <marker>
3762 -- <call>
3764 -- 2) Inserting the marker prior to the call ensures that an ABE check
3765 -- will take effect prior to the call.
3767 -- <ABE check>
3768 -- <marker>
3769 -- <call>
3771 -- 3) The above two properties are preserved even when the call is a
3772 -- function which is subsequently relocated in order to capture its
3773 -- result. Note that if the call is relocated to a new context, the
3774 -- relocated call will receive a marker of its own.
3776 -- <ABE check>
3777 -- <maker>
3778 -- Temp : ... := Func_Call ...;
3779 -- ... Temp ...
3781 -- The insertion must take place even when the call does not occur in
3782 -- the main unit to keep the tree symmetric. This ensures that internal
3783 -- name serialization is consistent in case the call marker causes the
3784 -- tree to transform in some way.
3786 Insert_Action (N, Marker);
3788 -- The marker becomes the "corresponding" scenario for the call. Save
3789 -- the marker for later processing by the ABE phase.
3791 Record_Elaboration_Scenario (Marker);
3792 end Build_Call_Marker;
3794 -------------------------------------
3795 -- Build_Variable_Reference_Marker --
3796 -------------------------------------
3798 procedure Build_Variable_Reference_Marker
3799 (N : Node_Id;
3800 Read : Boolean;
3801 Write : Boolean)
3803 function Ultimate_Variable (Var_Id : Entity_Id) return Entity_Id;
3804 pragma Inline (Ultimate_Variable);
3805 -- Obtain the ultimate renamed variable of variable Var_Id
3807 -----------------------
3808 -- Ultimate_Variable --
3809 -----------------------
3811 function Ultimate_Variable (Var_Id : Entity_Id) return Entity_Id is
3812 pragma Assert (Ekind (Var_Id) = E_Variable);
3813 Ren_Id : Entity_Id;
3814 begin
3815 Ren_Id := Var_Id;
3816 while Present (Renamed_Object (Ren_Id))
3817 and then Nkind (Renamed_Object (Ren_Id)) in N_Entity
3818 loop
3819 Ren_Id := Renamed_Object (Ren_Id);
3820 end loop;
3822 return Ren_Id;
3823 end Ultimate_Variable;
3825 -- Local variables
3827 Var_Id : constant Entity_Id := Ultimate_Variable (Entity (N));
3828 Marker : Node_Id;
3830 -- Start of processing for Build_Variable_Reference_Marker
3832 begin
3833 -- Nothing to do when the elaboration phase of the compiler is not
3834 -- active.
3836 if not Elaboration_Phase_Active then
3837 return;
3838 end if;
3840 Marker := Make_Variable_Reference_Marker (Sloc (N));
3842 -- Inherit the attributes of the original variable reference
3844 Set_Is_Elaboration_Checks_OK_Node
3845 (Marker, Is_Elaboration_Checks_OK_Node (N));
3847 Set_Is_Elaboration_Warnings_OK_Node
3848 (Marker, Is_Elaboration_Warnings_OK_Node (N));
3850 Set_Is_Read (Marker, Read);
3851 Set_Is_SPARK_Mode_On_Node (Marker, Is_SPARK_Mode_On_Node (N));
3852 Set_Is_Write (Marker, Write);
3853 Set_Target (Marker, Var_Id);
3855 -- The marker is inserted prior to the original variable reference. The
3856 -- insertion must take place even when the reference does not occur in
3857 -- the main unit to keep the tree symmetric. This ensures that internal
3858 -- name serialization is consistent in case the variable marker causes
3859 -- the tree to transform in some way.
3861 Insert_Action (N, Marker);
3863 -- The marker becomes the "corresponding" scenario for the reference.
3864 -- Save the marker for later processing for the ABE phase.
3866 Record_Elaboration_Scenario (Marker);
3867 end Build_Variable_Reference_Marker;
3869 ---------------
3870 -- Call_Name --
3871 ---------------
3873 function Call_Name (Call : Node_Id) return Node_Id is
3874 Nam : Node_Id;
3876 begin
3877 Nam := Name (Call);
3879 -- When the call invokes an entry family, the name appears as an indexed
3880 -- component.
3882 if Nkind (Nam) = N_Indexed_Component then
3883 Nam := Prefix (Nam);
3884 end if;
3886 -- When the call employs the object.operation form, the name appears as
3887 -- a selected component.
3889 if Nkind (Nam) = N_Selected_Component then
3890 Nam := Selector_Name (Nam);
3891 end if;
3893 return Nam;
3894 end Call_Name;
3896 --------------------------
3897 -- Canonical_Subprogram --
3898 --------------------------
3900 function Canonical_Subprogram (Subp_Id : Entity_Id) return Entity_Id is
3901 Canon_Id : Entity_Id;
3903 begin
3904 Canon_Id := Subp_Id;
3906 -- Use the original protected subprogram when dealing with one of the
3907 -- specialized lock-manipulating versions.
3909 if Is_Protected_Body_Subp (Canon_Id) then
3910 Canon_Id := Protected_Subprogram (Canon_Id);
3911 end if;
3913 -- Obtain the original subprogram except when the subprogram is also
3914 -- an instantiation. In this case the alias is the internally generated
3915 -- subprogram which appears within the anonymous package created for the
3916 -- instantiation, making it unuitable.
3918 if not Is_Generic_Instance (Canon_Id) then
3919 Canon_Id := Get_Renamed_Entity (Canon_Id);
3920 end if;
3922 return Canon_Id;
3923 end Canonical_Subprogram;
3925 ---------------------------------
3926 -- Check_Elaboration_Scenarios --
3927 ---------------------------------
3929 procedure Check_Elaboration_Scenarios is
3930 Iter : NE_Set.Iterator;
3932 begin
3933 -- Nothing to do when switch -gnatH (legacy elaboration checking mode
3934 -- enabled) is in effect because the legacy ABE mechanism does not need
3935 -- to carry out this action.
3937 if Legacy_Elaboration_Checks then
3938 Finalize_All_Data_Structures;
3939 return;
3941 -- Nothing to do when the elaboration phase of the compiler is not
3942 -- active.
3944 elsif not Elaboration_Phase_Active then
3945 Finalize_All_Data_Structures;
3946 return;
3947 end if;
3949 -- Restore the original elaboration model which was in effect when the
3950 -- scenarios were first recorded. The model may be specified by pragma
3951 -- Elaboration_Checks which appears on the initial declaration of the
3952 -- main unit.
3954 Install_Elaboration_Model (Unit_Entity (Main_Unit_Entity));
3956 -- Examine the context of the main unit and record all units with prior
3957 -- elaboration with respect to it.
3959 Collect_Elaborated_Units;
3961 -- Examine all scenarios saved during the Recording phase applying the
3962 -- Ada or SPARK elaboration rules in order to detect and diagnose ABE
3963 -- issues, install conditional ABE checks, and ensure the elaboration
3964 -- of units.
3966 Iter := Iterate_Declaration_Scenarios;
3967 Check_Conditional_ABE_Scenarios (Iter);
3969 Iter := Iterate_Library_Body_Scenarios;
3970 Check_Conditional_ABE_Scenarios (Iter);
3972 Iter := Iterate_Library_Spec_Scenarios;
3973 Check_Conditional_ABE_Scenarios (Iter);
3975 -- Examine each SPARK scenario saved during the Recording phase which
3976 -- is not necessarily executable during elaboration, but still requires
3977 -- elaboration-related checks.
3979 Check_SPARK_Scenarios;
3981 -- Add conditional ABE checks for all scenarios that require one when
3982 -- the dynamic model is in effect.
3984 Install_Dynamic_ABE_Checks;
3986 -- Examine all scenarios saved during the Recording phase along with
3987 -- invocation constructs within the spec and body of the main unit.
3988 -- Record the declarations and paths that reach into an external unit
3989 -- in the ALI file of the main unit.
3991 Record_Invocation_Graph;
3993 -- Destroy all internal data structures and complete the elaboration
3994 -- phase of the compiler.
3996 Finalize_All_Data_Structures;
3997 Set_Elaboration_Phase (Completed);
3998 end Check_Elaboration_Scenarios;
4000 ---------------------
4001 -- Check_Installer --
4002 ---------------------
4004 package body Check_Installer is
4006 -----------------------
4007 -- Local subprograms --
4008 -----------------------
4010 function ABE_Check_Or_Failure_OK
4011 (N : Node_Id;
4012 Targ_Id : Entity_Id;
4013 Unit_Id : Entity_Id) return Boolean;
4014 pragma Inline (ABE_Check_Or_Failure_OK);
4015 -- Determine whether a conditional ABE check or guaranteed ABE failure
4016 -- can be installed for scenario N with target Targ_Id which resides in
4017 -- unit Unit_Id.
4019 function Insertion_Node (N : Node_Id) return Node_Id;
4020 pragma Inline (Insertion_Node);
4021 -- Obtain the proper insertion node of an ABE check or failure for
4022 -- scenario N.
4024 procedure Insert_ABE_Check_Or_Failure (N : Node_Id; Check : Node_Id);
4025 pragma Inline (Insert_ABE_Check_Or_Failure);
4026 -- Insert conditional ABE check or guaranteed ABE failure Check prior to
4027 -- scenario N.
4029 procedure Install_Scenario_ABE_Check_Common
4030 (N : Node_Id;
4031 Targ_Id : Entity_Id;
4032 Targ_Rep : Target_Rep_Id);
4033 pragma Inline (Install_Scenario_ABE_Check_Common);
4034 -- Install a conditional ABE check for scenario N to ensure that target
4035 -- Targ_Id is properly elaborated. Targ_Rep is the representation of the
4036 -- target.
4038 procedure Install_Scenario_ABE_Failure_Common (N : Node_Id);
4039 pragma Inline (Install_Scenario_ABE_Failure_Common);
4040 -- Install a guaranteed ABE failure for scenario N
4042 procedure Install_Unit_ABE_Check_Common
4043 (N : Node_Id;
4044 Unit_Id : Entity_Id);
4045 pragma Inline (Install_Unit_ABE_Check_Common);
4046 -- Install a conditional ABE check for scenario N to ensure that unit
4047 -- Unit_Id is properly elaborated.
4049 -----------------------------
4050 -- ABE_Check_Or_Failure_OK --
4051 -----------------------------
4053 function ABE_Check_Or_Failure_OK
4054 (N : Node_Id;
4055 Targ_Id : Entity_Id;
4056 Unit_Id : Entity_Id) return Boolean
4058 pragma Unreferenced (Targ_Id);
4060 Ins_Node : constant Node_Id := Insertion_Node (N);
4062 begin
4063 if not Check_Or_Failure_Generation_OK then
4064 return False;
4066 -- Nothing to do when the scenario denots a compilation unit because
4067 -- there is no executable environment at that level.
4069 elsif Nkind (Parent (Ins_Node)) = N_Compilation_Unit then
4070 return False;
4072 -- An ABE check or failure is not needed when the target is defined
4073 -- in a unit which is elaborated prior to the main unit. This check
4074 -- must also consider the following cases:
4076 -- * The unit of the target appears in the context of the main unit
4078 -- * The unit of the target is subject to pragma Elaborate_Body. An
4079 -- ABE check MUST NOT be generated because the unit is always
4080 -- elaborated prior to the main unit.
4082 -- * The unit of the target is the main unit. An ABE check MUST be
4083 -- added in this case because a conditional ABE may be raised
4084 -- depending on the flow of execution within the main unit (flag
4085 -- Same_Unit_OK is False).
4087 elsif Has_Prior_Elaboration
4088 (Unit_Id => Unit_Id,
4089 Context_OK => True,
4090 Elab_Body_OK => True)
4091 then
4092 return False;
4093 end if;
4095 return True;
4096 end ABE_Check_Or_Failure_OK;
4098 ------------------------------------
4099 -- Check_Or_Failure_Generation_OK --
4100 ------------------------------------
4102 function Check_Or_Failure_Generation_OK return Boolean is
4103 begin
4104 -- An ABE check or failure is not needed when the compilation will
4105 -- not produce an executable.
4107 if Serious_Errors_Detected > 0 then
4108 return False;
4110 -- An ABE check or failure must not be installed when compiling for
4111 -- GNATprove because raise statements are not supported.
4113 elsif GNATprove_Mode then
4114 return False;
4115 end if;
4117 return True;
4118 end Check_Or_Failure_Generation_OK;
4120 --------------------
4121 -- Insertion_Node --
4122 --------------------
4124 function Insertion_Node (N : Node_Id) return Node_Id is
4125 begin
4126 -- When the scenario denotes an instantiation, the proper insertion
4127 -- node is the instance spec. This ensures that the generic actuals
4128 -- will not be evaluated prior to a potential ABE.
4130 if Nkind (N) in N_Generic_Instantiation
4131 and then Present (Instance_Spec (N))
4132 then
4133 return Instance_Spec (N);
4135 -- Otherwise the proper insertion node is the scenario itself
4137 else
4138 return N;
4139 end if;
4140 end Insertion_Node;
4142 ---------------------------------
4143 -- Insert_ABE_Check_Or_Failure --
4144 ---------------------------------
4146 procedure Insert_ABE_Check_Or_Failure (N : Node_Id; Check : Node_Id) is
4147 Ins_Nod : constant Node_Id := Insertion_Node (N);
4148 Scop_Id : constant Entity_Id := Find_Enclosing_Scope (Ins_Nod);
4150 begin
4151 -- Install the nearest enclosing scope of the scenario as there must
4152 -- be something on the scope stack.
4154 Push_Scope (Scop_Id);
4156 Insert_Action (Ins_Nod, Check);
4158 Pop_Scope;
4159 end Insert_ABE_Check_Or_Failure;
4161 --------------------------------
4162 -- Install_Dynamic_ABE_Checks --
4163 --------------------------------
4165 procedure Install_Dynamic_ABE_Checks is
4166 Iter : NE_Set.Iterator;
4167 N : Node_Id;
4169 begin
4170 if not Check_Or_Failure_Generation_OK then
4171 return;
4173 -- Nothing to do if the dynamic model is not in effect
4175 elsif not Dynamic_Elaboration_Checks then
4176 return;
4177 end if;
4179 -- Install a conditional ABE check for each saved scenario
4181 Iter := Iterate_Dynamic_ABE_Check_Scenarios;
4182 while NE_Set.Has_Next (Iter) loop
4183 NE_Set.Next (Iter, N);
4185 Process_Conditional_ABE
4186 (N => N,
4187 In_State => Dynamic_Model_State);
4188 end loop;
4189 end Install_Dynamic_ABE_Checks;
4191 --------------------------------
4192 -- Install_Scenario_ABE_Check --
4193 --------------------------------
4195 procedure Install_Scenario_ABE_Check
4196 (N : Node_Id;
4197 Targ_Id : Entity_Id;
4198 Targ_Rep : Target_Rep_Id;
4199 Disable : Scenario_Rep_Id)
4201 begin
4202 -- Nothing to do when the scenario does not need an ABE check
4204 if not ABE_Check_Or_Failure_OK
4205 (N => N,
4206 Targ_Id => Targ_Id,
4207 Unit_Id => Unit (Targ_Rep))
4208 then
4209 return;
4210 end if;
4212 -- Prevent multiple attempts to install the same ABE check
4214 Disable_Elaboration_Checks (Disable);
4216 Install_Scenario_ABE_Check_Common
4217 (N => N,
4218 Targ_Id => Targ_Id,
4219 Targ_Rep => Targ_Rep);
4220 end Install_Scenario_ABE_Check;
4222 --------------------------------
4223 -- Install_Scenario_ABE_Check --
4224 --------------------------------
4226 procedure Install_Scenario_ABE_Check
4227 (N : Node_Id;
4228 Targ_Id : Entity_Id;
4229 Targ_Rep : Target_Rep_Id;
4230 Disable : Target_Rep_Id)
4232 begin
4233 -- Nothing to do when the scenario does not need an ABE check
4235 if not ABE_Check_Or_Failure_OK
4236 (N => N,
4237 Targ_Id => Targ_Id,
4238 Unit_Id => Unit (Targ_Rep))
4239 then
4240 return;
4241 end if;
4243 -- Prevent multiple attempts to install the same ABE check
4245 Disable_Elaboration_Checks (Disable);
4247 Install_Scenario_ABE_Check_Common
4248 (N => N,
4249 Targ_Id => Targ_Id,
4250 Targ_Rep => Targ_Rep);
4251 end Install_Scenario_ABE_Check;
4253 ---------------------------------------
4254 -- Install_Scenario_ABE_Check_Common --
4255 ---------------------------------------
4257 procedure Install_Scenario_ABE_Check_Common
4258 (N : Node_Id;
4259 Targ_Id : Entity_Id;
4260 Targ_Rep : Target_Rep_Id)
4262 Targ_Body : constant Node_Id := Body_Declaration (Targ_Rep);
4263 Targ_Decl : constant Node_Id := Spec_Declaration (Targ_Rep);
4265 pragma Assert (Present (Targ_Body));
4266 pragma Assert (Present (Targ_Decl));
4268 procedure Build_Elaboration_Entity;
4269 pragma Inline (Build_Elaboration_Entity);
4270 -- Create a new elaboration flag for Targ_Id, insert it prior to
4271 -- Targ_Decl, and set it after Targ_Body.
4273 ------------------------------
4274 -- Build_Elaboration_Entity --
4275 ------------------------------
4277 procedure Build_Elaboration_Entity is
4278 Loc : constant Source_Ptr := Sloc (Targ_Id);
4279 Flag_Id : Entity_Id;
4281 begin
4282 -- Nothing to do if the target has an elaboration flag
4284 if Present (Elaboration_Entity (Targ_Id)) then
4285 return;
4286 end if;
4288 -- Create the declaration of the elaboration flag. The name
4289 -- carries a unique counter in case the name is overloaded.
4291 Flag_Id :=
4292 Make_Defining_Identifier (Loc,
4293 Chars => New_External_Name (Chars (Targ_Id), 'E', -1));
4295 Set_Elaboration_Entity (Targ_Id, Flag_Id);
4296 Set_Elaboration_Entity_Required (Targ_Id);
4298 Push_Scope (Scope (Targ_Id));
4300 -- Generate:
4301 -- Enn : Short_Integer := 0;
4303 Insert_Action (Targ_Decl,
4304 Make_Object_Declaration (Loc,
4305 Defining_Identifier => Flag_Id,
4306 Object_Definition =>
4307 New_Occurrence_Of (Standard_Short_Integer, Loc),
4308 Expression => Make_Integer_Literal (Loc, Uint_0)));
4310 -- Generate:
4311 -- Enn := 1;
4313 Set_Elaboration_Flag (Targ_Body, Targ_Id);
4315 Pop_Scope;
4316 end Build_Elaboration_Entity;
4318 -- Local variables
4320 Loc : constant Source_Ptr := Sloc (N);
4322 -- Start for processing for Install_Scenario_ABE_Check_Common
4324 begin
4325 -- Create an elaboration flag for the target when it does not have
4326 -- one.
4328 Build_Elaboration_Entity;
4330 -- Generate:
4331 -- if not Targ_Id'Elaborated then
4332 -- raise Program_Error with "access before elaboration";
4333 -- end if;
4335 Insert_ABE_Check_Or_Failure
4336 (N => N,
4337 Check =>
4338 Make_Raise_Program_Error (Loc,
4339 Condition =>
4340 Make_Op_Not (Loc,
4341 Right_Opnd =>
4342 Make_Attribute_Reference (Loc,
4343 Prefix => New_Occurrence_Of (Targ_Id, Loc),
4344 Attribute_Name => Name_Elaborated)),
4345 Reason => PE_Access_Before_Elaboration));
4346 end Install_Scenario_ABE_Check_Common;
4348 ----------------------------------
4349 -- Install_Scenario_ABE_Failure --
4350 ----------------------------------
4352 procedure Install_Scenario_ABE_Failure
4353 (N : Node_Id;
4354 Targ_Id : Entity_Id;
4355 Targ_Rep : Target_Rep_Id;
4356 Disable : Scenario_Rep_Id)
4358 begin
4359 -- Nothing to do when the scenario does not require an ABE failure
4361 if not ABE_Check_Or_Failure_OK
4362 (N => N,
4363 Targ_Id => Targ_Id,
4364 Unit_Id => Unit (Targ_Rep))
4365 then
4366 return;
4367 end if;
4369 -- Prevent multiple attempts to install the same ABE check
4371 Disable_Elaboration_Checks (Disable);
4373 Install_Scenario_ABE_Failure_Common (N);
4374 end Install_Scenario_ABE_Failure;
4376 ----------------------------------
4377 -- Install_Scenario_ABE_Failure --
4378 ----------------------------------
4380 procedure Install_Scenario_ABE_Failure
4381 (N : Node_Id;
4382 Targ_Id : Entity_Id;
4383 Targ_Rep : Target_Rep_Id;
4384 Disable : Target_Rep_Id)
4386 begin
4387 -- Nothing to do when the scenario does not require an ABE failure
4389 if not ABE_Check_Or_Failure_OK
4390 (N => N,
4391 Targ_Id => Targ_Id,
4392 Unit_Id => Unit (Targ_Rep))
4393 then
4394 return;
4395 end if;
4397 -- Prevent multiple attempts to install the same ABE check
4399 Disable_Elaboration_Checks (Disable);
4401 Install_Scenario_ABE_Failure_Common (N);
4402 end Install_Scenario_ABE_Failure;
4404 -----------------------------------------
4405 -- Install_Scenario_ABE_Failure_Common --
4406 -----------------------------------------
4408 procedure Install_Scenario_ABE_Failure_Common (N : Node_Id) is
4409 Loc : constant Source_Ptr := Sloc (N);
4411 begin
4412 -- Generate:
4413 -- raise Program_Error with "access before elaboration";
4415 Insert_ABE_Check_Or_Failure
4416 (N => N,
4417 Check =>
4418 Make_Raise_Program_Error (Loc,
4419 Reason => PE_Access_Before_Elaboration));
4420 end Install_Scenario_ABE_Failure_Common;
4422 ----------------------------
4423 -- Install_Unit_ABE_Check --
4424 ----------------------------
4426 procedure Install_Unit_ABE_Check
4427 (N : Node_Id;
4428 Unit_Id : Entity_Id;
4429 Disable : Scenario_Rep_Id)
4431 Spec_Id : constant Entity_Id := Unique_Entity (Unit_Id);
4433 begin
4434 -- Nothing to do when the scenario does not require an ABE check
4436 if not ABE_Check_Or_Failure_OK
4437 (N => N,
4438 Targ_Id => Empty,
4439 Unit_Id => Spec_Id)
4440 then
4441 return;
4442 end if;
4444 -- Prevent multiple attempts to install the same ABE check
4446 Disable_Elaboration_Checks (Disable);
4448 Install_Unit_ABE_Check_Common
4449 (N => N,
4450 Unit_Id => Unit_Id);
4451 end Install_Unit_ABE_Check;
4453 ----------------------------
4454 -- Install_Unit_ABE_Check --
4455 ----------------------------
4457 procedure Install_Unit_ABE_Check
4458 (N : Node_Id;
4459 Unit_Id : Entity_Id;
4460 Disable : Target_Rep_Id)
4462 Spec_Id : constant Entity_Id := Unique_Entity (Unit_Id);
4464 begin
4465 -- Nothing to do when the scenario does not require an ABE check
4467 if not ABE_Check_Or_Failure_OK
4468 (N => N,
4469 Targ_Id => Empty,
4470 Unit_Id => Spec_Id)
4471 then
4472 return;
4473 end if;
4475 -- Prevent multiple attempts to install the same ABE check
4477 Disable_Elaboration_Checks (Disable);
4479 Install_Unit_ABE_Check_Common
4480 (N => N,
4481 Unit_Id => Unit_Id);
4482 end Install_Unit_ABE_Check;
4484 -----------------------------------
4485 -- Install_Unit_ABE_Check_Common --
4486 -----------------------------------
4488 procedure Install_Unit_ABE_Check_Common
4489 (N : Node_Id;
4490 Unit_Id : Entity_Id)
4492 Loc : constant Source_Ptr := Sloc (N);
4493 Spec_Id : constant Entity_Id := Unique_Entity (Unit_Id);
4495 begin
4496 -- Generate:
4497 -- if not Spec_Id'Elaborated then
4498 -- raise Program_Error with "access before elaboration";
4499 -- end if;
4501 Insert_ABE_Check_Or_Failure
4502 (N => N,
4503 Check =>
4504 Make_Raise_Program_Error (Loc,
4505 Condition =>
4506 Make_Op_Not (Loc,
4507 Right_Opnd =>
4508 Make_Attribute_Reference (Loc,
4509 Prefix => New_Occurrence_Of (Spec_Id, Loc),
4510 Attribute_Name => Name_Elaborated)),
4511 Reason => PE_Access_Before_Elaboration));
4512 end Install_Unit_ABE_Check_Common;
4513 end Check_Installer;
4515 ----------------------
4516 -- Compilation_Unit --
4517 ----------------------
4519 function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id is
4520 Comp_Unit : Node_Id;
4522 begin
4523 Comp_Unit := Parent (Unit_Id);
4525 -- Handle the case where a concurrent subunit is rewritten as a null
4526 -- statement due to expansion activities.
4528 if Nkind (Comp_Unit) = N_Null_Statement
4529 and then Nkind (Original_Node (Comp_Unit)) in
4530 N_Protected_Body | N_Task_Body
4531 then
4532 Comp_Unit := Parent (Comp_Unit);
4533 pragma Assert (Nkind (Comp_Unit) = N_Subunit);
4535 -- Otherwise use the declaration node of the unit
4537 else
4538 Comp_Unit := Parent (Unit_Declaration_Node (Unit_Id));
4539 end if;
4541 -- Handle the case where a subprogram instantiation which acts as a
4542 -- compilation unit is expanded into an anonymous package that wraps
4543 -- the instantiated subprogram.
4545 if Nkind (Comp_Unit) = N_Package_Specification
4546 and then Nkind (Original_Node (Parent (Comp_Unit))) in
4547 N_Function_Instantiation | N_Procedure_Instantiation
4548 then
4549 Comp_Unit := Parent (Parent (Comp_Unit));
4551 -- Handle the case where the compilation unit is a subunit
4553 elsif Nkind (Comp_Unit) = N_Subunit then
4554 Comp_Unit := Parent (Comp_Unit);
4555 end if;
4557 pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit);
4559 return Comp_Unit;
4560 end Compilation_Unit;
4562 -------------------------------
4563 -- Conditional_ABE_Processor --
4564 -------------------------------
4566 package body Conditional_ABE_Processor is
4568 -----------------------
4569 -- Local subprograms --
4570 -----------------------
4572 function Is_Conditional_ABE_Scenario (N : Node_Id) return Boolean;
4573 pragma Inline (Is_Conditional_ABE_Scenario);
4574 -- Determine whether node N is a suitable scenario for conditional ABE
4575 -- checks and diagnostics.
4577 procedure Process_Conditional_ABE_Access_Taken
4578 (Attr : Node_Id;
4579 Attr_Rep : Scenario_Rep_Id;
4580 In_State : Processing_In_State);
4581 pragma Inline (Process_Conditional_ABE_Access_Taken);
4582 -- Perform ABE checks and diagnostics for attribute reference Attr with
4583 -- representation Attr_Rep which takes 'Access of an entry, operator, or
4584 -- subprogram. In_State is the current state of the Processing phase.
4586 procedure Process_Conditional_ABE_Activation
4587 (Call : Node_Id;
4588 Call_Rep : Scenario_Rep_Id;
4589 Obj_Id : Entity_Id;
4590 Obj_Rep : Target_Rep_Id;
4591 Task_Typ : Entity_Id;
4592 Task_Rep : Target_Rep_Id;
4593 In_State : Processing_In_State);
4594 pragma Inline (Process_Conditional_ABE_Activation);
4595 -- Perform common conditional ABE checks and diagnostics for activation
4596 -- call Call which activates object Obj_Id of task type Task_Typ. Formal
4597 -- Call_Rep denotes the representation of the call. Obj_Rep denotes the
4598 -- representation of the object. Task_Rep denotes the representation of
4599 -- the task type. In_State is the current state of the Processing phase.
4601 procedure Process_Conditional_ABE_Call
4602 (Call : Node_Id;
4603 Call_Rep : Scenario_Rep_Id;
4604 In_State : Processing_In_State);
4605 pragma Inline (Process_Conditional_ABE_Call);
4606 -- Top-level dispatcher for processing of calls. Perform ABE checks and
4607 -- diagnostics for call Call with representation Call_Rep. In_State is
4608 -- the current state of the Processing phase.
4610 procedure Process_Conditional_ABE_Call_Ada
4611 (Call : Node_Id;
4612 Call_Rep : Scenario_Rep_Id;
4613 Subp_Id : Entity_Id;
4614 Subp_Rep : Target_Rep_Id;
4615 In_State : Processing_In_State);
4616 pragma Inline (Process_Conditional_ABE_Call_Ada);
4617 -- Perform ABE checks and diagnostics for call Call which invokes entry,
4618 -- operator, or subprogram Subp_Id using the Ada rules. Call_Rep denotes
4619 -- the representation of the call. Subp_Rep denotes the representation
4620 -- of the subprogram. In_State is the current state of the Processing
4621 -- phase.
4623 procedure Process_Conditional_ABE_Call_SPARK
4624 (Call : Node_Id;
4625 Call_Rep : Scenario_Rep_Id;
4626 Subp_Id : Entity_Id;
4627 Subp_Rep : Target_Rep_Id;
4628 In_State : Processing_In_State);
4629 pragma Inline (Process_Conditional_ABE_Call_SPARK);
4630 -- Perform ABE checks and diagnostics for call Call which invokes entry,
4631 -- operator, or subprogram Subp_Id using the SPARK rules. Call_Rep is
4632 -- the representation of the call. Subp_Rep denotes the representation
4633 -- of the subprogram. In_State is the current state of the Processing
4634 -- phase.
4636 procedure Process_Conditional_ABE_Instantiation
4637 (Inst : Node_Id;
4638 Inst_Rep : Scenario_Rep_Id;
4639 In_State : Processing_In_State);
4640 pragma Inline (Process_Conditional_ABE_Instantiation);
4641 -- Top-level dispatcher for processing of instantiations. Perform ABE
4642 -- checks and diagnostics for instantiation Inst with representation
4643 -- Inst_Rep. In_State is the current state of the Processing phase.
4645 procedure Process_Conditional_ABE_Instantiation_Ada
4646 (Inst : Node_Id;
4647 Inst_Rep : Scenario_Rep_Id;
4648 Gen_Id : Entity_Id;
4649 Gen_Rep : Target_Rep_Id;
4650 In_State : Processing_In_State);
4651 pragma Inline (Process_Conditional_ABE_Instantiation_Ada);
4652 -- Perform ABE checks and diagnostics for instantiation Inst of generic
4653 -- Gen_Id using the Ada rules. Inst_Rep denotes the representation of
4654 -- the instnace. Gen_Rep is the representation of the generic. In_State
4655 -- is the current state of the Processing phase.
4657 procedure Process_Conditional_ABE_Instantiation_SPARK
4658 (Inst : Node_Id;
4659 Inst_Rep : Scenario_Rep_Id;
4660 Gen_Id : Entity_Id;
4661 Gen_Rep : Target_Rep_Id;
4662 In_State : Processing_In_State);
4663 pragma Inline (Process_Conditional_ABE_Instantiation_SPARK);
4664 -- Perform ABE checks and diagnostics for instantiation Inst of generic
4665 -- Gen_Id using the SPARK rules. Inst_Rep denotes the representation of
4666 -- the instnace. Gen_Rep is the representation of the generic. In_State
4667 -- is the current state of the Processing phase.
4669 procedure Process_Conditional_ABE_Variable_Assignment
4670 (Asmt : Node_Id;
4671 Asmt_Rep : Scenario_Rep_Id;
4672 In_State : Processing_In_State);
4673 pragma Inline (Process_Conditional_ABE_Variable_Assignment);
4674 -- Top-level dispatcher for processing of variable assignments. Perform
4675 -- ABE checks and diagnostics for assignment Asmt with representation
4676 -- Asmt_Rep. In_State denotes the current state of the Processing phase.
4678 procedure Process_Conditional_ABE_Variable_Assignment_Ada
4679 (Asmt : Node_Id;
4680 Asmt_Rep : Scenario_Rep_Id;
4681 Var_Id : Entity_Id;
4682 Var_Rep : Target_Rep_Id;
4683 In_State : Processing_In_State);
4684 pragma Inline (Process_Conditional_ABE_Variable_Assignment_Ada);
4685 -- Perform ABE checks and diagnostics for assignment statement Asmt that
4686 -- modifies the value of variable Var_Id using the Ada rules. Asmt_Rep
4687 -- denotes the representation of the assignment. Var_Rep denotes the
4688 -- representation of the variable. In_State is the current state of the
4689 -- Processing phase.
4691 procedure Process_Conditional_ABE_Variable_Assignment_SPARK
4692 (Asmt : Node_Id;
4693 Asmt_Rep : Scenario_Rep_Id;
4694 Var_Id : Entity_Id;
4695 Var_Rep : Target_Rep_Id;
4696 In_State : Processing_In_State);
4697 pragma Inline (Process_Conditional_ABE_Variable_Assignment_SPARK);
4698 -- Perform ABE checks and diagnostics for assignment statement Asmt that
4699 -- modifies the value of variable Var_Id using the SPARK rules. Asmt_Rep
4700 -- denotes the representation of the assignment. Var_Rep denotes the
4701 -- representation of the variable. In_State is the current state of the
4702 -- Processing phase.
4704 procedure Process_Conditional_ABE_Variable_Reference
4705 (Ref : Node_Id;
4706 Ref_Rep : Scenario_Rep_Id;
4707 In_State : Processing_In_State);
4708 pragma Inline (Process_Conditional_ABE_Variable_Reference);
4709 -- Perform ABE checks and diagnostics for variable reference Ref with
4710 -- representation Ref_Rep. In_State denotes the current state of the
4711 -- Processing phase.
4713 procedure Traverse_Conditional_ABE_Body
4714 (N : Node_Id;
4715 In_State : Processing_In_State);
4716 pragma Inline (Traverse_Conditional_ABE_Body);
4717 -- Traverse subprogram body N looking for suitable scenarios that need
4718 -- to be processed for conditional ABE checks and diagnostics. In_State
4719 -- is the current state of the Processing phase.
4721 -------------------------------------
4722 -- Check_Conditional_ABE_Scenarios --
4723 -------------------------------------
4725 procedure Check_Conditional_ABE_Scenarios
4726 (Iter : in out NE_Set.Iterator)
4728 N : Node_Id;
4730 begin
4731 while NE_Set.Has_Next (Iter) loop
4732 NE_Set.Next (Iter, N);
4734 -- Reset the traversed status of all subprogram bodies because the
4735 -- current conditional scenario acts as a new DFS traversal root.
4737 Reset_Traversed_Bodies;
4739 Process_Conditional_ABE
4740 (N => N,
4741 In_State => Conditional_ABE_State);
4742 end loop;
4743 end Check_Conditional_ABE_Scenarios;
4745 ---------------------------------
4746 -- Is_Conditional_ABE_Scenario --
4747 ---------------------------------
4749 function Is_Conditional_ABE_Scenario (N : Node_Id) return Boolean is
4750 begin
4751 return
4752 Is_Suitable_Access_Taken (N)
4753 or else Is_Suitable_Call (N)
4754 or else Is_Suitable_Instantiation (N)
4755 or else Is_Suitable_Variable_Assignment (N)
4756 or else Is_Suitable_Variable_Reference (N);
4757 end Is_Conditional_ABE_Scenario;
4759 -----------------------------
4760 -- Process_Conditional_ABE --
4761 -----------------------------
4763 procedure Process_Conditional_ABE
4764 (N : Node_Id;
4765 In_State : Processing_In_State)
4767 Scen : constant Node_Id := Scenario (N);
4768 Scen_Rep : Scenario_Rep_Id;
4770 begin
4771 -- Add the current scenario to the stack of active scenarios
4773 Push_Active_Scenario (Scen);
4775 -- 'Access
4777 if Is_Suitable_Access_Taken (Scen) then
4778 Process_Conditional_ABE_Access_Taken
4779 (Attr => Scen,
4780 Attr_Rep => Scenario_Representation_Of (Scen, In_State),
4781 In_State => In_State);
4783 -- Call or task activation
4785 elsif Is_Suitable_Call (Scen) then
4786 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
4788 -- Routine Build_Call_Marker creates call markers regardless of
4789 -- whether the call occurs within the main unit or not. This way
4790 -- the serialization of internal names is kept consistent. Only
4791 -- call markers found within the main unit must be processed.
4793 if In_Main_Context (Scen) then
4794 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
4796 if Kind (Scen_Rep) = Call_Scenario then
4797 Process_Conditional_ABE_Call
4798 (Call => Scen,
4799 Call_Rep => Scen_Rep,
4800 In_State => In_State);
4802 else
4803 pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);
4805 Process_Activation
4806 (Call => Scen,
4807 Call_Rep => Scen_Rep,
4808 Processor => Process_Conditional_ABE_Activation'Access,
4809 In_State => In_State);
4810 end if;
4811 end if;
4813 -- Instantiation
4815 elsif Is_Suitable_Instantiation (Scen) then
4816 Process_Conditional_ABE_Instantiation
4817 (Inst => Scen,
4818 Inst_Rep => Scenario_Representation_Of (Scen, In_State),
4819 In_State => In_State);
4821 -- Variable assignments
4823 elsif Is_Suitable_Variable_Assignment (Scen) then
4824 Process_Conditional_ABE_Variable_Assignment
4825 (Asmt => Scen,
4826 Asmt_Rep => Scenario_Representation_Of (Scen, In_State),
4827 In_State => In_State);
4829 -- Variable references
4831 elsif Is_Suitable_Variable_Reference (Scen) then
4833 -- Routine Build_Variable_Reference_Marker makes variable markers
4834 -- regardless of whether the reference occurs within the main unit
4835 -- or not. This way the serialization of internal names is kept
4836 -- consistent. Only variable markers within the main unit must be
4837 -- processed.
4839 if In_Main_Context (Scen) then
4840 Process_Conditional_ABE_Variable_Reference
4841 (Ref => Scen,
4842 Ref_Rep => Scenario_Representation_Of (Scen, In_State),
4843 In_State => In_State);
4844 end if;
4845 end if;
4847 -- Remove the current scenario from the stack of active scenarios
4848 -- once all ABE diagnostics and checks have been performed.
4850 Pop_Active_Scenario (Scen);
4851 end Process_Conditional_ABE;
4853 ------------------------------------------
4854 -- Process_Conditional_ABE_Access_Taken --
4855 ------------------------------------------
4857 procedure Process_Conditional_ABE_Access_Taken
4858 (Attr : Node_Id;
4859 Attr_Rep : Scenario_Rep_Id;
4860 In_State : Processing_In_State)
4862 function Build_Access_Marker (Subp_Id : Entity_Id) return Node_Id;
4863 pragma Inline (Build_Access_Marker);
4864 -- Create a suitable call marker which invokes subprogram Subp_Id
4866 -------------------------
4867 -- Build_Access_Marker --
4868 -------------------------
4870 function Build_Access_Marker (Subp_Id : Entity_Id) return Node_Id is
4871 Marker : Node_Id;
4873 begin
4874 Marker := Make_Call_Marker (Sloc (Attr));
4876 -- Inherit relevant attributes from the attribute
4878 Set_Target (Marker, Subp_Id);
4879 Set_Is_Declaration_Level_Node
4880 (Marker, Level (Attr_Rep) = Declaration_Level);
4881 Set_Is_Dispatching_Call
4882 (Marker, False);
4883 Set_Is_Elaboration_Checks_OK_Node
4884 (Marker, Elaboration_Checks_OK (Attr_Rep));
4885 Set_Is_Elaboration_Warnings_OK_Node
4886 (Marker, Elaboration_Warnings_OK (Attr_Rep));
4887 Set_Is_Preelaborable_Call
4888 (Marker, False);
4889 Set_Is_Source_Call
4890 (Marker, Comes_From_Source (Attr));
4891 Set_Is_SPARK_Mode_On_Node
4892 (Marker, SPARK_Mode_Of (Attr_Rep) = Is_On);
4894 -- Partially insert the call marker into the tree by setting its
4895 -- parent pointer.
4897 Set_Parent (Marker, Attr);
4899 return Marker;
4900 end Build_Access_Marker;
4902 -- Local variables
4904 Root : constant Node_Id := Root_Scenario;
4905 Subp_Id : constant Entity_Id := Target (Attr_Rep);
4906 Subp_Rep : constant Target_Rep_Id :=
4907 Target_Representation_Of (Subp_Id, In_State);
4908 Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
4910 New_In_State : Processing_In_State := In_State;
4911 -- Each step of the Processing phase constitutes a new state
4913 -- Start of processing for Process_Conditional_ABE_Access
4915 begin
4916 -- Output relevant information when switch -gnatel (info messages on
4917 -- implicit Elaborate[_All] pragmas) is in effect.
4919 if Elab_Info_Messages
4920 and then not New_In_State.Suppress_Info_Messages
4921 then
4922 Error_Msg_NE
4923 ("info: access to & during elaboration", Attr, Subp_Id);
4924 end if;
4926 -- Warnings are suppressed when a prior scenario is already in that
4927 -- mode or when the attribute or the target have warnings suppressed.
4928 -- Update the state of the Processing phase to reflect this.
4930 New_In_State.Suppress_Warnings :=
4931 New_In_State.Suppress_Warnings
4932 or else not Elaboration_Warnings_OK (Attr_Rep)
4933 or else not Elaboration_Warnings_OK (Subp_Rep);
4935 -- Do not emit any ABE diagnostics when the current or previous
4936 -- scenario in this traversal has suppressed elaboration warnings.
4938 if New_In_State.Suppress_Warnings then
4939 null;
4941 -- Both the attribute and the corresponding subprogram body are in
4942 -- the same unit. The body must appear prior to the root scenario
4943 -- which started the recursive search. If this is not the case, then
4944 -- there is a potential ABE if the access value is used to call the
4945 -- subprogram. Emit a warning only when switch -gnatw.f (warnings on
4946 -- suspicious 'Access) is in effect.
4948 elsif Warn_On_Elab_Access
4949 and then Present (Body_Decl)
4950 and then In_Extended_Main_Code_Unit (Body_Decl)
4951 and then Earlier_In_Extended_Unit (Root, Body_Decl)
4952 then
4953 Error_Msg_Name_1 := Attribute_Name (Attr);
4954 Error_Msg_NE
4955 ("?.f?% attribute of & before body seen", Attr, Subp_Id);
4956 Error_Msg_N ("\possible Program_Error on later references", Attr);
4958 Output_Active_Scenarios (Attr, New_In_State);
4959 end if;
4961 -- Treat the attribute an immediate invocation of the target when
4962 -- switch -gnatd.o (conservative elaboration order for indirect
4963 -- calls) is in effect. This has the following desirable effects:
4965 -- * Ensure that the unit with the corresponding body is elaborated
4966 -- prior to the main unit.
4968 -- * Perform conditional ABE checks and diagnostics
4970 -- * Traverse the body of the target (if available)
4972 if Debug_Flag_Dot_O then
4973 Process_Conditional_ABE
4974 (N => Build_Access_Marker (Subp_Id),
4975 In_State => New_In_State);
4977 -- Otherwise ensure that the unit with the corresponding body is
4978 -- elaborated prior to the main unit.
4980 else
4981 Ensure_Prior_Elaboration
4982 (N => Attr,
4983 Unit_Id => Unit (Subp_Rep),
4984 Prag_Nam => Name_Elaborate_All,
4985 In_State => New_In_State);
4986 end if;
4987 end Process_Conditional_ABE_Access_Taken;
4989 ----------------------------------------
4990 -- Process_Conditional_ABE_Activation --
4991 ----------------------------------------
4993 procedure Process_Conditional_ABE_Activation
4994 (Call : Node_Id;
4995 Call_Rep : Scenario_Rep_Id;
4996 Obj_Id : Entity_Id;
4997 Obj_Rep : Target_Rep_Id;
4998 Task_Typ : Entity_Id;
4999 Task_Rep : Target_Rep_Id;
5000 In_State : Processing_In_State)
5002 pragma Unreferenced (Task_Typ);
5004 Body_Decl : constant Node_Id := Body_Declaration (Task_Rep);
5005 Spec_Decl : constant Node_Id := Spec_Declaration (Task_Rep);
5006 Root : constant Node_Id := Root_Scenario;
5007 Unit_Id : constant Node_Id := Unit (Task_Rep);
5009 Check_OK : constant Boolean :=
5010 not In_State.Suppress_Checks
5011 and then Ghost_Mode_Of (Obj_Rep) /= Is_Ignored
5012 and then Ghost_Mode_Of (Task_Rep) /= Is_Ignored
5013 and then Elaboration_Checks_OK (Obj_Rep)
5014 and then Elaboration_Checks_OK (Task_Rep);
5015 -- A run-time ABE check may be installed only when the object and the
5016 -- task type have active elaboration checks, and both are not ignored
5017 -- Ghost constructs.
5019 New_In_State : Processing_In_State := In_State;
5020 -- Each step of the Processing phase constitutes a new state
5022 begin
5023 -- Output relevant information when switch -gnatel (info messages on
5024 -- implicit Elaborate[_All] pragmas) is in effect.
5026 if Elab_Info_Messages
5027 and then not New_In_State.Suppress_Info_Messages
5028 then
5029 Error_Msg_NE
5030 ("info: activation of & during elaboration", Call, Obj_Id);
5031 end if;
5033 -- Nothing to do when the call activates a task whose type is defined
5034 -- within an instance and switch -gnatd_i (ignore activations and
5035 -- calls to instances for elaboration) is in effect.
5037 if Debug_Flag_Underscore_I
5038 and then In_External_Instance
5039 (N => Call,
5040 Target_Decl => Spec_Decl)
5041 then
5042 return;
5044 -- Nothing to do when the activation is a guaranteed ABE
5046 elsif Is_Known_Guaranteed_ABE (Call) then
5047 return;
5049 -- Nothing to do when the root scenario appears at the declaration
5050 -- level and the task is in the same unit, but outside this context.
5052 -- task type Task_Typ; -- task declaration
5054 -- procedure Proc is
5055 -- function A ... is
5056 -- begin
5057 -- if Some_Condition then
5058 -- declare
5059 -- T : Task_Typ;
5060 -- begin
5061 -- <activation call> -- activation site
5062 -- end;
5063 -- ...
5064 -- end A;
5066 -- X : ... := A; -- root scenario
5067 -- ...
5069 -- task body Task_Typ is
5070 -- ...
5071 -- end Task_Typ;
5073 -- In the example above, the context of X is the declarative list of
5074 -- Proc. The "elaboration" of X may reach the activation of T whose
5075 -- body is defined outside of X's context. The task body is relevant
5076 -- only when Proc is invoked, but this happens only during "normal"
5077 -- elaboration, therefore the task body must not be considered if
5078 -- this is not the case.
5080 elsif Is_Up_Level_Target
5081 (Targ_Decl => Spec_Decl,
5082 In_State => New_In_State)
5083 then
5084 return;
5086 -- Nothing to do when the activation is ABE-safe
5088 -- generic
5089 -- package Gen is
5090 -- task type Task_Typ;
5091 -- end Gen;
5093 -- package body Gen is
5094 -- task body Task_Typ is
5095 -- begin
5096 -- ...
5097 -- end Task_Typ;
5098 -- end Gen;
5100 -- with Gen;
5101 -- procedure Main is
5102 -- package Nested is
5103 -- package Inst is new Gen;
5104 -- T : Inst.Task_Typ;
5105 -- <activation call> -- safe activation
5106 -- end Nested;
5107 -- ...
5109 elsif Is_Safe_Activation (Call, Task_Rep) then
5111 -- Note that the task body must still be examined for any nested
5112 -- scenarios.
5114 null;
5116 -- The activation call and the task body are both in the main unit
5118 -- If the root scenario appears prior to the task body, then this is
5119 -- a possible ABE with respect to the root scenario.
5121 -- task type Task_Typ;
5123 -- function A ... is
5124 -- begin
5125 -- if Some_Condition then
5126 -- declare
5127 -- package Pack is
5128 -- T : Task_Typ;
5129 -- end Pack; -- activation of T
5130 -- ...
5131 -- end A;
5133 -- X : ... := A; -- root scenario
5135 -- task body Task_Typ is -- task body
5136 -- ...
5137 -- end Task_Typ;
5139 -- Y : ... := A; -- root scenario
5141 -- IMPORTANT: The activation of T is a possible ABE for X, but
5142 -- not for Y. Intalling an unconditional ABE raise prior to the
5143 -- activation call would be wrong as it will fail for Y as well
5144 -- but in Y's case the activation of T is never an ABE.
5146 elsif Present (Body_Decl)
5147 and then In_Extended_Main_Code_Unit (Body_Decl)
5148 then
5149 if Earlier_In_Extended_Unit (Root, Body_Decl) then
5151 -- Do not emit any ABE diagnostics when a previous scenario in
5152 -- this traversal has suppressed elaboration warnings.
5154 if New_In_State.Suppress_Warnings then
5155 null;
5157 -- Do not emit any ABE diagnostics when the activation occurs
5158 -- in a partial finalization context because this action leads
5159 -- to confusing noise.
5161 elsif New_In_State.Within_Partial_Finalization then
5162 null;
5164 -- Otherwise emit the ABE disgnostic
5166 else
5167 Error_Msg_Sloc := Sloc (Call);
5168 Error_Msg_N
5169 ("??task & will be activated # before elaboration of its "
5170 & "body", Obj_Id);
5171 Error_Msg_N
5172 ("\Program_Error may be raised at run time", Obj_Id);
5174 Output_Active_Scenarios (Obj_Id, New_In_State);
5175 end if;
5177 -- Install a conditional run-time ABE check to verify that the
5178 -- task body has been elaborated prior to the activation call.
5180 if Check_OK then
5181 Install_Scenario_ABE_Check
5182 (N => Call,
5183 Targ_Id => Defining_Entity (Spec_Decl),
5184 Targ_Rep => Task_Rep,
5185 Disable => Obj_Rep);
5187 -- Update the state of the Processing phase to indicate that
5188 -- no implicit Elaborate[_All] pragma must be generated from
5189 -- this point on.
5191 -- task type Task_Typ;
5193 -- function A ... is
5194 -- begin
5195 -- if Some_Condition then
5196 -- declare
5197 -- package Pack is
5198 -- <ABE check>
5199 -- T : Task_Typ;
5200 -- end Pack; -- activation of T
5201 -- ...
5202 -- end A;
5204 -- X : ... := A;
5206 -- task body Task_Typ is
5207 -- begin
5208 -- External.Subp; -- imparts Elaborate_All
5209 -- end Task_Typ;
5211 -- If Some_Condition is True, then the ABE check will fail
5212 -- at runtime and the call to External.Subp will never take
5213 -- place, rendering the implicit Elaborate_All useless.
5215 -- If the value of Some_Condition is False, then the call
5216 -- to External.Subp will never take place, rendering the
5217 -- implicit Elaborate_All useless.
5219 New_In_State.Suppress_Implicit_Pragmas := True;
5220 end if;
5221 end if;
5223 -- Otherwise the task body is not available in this compilation or
5224 -- it resides in an external unit. Install a run-time ABE check to
5225 -- verify that the task body has been elaborated prior to the
5226 -- activation call when the dynamic model is in effect.
5228 elsif Check_OK
5229 and then New_In_State.Processing = Dynamic_Model_Processing
5230 then
5231 Install_Unit_ABE_Check
5232 (N => Call,
5233 Unit_Id => Unit_Id,
5234 Disable => Obj_Rep);
5235 end if;
5237 -- Both the activation call and task type are subject to SPARK_Mode
5238 -- On, this triggers the SPARK rules for task activation. Compared
5239 -- to calls and instantiations, task activation in SPARK does not
5240 -- require the presence of Elaborate[_All] pragmas in case the task
5241 -- type is defined outside the main unit. This is because SPARK uses
5242 -- a special policy which activates all tasks after the main unit has
5243 -- finished its elaboration.
5245 if SPARK_Mode_Of (Call_Rep) = Is_On
5246 and then SPARK_Mode_Of (Task_Rep) = Is_On
5247 then
5248 null;
5250 -- Otherwise the Ada rules are in effect. Ensure that the unit with
5251 -- the task body is elaborated prior to the main unit.
5253 else
5254 Ensure_Prior_Elaboration
5255 (N => Call,
5256 Unit_Id => Unit_Id,
5257 Prag_Nam => Name_Elaborate_All,
5258 In_State => New_In_State);
5259 end if;
5261 Traverse_Conditional_ABE_Body
5262 (N => Body_Decl,
5263 In_State => New_In_State);
5264 end Process_Conditional_ABE_Activation;
5266 ----------------------------------
5267 -- Process_Conditional_ABE_Call --
5268 ----------------------------------
5270 procedure Process_Conditional_ABE_Call
5271 (Call : Node_Id;
5272 Call_Rep : Scenario_Rep_Id;
5273 In_State : Processing_In_State)
5275 function In_Initialization_Context (N : Node_Id) return Boolean;
5276 pragma Inline (In_Initialization_Context);
5277 -- Determine whether arbitrary node N appears within a type init
5278 -- proc, primitive [Deep_]Initialize, or a block created for
5279 -- initialization purposes.
5281 function Is_Partial_Finalization_Proc
5282 (Subp_Id : Entity_Id) return Boolean;
5283 pragma Inline (Is_Partial_Finalization_Proc);
5284 -- Determine whether subprogram Subp_Id is a partial finalization
5285 -- procedure.
5287 -------------------------------
5288 -- In_Initialization_Context --
5289 -------------------------------
5291 function In_Initialization_Context (N : Node_Id) return Boolean is
5292 Par : Node_Id;
5293 Spec_Id : Entity_Id;
5295 begin
5296 -- Climb the parent chain looking for initialization actions
5298 Par := Parent (N);
5299 while Present (Par) loop
5301 -- A block may be part of the initialization actions of a
5302 -- default initialized object.
5304 if Nkind (Par) = N_Block_Statement
5305 and then Is_Initialization_Block (Par)
5306 then
5307 return True;
5309 -- A subprogram body may denote an initialization routine
5311 elsif Nkind (Par) = N_Subprogram_Body then
5312 Spec_Id := Unique_Defining_Entity (Par);
5314 -- The current subprogram body denotes a type init proc or
5315 -- primitive [Deep_]Initialize.
5317 if Is_Init_Proc (Spec_Id)
5318 or else Is_Controlled_Proc (Spec_Id, Name_Initialize)
5319 or else Is_TSS (Spec_Id, TSS_Deep_Initialize)
5320 then
5321 return True;
5322 end if;
5324 -- Prevent the search from going too far
5326 elsif Is_Body_Or_Package_Declaration (Par) then
5327 exit;
5328 end if;
5330 Par := Parent (Par);
5331 end loop;
5333 return False;
5334 end In_Initialization_Context;
5336 ----------------------------------
5337 -- Is_Partial_Finalization_Proc --
5338 ----------------------------------
5340 function Is_Partial_Finalization_Proc
5341 (Subp_Id : Entity_Id) return Boolean
5343 begin
5344 -- To qualify, the subprogram must denote a finalizer procedure
5345 -- or primitive [Deep_]Finalize, and the call must appear within
5346 -- an initialization context.
5348 return
5349 (Is_Controlled_Proc (Subp_Id, Name_Finalize)
5350 or else Is_Finalizer_Proc (Subp_Id)
5351 or else Is_TSS (Subp_Id, TSS_Deep_Finalize))
5352 and then In_Initialization_Context (Call);
5353 end Is_Partial_Finalization_Proc;
5355 -- Local variables
5357 Subp_Id : constant Entity_Id := Target (Call_Rep);
5358 Subp_Rep : constant Target_Rep_Id :=
5359 Target_Representation_Of (Subp_Id, In_State);
5360 Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
5361 Subp_Decl : constant Node_Id := Spec_Declaration (Subp_Rep);
5363 SPARK_Rules_On : constant Boolean :=
5364 SPARK_Mode_Of (Call_Rep) = Is_On
5365 and then SPARK_Mode_Of (Subp_Rep) = Is_On;
5367 New_In_State : Processing_In_State := In_State;
5368 -- Each step of the Processing phase constitutes a new state
5370 -- Start of processing for Process_Conditional_ABE_Call
5372 begin
5373 -- Output relevant information when switch -gnatel (info messages on
5374 -- implicit Elaborate[_All] pragmas) is in effect.
5376 if Elab_Info_Messages
5377 and then not New_In_State.Suppress_Info_Messages
5378 then
5379 Info_Call
5380 (Call => Call,
5381 Subp_Id => Subp_Id,
5382 Info_Msg => True,
5383 In_SPARK => SPARK_Rules_On);
5384 end if;
5386 -- Check whether the invocation of an entry clashes with an existing
5387 -- restriction. This check is relevant only when the processing was
5388 -- started from some library-level scenario.
5390 if Is_Protected_Entry (Subp_Id) then
5391 Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call);
5393 elsif Is_Task_Entry (Subp_Id) then
5394 Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call);
5396 -- Task entry calls are never processed because the entry being
5397 -- invoked does not have a corresponding "body", it has a select.
5399 return;
5400 end if;
5402 -- Nothing to do when the call invokes a target defined within an
5403 -- instance and switch -gnatd_i (ignore activations and calls to
5404 -- instances for elaboration) is in effect.
5406 if Debug_Flag_Underscore_I
5407 and then In_External_Instance
5408 (N => Call,
5409 Target_Decl => Subp_Decl)
5410 then
5411 return;
5413 -- Nothing to do when the call is a guaranteed ABE
5415 elsif Is_Known_Guaranteed_ABE (Call) then
5416 return;
5418 -- Nothing to do when the root scenario appears at the declaration
5419 -- level and the target is in the same unit but outside this context.
5421 -- function B ...; -- target declaration
5423 -- procedure Proc is
5424 -- function A ... is
5425 -- begin
5426 -- if Some_Condition then
5427 -- return B; -- call site
5428 -- ...
5429 -- end A;
5431 -- X : ... := A; -- root scenario
5432 -- ...
5434 -- function B ... is
5435 -- ...
5436 -- end B;
5438 -- In the example above, the context of X is the declarative region
5439 -- of Proc. The "elaboration" of X may eventually reach B which is
5440 -- defined outside of X's context. B is relevant only when Proc is
5441 -- invoked, but this happens only by means of "normal" elaboration,
5442 -- therefore B must not be considered if this is not the case.
5444 elsif Is_Up_Level_Target
5445 (Targ_Decl => Subp_Decl,
5446 In_State => New_In_State)
5447 then
5448 return;
5449 end if;
5451 -- Warnings are suppressed when a prior scenario is already in that
5452 -- mode, or the call or target have warnings suppressed. Update the
5453 -- state of the Processing phase to reflect this.
5455 New_In_State.Suppress_Warnings :=
5456 New_In_State.Suppress_Warnings
5457 or else not Elaboration_Warnings_OK (Call_Rep)
5458 or else not Elaboration_Warnings_OK (Subp_Rep);
5460 -- The call occurs in freezing actions context when a prior scenario
5461 -- is already in that mode, or when the target is a subprogram whose
5462 -- body has been generated as a freezing action. Update the state of
5463 -- the Processing phase to reflect this.
5465 New_In_State.Within_Freezing_Actions :=
5466 New_In_State.Within_Freezing_Actions
5467 or else (Present (Body_Decl)
5468 and then Nkind (Parent (Body_Decl)) = N_Freeze_Entity);
5470 -- The call occurs in an initial condition context when a prior
5471 -- scenario is already in that mode, or when the target is an
5472 -- Initial_Condition procedure. Update the state of the Processing
5473 -- phase to reflect this.
5475 New_In_State.Within_Initial_Condition :=
5476 New_In_State.Within_Initial_Condition
5477 or else Is_Initial_Condition_Proc (Subp_Id);
5479 -- The call occurs in a partial finalization context when a prior
5480 -- scenario is already in that mode, or when the target denotes a
5481 -- [Deep_]Finalize primitive or a finalizer within an initialization
5482 -- context. Update the state of the Processing phase to reflect this.
5484 New_In_State.Within_Partial_Finalization :=
5485 New_In_State.Within_Partial_Finalization
5486 or else Is_Partial_Finalization_Proc (Subp_Id);
5488 -- The SPARK rules are in effect. Note that -gnatd.v (enforce SPARK
5489 -- elaboration rules in SPARK code) is intentionally not taken into
5490 -- account here because Process_Conditional_ABE_Call_SPARK has two
5491 -- separate modes of operation.
5493 if SPARK_Rules_On then
5494 Process_Conditional_ABE_Call_SPARK
5495 (Call => Call,
5496 Call_Rep => Call_Rep,
5497 Subp_Id => Subp_Id,
5498 Subp_Rep => Subp_Rep,
5499 In_State => New_In_State);
5501 -- Otherwise the Ada rules are in effect
5503 else
5504 Process_Conditional_ABE_Call_Ada
5505 (Call => Call,
5506 Call_Rep => Call_Rep,
5507 Subp_Id => Subp_Id,
5508 Subp_Rep => Subp_Rep,
5509 In_State => New_In_State);
5510 end if;
5512 -- Inspect the target body (and barried function) for other suitable
5513 -- elaboration scenarios.
5515 Traverse_Conditional_ABE_Body
5516 (N => Barrier_Body_Declaration (Subp_Rep),
5517 In_State => New_In_State);
5519 Traverse_Conditional_ABE_Body
5520 (N => Body_Decl,
5521 In_State => New_In_State);
5522 end Process_Conditional_ABE_Call;
5524 --------------------------------------
5525 -- Process_Conditional_ABE_Call_Ada --
5526 --------------------------------------
5528 procedure Process_Conditional_ABE_Call_Ada
5529 (Call : Node_Id;
5530 Call_Rep : Scenario_Rep_Id;
5531 Subp_Id : Entity_Id;
5532 Subp_Rep : Target_Rep_Id;
5533 In_State : Processing_In_State)
5535 Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
5536 Root : constant Node_Id := Root_Scenario;
5537 Unit_Id : constant Node_Id := Unit (Subp_Rep);
5539 Check_OK : constant Boolean :=
5540 not In_State.Suppress_Checks
5541 and then Ghost_Mode_Of (Call_Rep) /= Is_Ignored
5542 and then Ghost_Mode_Of (Subp_Rep) /= Is_Ignored
5543 and then Elaboration_Checks_OK (Call_Rep)
5544 and then Elaboration_Checks_OK (Subp_Rep);
5545 -- A run-time ABE check may be installed only when both the call
5546 -- and the target have active elaboration checks, and both are not
5547 -- ignored Ghost constructs.
5549 New_In_State : Processing_In_State := In_State;
5550 -- Each step of the Processing phase constitutes a new state
5552 begin
5553 -- Nothing to do for an Ada dispatching call because there are no
5554 -- ABE diagnostics for either models. ABE checks for the dynamic
5555 -- model are handled by Install_Primitive_Elaboration_Check.
5557 if Is_Dispatching_Call (Call_Rep) then
5558 return;
5560 -- Nothing to do when the call is ABE-safe
5562 -- generic
5563 -- function Gen ...;
5565 -- function Gen ... is
5566 -- begin
5567 -- ...
5568 -- end Gen;
5570 -- with Gen;
5571 -- procedure Main is
5572 -- function Inst is new Gen;
5573 -- X : ... := Inst; -- safe call
5574 -- ...
5576 elsif Is_Safe_Call (Call, Subp_Id, Subp_Rep) then
5577 return;
5579 -- The call and the target body are both in the main unit
5581 -- If the root scenario appears prior to the target body, then this
5582 -- is a possible ABE with respect to the root scenario.
5584 -- function B ...;
5586 -- function A ... is
5587 -- begin
5588 -- if Some_Condition then
5589 -- return B; -- call site
5590 -- ...
5591 -- end A;
5593 -- X : ... := A; -- root scenario
5595 -- function B ... is -- target body
5596 -- ...
5597 -- end B;
5599 -- Y : ... := A; -- root scenario
5601 -- IMPORTANT: The call to B from A is a possible ABE for X, but
5602 -- not for Y. Installing an unconditional ABE raise prior to the
5603 -- call to B would be wrong as it will fail for Y as well, but in
5604 -- Y's case the call to B is never an ABE.
5606 elsif Present (Body_Decl)
5607 and then In_Extended_Main_Code_Unit (Body_Decl)
5608 then
5609 if Earlier_In_Extended_Unit (Root, Body_Decl) then
5611 -- Do not emit any ABE diagnostics when a previous scenario in
5612 -- this traversal has suppressed elaboration warnings.
5614 if New_In_State.Suppress_Warnings then
5615 null;
5617 -- Do not emit any ABE diagnostics when the call occurs in a
5618 -- partial finalization context because this leads to confusing
5619 -- noise.
5621 elsif New_In_State.Within_Partial_Finalization then
5622 null;
5624 -- Otherwise emit the ABE diagnostic
5626 else
5627 Error_Msg_NE
5628 ("??cannot call & before body seen", Call, Subp_Id);
5629 Error_Msg_N
5630 ("\Program_Error may be raised at run time", Call);
5632 Output_Active_Scenarios (Call, New_In_State);
5633 end if;
5635 -- Install a conditional run-time ABE check to verify that the
5636 -- target body has been elaborated prior to the call.
5638 if Check_OK then
5639 Install_Scenario_ABE_Check
5640 (N => Call,
5641 Targ_Id => Subp_Id,
5642 Targ_Rep => Subp_Rep,
5643 Disable => Call_Rep);
5645 -- Update the state of the Processing phase to indicate that
5646 -- no implicit Elaborate[_All] pragma must be generated from
5647 -- this point on.
5649 -- function B ...;
5651 -- function A ... is
5652 -- begin
5653 -- if Some_Condition then
5654 -- <ABE check>
5655 -- return B;
5656 -- ...
5657 -- end A;
5659 -- X : ... := A;
5661 -- function B ... is
5662 -- External.Subp; -- imparts Elaborate_All
5663 -- end B;
5665 -- If Some_Condition is True, then the ABE check will fail
5666 -- at runtime and the call to External.Subp will never take
5667 -- place, rendering the implicit Elaborate_All useless.
5669 -- If the value of Some_Condition is False, then the call
5670 -- to External.Subp will never take place, rendering the
5671 -- implicit Elaborate_All useless.
5673 New_In_State.Suppress_Implicit_Pragmas := True;
5674 end if;
5675 end if;
5677 -- Otherwise the target body is not available in this compilation or
5678 -- it resides in an external unit. Install a run-time ABE check to
5679 -- verify that the target body has been elaborated prior to the call
5680 -- site when the dynamic model is in effect.
5682 elsif Check_OK
5683 and then New_In_State.Processing = Dynamic_Model_Processing
5684 then
5685 Install_Unit_ABE_Check
5686 (N => Call,
5687 Unit_Id => Unit_Id,
5688 Disable => Call_Rep);
5689 end if;
5691 -- Ensure that the unit with the target body is elaborated prior to
5692 -- the main unit. The implicit Elaborate[_All] is generated only when
5693 -- the call has elaboration checks enabled. This behavior parallels
5694 -- that of the old ABE mechanism.
5696 if Elaboration_Checks_OK (Call_Rep) then
5697 Ensure_Prior_Elaboration
5698 (N => Call,
5699 Unit_Id => Unit_Id,
5700 Prag_Nam => Name_Elaborate_All,
5701 In_State => New_In_State);
5702 end if;
5703 end Process_Conditional_ABE_Call_Ada;
5705 ----------------------------------------
5706 -- Process_Conditional_ABE_Call_SPARK --
5707 ----------------------------------------
5709 procedure Process_Conditional_ABE_Call_SPARK
5710 (Call : Node_Id;
5711 Call_Rep : Scenario_Rep_Id;
5712 Subp_Id : Entity_Id;
5713 Subp_Rep : Target_Rep_Id;
5714 In_State : Processing_In_State)
5716 pragma Unreferenced (Call_Rep);
5718 Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
5719 Region : Node_Id;
5721 begin
5722 -- Ensure that a suitable elaboration model is in effect for SPARK
5723 -- rule verification.
5725 Check_SPARK_Model_In_Effect;
5727 -- The call and the target body are both in the main unit
5729 if Present (Body_Decl)
5730 and then In_Extended_Main_Code_Unit (Body_Decl)
5731 and then Earlier_In_Extended_Unit (Call, Body_Decl)
5732 then
5733 -- Do not emit any ABE diagnostics when a previous scenario in
5734 -- this traversal has suppressed elaboration warnings.
5736 if In_State.Suppress_Warnings then
5737 null;
5739 -- Do not emit any ABE diagnostics when the call occurs in a
5740 -- freezing actions context because this leads to incorrect
5741 -- diagnostics.
5743 elsif In_State.Within_Freezing_Actions then
5744 null;
5746 -- Do not emit any ABE diagnostics when the call occurs in an
5747 -- initial condition context because this leads to incorrect
5748 -- diagnostics.
5750 elsif In_State.Within_Initial_Condition then
5751 null;
5753 -- Do not emit any ABE diagnostics when the call occurs in a
5754 -- partial finalization context because this leads to confusing
5755 -- noise.
5757 elsif In_State.Within_Partial_Finalization then
5758 null;
5760 -- Ensure that a call that textually precedes the subprogram body
5761 -- it invokes appears within the early call region of the body.
5763 -- IMPORTANT: This check must always be performed even when switch
5764 -- -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
5765 -- specified because the static model cannot guarantee the absence
5766 -- of elaboration issues when dispatching calls are involved.
5768 else
5769 Region := Find_Early_Call_Region (Body_Decl);
5771 if Earlier_In_Extended_Unit (Call, Region) then
5772 Error_Msg_NE
5773 ("call must appear within early call region of subprogram "
5774 & "body & (SPARK RM 7.7(3))",
5775 Call, Subp_Id);
5777 Error_Msg_Sloc := Sloc (Region);
5778 Error_Msg_N ("\region starts #", Call);
5780 Error_Msg_Sloc := Sloc (Body_Decl);
5781 Error_Msg_N ("\region ends #", Call);
5783 Output_Active_Scenarios (Call, In_State);
5784 end if;
5785 end if;
5786 end if;
5788 -- A call to a source target or to a target which emulates Ada
5789 -- or SPARK semantics imposes an Elaborate_All requirement on the
5790 -- context of the main unit. Determine whether the context has a
5791 -- pragma strong enough to meet the requirement.
5793 -- IMPORTANT: This check must be performed only when switch -gnatd.v
5794 -- (enforce SPARK elaboration rules in SPARK code) is active because
5795 -- the static model can ensure the prior elaboration of the unit
5796 -- which contains a body by installing an implicit Elaborate[_All]
5797 -- pragma.
5799 if Debug_Flag_Dot_V then
5800 if Comes_From_Source (Subp_Id)
5801 or else Is_Ada_Semantic_Target (Subp_Id)
5802 or else Is_SPARK_Semantic_Target (Subp_Id)
5803 then
5804 Meet_Elaboration_Requirement
5805 (N => Call,
5806 Targ_Id => Subp_Id,
5807 Req_Nam => Name_Elaborate_All,
5808 In_State => In_State);
5809 end if;
5811 -- Otherwise ensure that the unit with the target body is elaborated
5812 -- prior to the main unit.
5814 else
5815 Ensure_Prior_Elaboration
5816 (N => Call,
5817 Unit_Id => Unit (Subp_Rep),
5818 Prag_Nam => Name_Elaborate_All,
5819 In_State => In_State);
5820 end if;
5821 end Process_Conditional_ABE_Call_SPARK;
5823 -------------------------------------------
5824 -- Process_Conditional_ABE_Instantiation --
5825 -------------------------------------------
5827 procedure Process_Conditional_ABE_Instantiation
5828 (Inst : Node_Id;
5829 Inst_Rep : Scenario_Rep_Id;
5830 In_State : Processing_In_State)
5832 Gen_Id : constant Entity_Id := Target (Inst_Rep);
5833 Gen_Rep : constant Target_Rep_Id :=
5834 Target_Representation_Of (Gen_Id, In_State);
5836 SPARK_Rules_On : constant Boolean :=
5837 SPARK_Mode_Of (Inst_Rep) = Is_On
5838 and then SPARK_Mode_Of (Gen_Rep) = Is_On;
5840 New_In_State : Processing_In_State := In_State;
5841 -- Each step of the Processing phase constitutes a new state
5843 begin
5844 -- Output relevant information when switch -gnatel (info messages on
5845 -- implicit Elaborate[_All] pragmas) is in effect.
5847 if Elab_Info_Messages
5848 and then not New_In_State.Suppress_Info_Messages
5849 then
5850 Info_Instantiation
5851 (Inst => Inst,
5852 Gen_Id => Gen_Id,
5853 Info_Msg => True,
5854 In_SPARK => SPARK_Rules_On);
5855 end if;
5857 -- Nothing to do when the instantiation is a guaranteed ABE
5859 if Is_Known_Guaranteed_ABE (Inst) then
5860 return;
5862 -- Nothing to do when the root scenario appears at the declaration
5863 -- level and the generic is in the same unit, but outside this
5864 -- context.
5866 -- generic
5867 -- procedure Gen is ...; -- generic declaration
5869 -- procedure Proc is
5870 -- function A ... is
5871 -- begin
5872 -- if Some_Condition then
5873 -- declare
5874 -- procedure I is new Gen; -- instantiation site
5875 -- ...
5876 -- ...
5877 -- end A;
5879 -- X : ... := A; -- root scenario
5880 -- ...
5882 -- procedure Gen is
5883 -- ...
5884 -- end Gen;
5886 -- In the example above, the context of X is the declarative region
5887 -- of Proc. The "elaboration" of X may eventually reach Gen which
5888 -- appears outside of X's context. Gen is relevant only when Proc is
5889 -- invoked, but this happens only by means of "normal" elaboration,
5890 -- therefore Gen must not be considered if this is not the case.
5892 elsif Is_Up_Level_Target
5893 (Targ_Decl => Spec_Declaration (Gen_Rep),
5894 In_State => New_In_State)
5895 then
5896 return;
5897 end if;
5899 -- Warnings are suppressed when a prior scenario is already in that
5900 -- mode, or when the instantiation has warnings suppressed. Update
5901 -- the state of the processing phase to reflect this.
5903 New_In_State.Suppress_Warnings :=
5904 New_In_State.Suppress_Warnings
5905 or else not Elaboration_Warnings_OK (Inst_Rep);
5907 -- The SPARK rules are in effect
5909 if SPARK_Rules_On then
5910 Process_Conditional_ABE_Instantiation_SPARK
5911 (Inst => Inst,
5912 Inst_Rep => Inst_Rep,
5913 Gen_Id => Gen_Id,
5914 Gen_Rep => Gen_Rep,
5915 In_State => New_In_State);
5917 -- Otherwise the Ada rules are in effect, or SPARK code is allowed to
5918 -- violate the SPARK rules.
5920 else
5921 Process_Conditional_ABE_Instantiation_Ada
5922 (Inst => Inst,
5923 Inst_Rep => Inst_Rep,
5924 Gen_Id => Gen_Id,
5925 Gen_Rep => Gen_Rep,
5926 In_State => New_In_State);
5927 end if;
5928 end Process_Conditional_ABE_Instantiation;
5930 -----------------------------------------------
5931 -- Process_Conditional_ABE_Instantiation_Ada --
5932 -----------------------------------------------
5934 procedure Process_Conditional_ABE_Instantiation_Ada
5935 (Inst : Node_Id;
5936 Inst_Rep : Scenario_Rep_Id;
5937 Gen_Id : Entity_Id;
5938 Gen_Rep : Target_Rep_Id;
5939 In_State : Processing_In_State)
5941 Body_Decl : constant Node_Id := Body_Declaration (Gen_Rep);
5942 Root : constant Node_Id := Root_Scenario;
5943 Unit_Id : constant Entity_Id := Unit (Gen_Rep);
5945 Check_OK : constant Boolean :=
5946 not In_State.Suppress_Checks
5947 and then Ghost_Mode_Of (Inst_Rep) /= Is_Ignored
5948 and then Ghost_Mode_Of (Gen_Rep) /= Is_Ignored
5949 and then Elaboration_Checks_OK (Inst_Rep)
5950 and then Elaboration_Checks_OK (Gen_Rep);
5951 -- A run-time ABE check may be installed only when both the instance
5952 -- and the generic have active elaboration checks and both are not
5953 -- ignored Ghost constructs.
5955 New_In_State : Processing_In_State := In_State;
5956 -- Each step of the Processing phase constitutes a new state
5958 begin
5959 -- Nothing to do when the instantiation is ABE-safe
5961 -- generic
5962 -- package Gen is
5963 -- ...
5964 -- end Gen;
5966 -- package body Gen is
5967 -- ...
5968 -- end Gen;
5970 -- with Gen;
5971 -- procedure Main is
5972 -- package Inst is new Gen (ABE); -- safe instantiation
5973 -- ...
5975 if Is_Safe_Instantiation (Inst, Gen_Id, Gen_Rep) then
5976 return;
5978 -- The instantiation and the generic body are both in the main unit
5980 -- If the root scenario appears prior to the generic body, then this
5981 -- is a possible ABE with respect to the root scenario.
5983 -- generic
5984 -- package Gen is
5985 -- ...
5986 -- end Gen;
5988 -- function A ... is
5989 -- begin
5990 -- if Some_Condition then
5991 -- declare
5992 -- package Inst is new Gen; -- instantiation site
5993 -- ...
5994 -- end A;
5996 -- X : ... := A; -- root scenario
5998 -- package body Gen is -- generic body
5999 -- ...
6000 -- end Gen;
6002 -- Y : ... := A; -- root scenario
6004 -- IMPORTANT: The instantiation of Gen is a possible ABE for X,
6005 -- but not for Y. Installing an unconditional ABE raise prior to
6006 -- the instance site would be wrong as it will fail for Y as well,
6007 -- but in Y's case the instantiation of Gen is never an ABE.
6009 elsif Present (Body_Decl)
6010 and then In_Extended_Main_Code_Unit (Body_Decl)
6011 then
6012 if Earlier_In_Extended_Unit (Root, Body_Decl) then
6014 -- Do not emit any ABE diagnostics when a previous scenario in
6015 -- this traversal has suppressed elaboration warnings.
6017 if New_In_State.Suppress_Warnings then
6018 null;
6020 -- Do not emit any ABE diagnostics when the instantiation
6021 -- occurs in partial finalization context because this leads
6022 -- to unwanted noise.
6024 elsif New_In_State.Within_Partial_Finalization then
6025 null;
6027 -- Otherwise output the diagnostic
6029 else
6030 Error_Msg_NE
6031 ("??cannot instantiate & before body seen", Inst, Gen_Id);
6032 Error_Msg_N
6033 ("\Program_Error may be raised at run time", Inst);
6035 Output_Active_Scenarios (Inst, New_In_State);
6036 end if;
6038 -- Install a conditional run-time ABE check to verify that the
6039 -- generic body has been elaborated prior to the instantiation.
6041 if Check_OK then
6042 Install_Scenario_ABE_Check
6043 (N => Inst,
6044 Targ_Id => Gen_Id,
6045 Targ_Rep => Gen_Rep,
6046 Disable => Inst_Rep);
6048 -- Update the state of the Processing phase to indicate that
6049 -- no implicit Elaborate[_All] pragma must be generated from
6050 -- this point on.
6052 -- generic
6053 -- package Gen is
6054 -- ...
6055 -- end Gen;
6057 -- function A ... is
6058 -- begin
6059 -- if Some_Condition then
6060 -- <ABE check>
6061 -- declare Inst is new Gen;
6062 -- ...
6063 -- end A;
6065 -- X : ... := A;
6067 -- package body Gen is
6068 -- begin
6069 -- External.Subp; -- imparts Elaborate_All
6070 -- end Gen;
6072 -- If Some_Condition is True, then the ABE check will fail
6073 -- at runtime and the call to External.Subp will never take
6074 -- place, rendering the implicit Elaborate_All useless.
6076 -- If the value of Some_Condition is False, then the call
6077 -- to External.Subp will never take place, rendering the
6078 -- implicit Elaborate_All useless.
6080 New_In_State.Suppress_Implicit_Pragmas := True;
6081 end if;
6082 end if;
6084 -- Otherwise the generic body is not available in this compilation
6085 -- or it resides in an external unit. Install a run-time ABE check
6086 -- to verify that the generic body has been elaborated prior to the
6087 -- instantiation when the dynamic model is in effect.
6089 elsif Check_OK
6090 and then New_In_State.Processing = Dynamic_Model_Processing
6091 then
6092 Install_Unit_ABE_Check
6093 (N => Inst,
6094 Unit_Id => Unit_Id,
6095 Disable => Inst_Rep);
6096 end if;
6098 -- Ensure that the unit with the generic body is elaborated prior
6099 -- to the main unit. No implicit pragma has to be generated if the
6100 -- instantiation has elaboration checks suppressed. This behavior
6101 -- parallels that of the old ABE mechanism.
6103 if Elaboration_Checks_OK (Inst_Rep) then
6104 Ensure_Prior_Elaboration
6105 (N => Inst,
6106 Unit_Id => Unit_Id,
6107 Prag_Nam => Name_Elaborate,
6108 In_State => New_In_State);
6109 end if;
6110 end Process_Conditional_ABE_Instantiation_Ada;
6112 -------------------------------------------------
6113 -- Process_Conditional_ABE_Instantiation_SPARK --
6114 -------------------------------------------------
6116 procedure Process_Conditional_ABE_Instantiation_SPARK
6117 (Inst : Node_Id;
6118 Inst_Rep : Scenario_Rep_Id;
6119 Gen_Id : Entity_Id;
6120 Gen_Rep : Target_Rep_Id;
6121 In_State : Processing_In_State)
6123 pragma Unreferenced (Inst_Rep);
6125 Req_Nam : Name_Id;
6127 begin
6128 -- Ensure that a suitable elaboration model is in effect for SPARK
6129 -- rule verification.
6131 Check_SPARK_Model_In_Effect;
6133 -- A source instantiation imposes an Elaborate[_All] requirement
6134 -- on the context of the main unit. Determine whether the context
6135 -- has a pragma strong enough to meet the requirement. The check
6136 -- is orthogonal to the ABE ramifications of the instantiation.
6138 -- IMPORTANT: This check must be performed only when switch -gnatd.v
6139 -- (enforce SPARK elaboration rules in SPARK code) is active because
6140 -- the static model can ensure the prior elaboration of the unit
6141 -- which contains a body by installing an implicit Elaborate[_All]
6142 -- pragma.
6144 if Debug_Flag_Dot_V then
6145 if Nkind (Inst) = N_Package_Instantiation then
6146 Req_Nam := Name_Elaborate_All;
6147 else
6148 Req_Nam := Name_Elaborate;
6149 end if;
6151 Meet_Elaboration_Requirement
6152 (N => Inst,
6153 Targ_Id => Gen_Id,
6154 Req_Nam => Req_Nam,
6155 In_State => In_State);
6157 -- Otherwise ensure that the unit with the target body is elaborated
6158 -- prior to the main unit.
6160 else
6161 Ensure_Prior_Elaboration
6162 (N => Inst,
6163 Unit_Id => Unit (Gen_Rep),
6164 Prag_Nam => Name_Elaborate,
6165 In_State => In_State);
6166 end if;
6167 end Process_Conditional_ABE_Instantiation_SPARK;
6169 -------------------------------------------------
6170 -- Process_Conditional_ABE_Variable_Assignment --
6171 -------------------------------------------------
6173 procedure Process_Conditional_ABE_Variable_Assignment
6174 (Asmt : Node_Id;
6175 Asmt_Rep : Scenario_Rep_Id;
6176 In_State : Processing_In_State)
6179 Var_Id : constant Entity_Id := Target (Asmt_Rep);
6180 Var_Rep : constant Target_Rep_Id :=
6181 Target_Representation_Of (Var_Id, In_State);
6183 SPARK_Rules_On : constant Boolean :=
6184 SPARK_Mode_Of (Asmt_Rep) = Is_On
6185 and then SPARK_Mode_Of (Var_Rep) = Is_On;
6187 begin
6188 -- Output relevant information when switch -gnatel (info messages on
6189 -- implicit Elaborate[_All] pragmas) is in effect.
6191 if Elab_Info_Messages
6192 and then not In_State.Suppress_Info_Messages
6193 then
6194 Elab_Msg_NE
6195 (Msg => "assignment to & during elaboration",
6196 N => Asmt,
6197 Id => Var_Id,
6198 Info_Msg => True,
6199 In_SPARK => SPARK_Rules_On);
6200 end if;
6202 -- The SPARK rules are in effect. These rules are applied regardless
6203 -- of whether switch -gnatd.v (enforce SPARK elaboration rules in
6204 -- SPARK code) is in effect because the static model cannot ensure
6205 -- safe assignment of variables.
6207 if SPARK_Rules_On then
6208 Process_Conditional_ABE_Variable_Assignment_SPARK
6209 (Asmt => Asmt,
6210 Asmt_Rep => Asmt_Rep,
6211 Var_Id => Var_Id,
6212 Var_Rep => Var_Rep,
6213 In_State => In_State);
6215 -- Otherwise the Ada rules are in effect
6217 else
6218 Process_Conditional_ABE_Variable_Assignment_Ada
6219 (Asmt => Asmt,
6220 Asmt_Rep => Asmt_Rep,
6221 Var_Id => Var_Id,
6222 Var_Rep => Var_Rep,
6223 In_State => In_State);
6224 end if;
6225 end Process_Conditional_ABE_Variable_Assignment;
6227 -----------------------------------------------------
6228 -- Process_Conditional_ABE_Variable_Assignment_Ada --
6229 -----------------------------------------------------
6231 procedure Process_Conditional_ABE_Variable_Assignment_Ada
6232 (Asmt : Node_Id;
6233 Asmt_Rep : Scenario_Rep_Id;
6234 Var_Id : Entity_Id;
6235 Var_Rep : Target_Rep_Id;
6236 In_State : Processing_In_State)
6238 pragma Unreferenced (Asmt_Rep);
6240 Var_Decl : constant Node_Id := Variable_Declaration (Var_Rep);
6241 Unit_Id : constant Entity_Id := Unit (Var_Rep);
6243 begin
6244 -- Emit a warning when an uninitialized variable declared in a
6245 -- package spec without a pragma Elaborate_Body is initialized
6246 -- by elaboration code within the corresponding body.
6248 if Is_Elaboration_Warnings_OK_Id (Var_Id)
6249 and then not Is_Initialized (Var_Decl)
6250 and then not Has_Pragma_Elaborate_Body (Unit_Id)
6251 then
6252 -- Do not emit any ABE diagnostics when a previous scenario in
6253 -- this traversal has suppressed elaboration warnings.
6255 if not In_State.Suppress_Warnings then
6256 Error_Msg_NE
6257 ("??variable & can be accessed by clients before this "
6258 & "initialization", Asmt, Var_Id);
6260 Error_Msg_NE
6261 ("\add pragma ""Elaborate_Body"" to spec & to ensure proper "
6262 & "initialization", Asmt, Unit_Id);
6264 Output_Active_Scenarios (Asmt, In_State);
6265 end if;
6267 -- Generate an implicit Elaborate_Body in the spec
6269 Set_Elaborate_Body_Desirable (Unit_Id);
6270 end if;
6271 end Process_Conditional_ABE_Variable_Assignment_Ada;
6273 -------------------------------------------------------
6274 -- Process_Conditional_ABE_Variable_Assignment_SPARK --
6275 -------------------------------------------------------
6277 procedure Process_Conditional_ABE_Variable_Assignment_SPARK
6278 (Asmt : Node_Id;
6279 Asmt_Rep : Scenario_Rep_Id;
6280 Var_Id : Entity_Id;
6281 Var_Rep : Target_Rep_Id;
6282 In_State : Processing_In_State)
6284 pragma Unreferenced (Asmt_Rep);
6286 Var_Decl : constant Node_Id := Variable_Declaration (Var_Rep);
6287 Unit_Id : constant Entity_Id := Unit (Var_Rep);
6289 begin
6290 -- Ensure that a suitable elaboration model is in effect for SPARK
6291 -- rule verification.
6293 Check_SPARK_Model_In_Effect;
6295 -- Do not emit any ABE diagnostics when a previous scenario in this
6296 -- traversal has suppressed elaboration warnings.
6298 if In_State.Suppress_Warnings then
6299 null;
6301 -- Emit an error when an initialized variable declared in a package
6302 -- spec that is missing pragma Elaborate_Body is further modified by
6303 -- elaboration code within the corresponding body.
6305 elsif Is_Elaboration_Warnings_OK_Id (Var_Id)
6306 and then Is_Initialized (Var_Decl)
6307 and then not Has_Pragma_Elaborate_Body (Unit_Id)
6308 then
6309 Error_Msg_NE
6310 ("variable & modified by elaboration code in package body",
6311 Asmt, Var_Id);
6313 Error_Msg_NE
6314 ("\add pragma ""Elaborate_Body"" to spec & to ensure full "
6315 & "initialization", Asmt, Unit_Id);
6317 Output_Active_Scenarios (Asmt, In_State);
6318 end if;
6319 end Process_Conditional_ABE_Variable_Assignment_SPARK;
6321 ------------------------------------------------
6322 -- Process_Conditional_ABE_Variable_Reference --
6323 ------------------------------------------------
6325 procedure Process_Conditional_ABE_Variable_Reference
6326 (Ref : Node_Id;
6327 Ref_Rep : Scenario_Rep_Id;
6328 In_State : Processing_In_State)
6330 Var_Id : constant Entity_Id := Target (Ref);
6331 Var_Rep : Target_Rep_Id;
6332 Unit_Id : Entity_Id;
6334 begin
6335 -- Nothing to do when the variable reference is not a read
6337 if not Is_Read_Reference (Ref_Rep) then
6338 return;
6339 end if;
6341 Var_Rep := Target_Representation_Of (Var_Id, In_State);
6342 Unit_Id := Unit (Var_Rep);
6344 -- Output relevant information when switch -gnatel (info messages on
6345 -- implicit Elaborate[_All] pragmas) is in effect.
6347 if Elab_Info_Messages
6348 and then not In_State.Suppress_Info_Messages
6349 then
6350 Elab_Msg_NE
6351 (Msg => "read of variable & during elaboration",
6352 N => Ref,
6353 Id => Var_Id,
6354 Info_Msg => True,
6355 In_SPARK => True);
6356 end if;
6358 -- Nothing to do when the variable appears within the main unit
6359 -- because diagnostics on reads are relevant only for external
6360 -- variables.
6362 if Is_Same_Unit (Unit_Id, Main_Unit_Entity) then
6363 null;
6365 -- Nothing to do when the variable is already initialized. Note that
6366 -- the variable may be further modified by the external unit.
6368 elsif Is_Initialized (Variable_Declaration (Var_Rep)) then
6369 null;
6371 -- Nothing to do when the external unit guarantees the initialization
6372 -- of the variable by means of pragma Elaborate_Body.
6374 elsif Has_Pragma_Elaborate_Body (Unit_Id) then
6375 null;
6377 -- A variable read imposes an Elaborate requirement on the context of
6378 -- the main unit. Determine whether the context has a pragma strong
6379 -- enough to meet the requirement.
6381 else
6382 Meet_Elaboration_Requirement
6383 (N => Ref,
6384 Targ_Id => Var_Id,
6385 Req_Nam => Name_Elaborate,
6386 In_State => In_State);
6387 end if;
6388 end Process_Conditional_ABE_Variable_Reference;
6390 -----------------------------------
6391 -- Traverse_Conditional_ABE_Body --
6392 -----------------------------------
6394 procedure Traverse_Conditional_ABE_Body
6395 (N : Node_Id;
6396 In_State : Processing_In_State)
6398 begin
6399 Traverse_Body
6400 (N => N,
6401 Requires_Processing => Is_Conditional_ABE_Scenario'Access,
6402 Processor => Process_Conditional_ABE'Access,
6403 In_State => In_State);
6404 end Traverse_Conditional_ABE_Body;
6405 end Conditional_ABE_Processor;
6407 -------------
6408 -- Destroy --
6409 -------------
6411 procedure Destroy (NE : in out Node_Or_Entity_Id) is
6412 pragma Unreferenced (NE);
6413 begin
6414 null;
6415 end Destroy;
6417 -----------------
6418 -- Diagnostics --
6419 -----------------
6421 package body Diagnostics is
6423 -----------------
6424 -- Elab_Msg_NE --
6425 -----------------
6427 procedure Elab_Msg_NE
6428 (Msg : String;
6429 N : Node_Id;
6430 Id : Entity_Id;
6431 Info_Msg : Boolean;
6432 In_SPARK : Boolean)
6434 function Prefix return String;
6435 pragma Inline (Prefix);
6436 -- Obtain the prefix of the message
6438 function Suffix return String;
6439 pragma Inline (Suffix);
6440 -- Obtain the suffix of the message
6442 ------------
6443 -- Prefix --
6444 ------------
6446 function Prefix return String is
6447 begin
6448 if Info_Msg then
6449 return "info: ";
6450 else
6451 return "";
6452 end if;
6453 end Prefix;
6455 ------------
6456 -- Suffix --
6457 ------------
6459 function Suffix return String is
6460 begin
6461 if In_SPARK then
6462 return " in SPARK";
6463 else
6464 return "";
6465 end if;
6466 end Suffix;
6468 -- Start of processing for Elab_Msg_NE
6470 begin
6471 Error_Msg_NE (Prefix & Msg & Suffix, N, Id);
6472 end Elab_Msg_NE;
6474 ---------------
6475 -- Info_Call --
6476 ---------------
6478 procedure Info_Call
6479 (Call : Node_Id;
6480 Subp_Id : Entity_Id;
6481 Info_Msg : Boolean;
6482 In_SPARK : Boolean)
6484 procedure Info_Accept_Alternative;
6485 pragma Inline (Info_Accept_Alternative);
6486 -- Output information concerning an accept alternative
6488 procedure Info_Simple_Call;
6489 pragma Inline (Info_Simple_Call);
6490 -- Output information concerning the call
6492 procedure Info_Type_Actions (Action : String);
6493 pragma Inline (Info_Type_Actions);
6494 -- Output information concerning action Action of a type
6496 procedure Info_Verification_Call
6497 (Pred : String;
6498 Id : Entity_Id;
6499 Id_Kind : String);
6500 pragma Inline (Info_Verification_Call);
6501 -- Output information concerning the verification of predicate Pred
6502 -- applied to related entity Id with kind Id_Kind.
6504 -----------------------------
6505 -- Info_Accept_Alternative --
6506 -----------------------------
6508 procedure Info_Accept_Alternative is
6509 Entry_Id : constant Entity_Id := Receiving_Entry (Subp_Id);
6510 pragma Assert (Present (Entry_Id));
6512 begin
6513 Elab_Msg_NE
6514 (Msg => "accept for entry & during elaboration",
6515 N => Call,
6516 Id => Entry_Id,
6517 Info_Msg => Info_Msg,
6518 In_SPARK => In_SPARK);
6519 end Info_Accept_Alternative;
6521 ----------------------
6522 -- Info_Simple_Call --
6523 ----------------------
6525 procedure Info_Simple_Call is
6526 begin
6527 Elab_Msg_NE
6528 (Msg => "call to & during elaboration",
6529 N => Call,
6530 Id => Subp_Id,
6531 Info_Msg => Info_Msg,
6532 In_SPARK => In_SPARK);
6533 end Info_Simple_Call;
6535 -----------------------
6536 -- Info_Type_Actions --
6537 -----------------------
6539 procedure Info_Type_Actions (Action : String) is
6540 Typ : constant Entity_Id := First_Formal_Type (Subp_Id);
6541 pragma Assert (Present (Typ));
6543 begin
6544 Elab_Msg_NE
6545 (Msg => Action & " actions for type & during elaboration",
6546 N => Call,
6547 Id => Typ,
6548 Info_Msg => Info_Msg,
6549 In_SPARK => In_SPARK);
6550 end Info_Type_Actions;
6552 ----------------------------
6553 -- Info_Verification_Call --
6554 ----------------------------
6556 procedure Info_Verification_Call
6557 (Pred : String;
6558 Id : Entity_Id;
6559 Id_Kind : String)
6561 pragma Assert (Present (Id));
6563 begin
6564 Elab_Msg_NE
6565 (Msg =>
6566 "verification of " & Pred & " of " & Id_Kind & " & during "
6567 & "elaboration",
6568 N => Call,
6569 Id => Id,
6570 Info_Msg => Info_Msg,
6571 In_SPARK => In_SPARK);
6572 end Info_Verification_Call;
6574 -- Start of processing for Info_Call
6576 begin
6577 -- Do not output anything for targets defined in internal units
6578 -- because this creates noise.
6580 if not In_Internal_Unit (Subp_Id) then
6582 -- Accept alternative
6584 if Is_Accept_Alternative_Proc (Subp_Id) then
6585 Info_Accept_Alternative;
6587 -- Adjustment
6589 elsif Is_TSS (Subp_Id, TSS_Deep_Adjust) then
6590 Info_Type_Actions ("adjustment");
6592 -- Default_Initial_Condition
6594 elsif Is_Default_Initial_Condition_Proc (Subp_Id) then
6595 Info_Verification_Call
6596 (Pred => "Default_Initial_Condition",
6597 Id => First_Formal_Type (Subp_Id),
6598 Id_Kind => "type");
6600 -- Entries
6602 elsif Is_Protected_Entry (Subp_Id) then
6603 Info_Simple_Call;
6605 -- Task entry calls are never processed because the entry being
6606 -- invoked does not have a corresponding "body", it has a select.
6608 elsif Is_Task_Entry (Subp_Id) then
6609 null;
6611 -- Finalization
6613 elsif Is_TSS (Subp_Id, TSS_Deep_Finalize) then
6614 Info_Type_Actions ("finalization");
6616 -- Calls to _Finalizer procedures must not appear in the output
6617 -- because this creates confusing noise.
6619 elsif Is_Finalizer_Proc (Subp_Id) then
6620 null;
6622 -- Initial_Condition
6624 elsif Is_Initial_Condition_Proc (Subp_Id) then
6625 Info_Verification_Call
6626 (Pred => "Initial_Condition",
6627 Id => Find_Enclosing_Scope (Call),
6628 Id_Kind => "package");
6630 -- Initialization
6632 elsif Is_Init_Proc (Subp_Id)
6633 or else Is_TSS (Subp_Id, TSS_Deep_Initialize)
6634 then
6635 Info_Type_Actions ("initialization");
6637 -- Invariant
6639 elsif Is_Invariant_Proc (Subp_Id) then
6640 Info_Verification_Call
6641 (Pred => "invariants",
6642 Id => First_Formal_Type (Subp_Id),
6643 Id_Kind => "type");
6645 -- Partial invariant calls must not appear in the output because
6646 -- this creates confusing noise.
6648 elsif Is_Partial_Invariant_Proc (Subp_Id) then
6649 null;
6651 -- Subprograms must come last because some of the previous cases
6652 -- fall under this category.
6654 elsif Ekind (Subp_Id) = E_Function then
6655 Info_Simple_Call;
6657 elsif Ekind (Subp_Id) = E_Procedure then
6658 Info_Simple_Call;
6660 else
6661 pragma Assert (False);
6662 return;
6663 end if;
6664 end if;
6665 end Info_Call;
6667 ------------------------
6668 -- Info_Instantiation --
6669 ------------------------
6671 procedure Info_Instantiation
6672 (Inst : Node_Id;
6673 Gen_Id : Entity_Id;
6674 Info_Msg : Boolean;
6675 In_SPARK : Boolean)
6677 begin
6678 Elab_Msg_NE
6679 (Msg => "instantiation of & during elaboration",
6680 N => Inst,
6681 Id => Gen_Id,
6682 Info_Msg => Info_Msg,
6683 In_SPARK => In_SPARK);
6684 end Info_Instantiation;
6686 -----------------------------
6687 -- Info_Variable_Reference --
6688 -----------------------------
6690 procedure Info_Variable_Reference
6691 (Ref : Node_Id;
6692 Var_Id : Entity_Id)
6694 begin
6695 if Is_Read (Ref) then
6696 Elab_Msg_NE
6697 (Msg => "read of variable & during elaboration",
6698 N => Ref,
6699 Id => Var_Id,
6700 Info_Msg => False,
6701 In_SPARK => True);
6702 end if;
6703 end Info_Variable_Reference;
6704 end Diagnostics;
6706 ---------------------------------
6707 -- Early_Call_Region_Processor --
6708 ---------------------------------
6710 package body Early_Call_Region_Processor is
6712 ---------------------
6713 -- Data structures --
6714 ---------------------
6716 -- The following map relates early call regions to subprogram bodies
6718 procedure Destroy (N : in out Node_Id);
6719 -- Destroy node N
6721 package ECR_Map is new Dynamic_Hash_Tables
6722 (Key_Type => Entity_Id,
6723 Value_Type => Node_Id,
6724 No_Value => Empty,
6725 Expansion_Threshold => 1.5,
6726 Expansion_Factor => 2,
6727 Compression_Threshold => 0.3,
6728 Compression_Factor => 2,
6729 "=" => "=",
6730 Destroy_Value => Destroy,
6731 Hash => Hash);
6733 Early_Call_Regions_Map : ECR_Map.Dynamic_Hash_Table := ECR_Map.Nil;
6735 -----------------------
6736 -- Local subprograms --
6737 -----------------------
6739 function Early_Call_Region (Body_Id : Entity_Id) return Node_Id;
6740 pragma Inline (Early_Call_Region);
6741 -- Obtain the early call region associated with entry or subprogram body
6742 -- Body_Id.
6744 procedure Set_Early_Call_Region (Body_Id : Entity_Id; Start : Node_Id);
6745 pragma Inline (Set_Early_Call_Region);
6746 -- Associate an early call region with begins at construct Start with
6747 -- entry or subprogram body Body_Id.
6749 -------------
6750 -- Destroy --
6751 -------------
6753 procedure Destroy (N : in out Node_Id) is
6754 pragma Unreferenced (N);
6755 begin
6756 null;
6757 end Destroy;
6759 -----------------------
6760 -- Early_Call_Region --
6761 -----------------------
6763 function Early_Call_Region (Body_Id : Entity_Id) return Node_Id is
6764 pragma Assert (Present (Body_Id));
6765 begin
6766 return ECR_Map.Get (Early_Call_Regions_Map, Body_Id);
6767 end Early_Call_Region;
6769 ------------------------------------------
6770 -- Finalize_Early_Call_Region_Processor --
6771 ------------------------------------------
6773 procedure Finalize_Early_Call_Region_Processor is
6774 begin
6775 ECR_Map.Destroy (Early_Call_Regions_Map);
6776 end Finalize_Early_Call_Region_Processor;
6778 ----------------------------
6779 -- Find_Early_Call_Region --
6780 ----------------------------
6782 function Find_Early_Call_Region
6783 (Body_Decl : Node_Id;
6784 Assume_Elab_Body : Boolean := False;
6785 Skip_Memoization : Boolean := False) return Node_Id
6787 -- NOTE: The routines within Find_Early_Call_Region are intentionally
6788 -- unnested to avoid deep indentation of code.
6790 ECR_Found : exception;
6791 -- This exception is raised when the early call region has been found
6793 Start : Node_Id := Empty;
6794 -- The start of the early call region. This variable is updated by
6795 -- the various nested routines. Due to the use of exceptions, the
6796 -- variable must be global to the nested routines.
6798 -- The algorithm implemented in this routine attempts to find the
6799 -- early call region of a subprogram body by inspecting constructs
6800 -- in reverse declarative order, while navigating the tree. The
6801 -- algorithm consists of an Inspection phase and Advancement phase.
6802 -- The pseudocode is as follows:
6804 -- loop
6805 -- inspection phase
6806 -- advancement phase
6807 -- end loop
6809 -- The infinite loop is terminated by raising exception ECR_Found.
6810 -- The algorithm utilizes two pointers, Curr and Start, to represent
6811 -- the current construct to inspect and the start of the early call
6812 -- region.
6814 -- IMPORTANT: The algorithm must maintain the following invariant at
6815 -- all time for it to function properly:
6817 -- A nested construct is entered only when it contains suitable
6818 -- constructs.
6820 -- This guarantees that leaving a nested or encapsulating construct
6821 -- functions properly.
6823 -- The Inspection phase determines whether the current construct is
6824 -- non-preelaborable, and if it is, the algorithm terminates.
6826 -- The Advancement phase walks the tree in reverse declarative order,
6827 -- while entering and leaving nested and encapsulating constructs. It
6828 -- may also terminate the elaborithm. There are several special cases
6829 -- of advancement.
6831 -- 1) General case:
6833 -- <construct 1>
6834 -- ...
6835 -- <construct N-1> <- Curr
6836 -- <construct N> <- Start
6837 -- <subprogram body>
6839 -- In the general case, a declarative or statement list is traversed
6840 -- in reverse order where Curr is the lead pointer, and Start is the
6841 -- last preelaborable construct.
6843 -- 2) Entering handled bodies
6845 -- package body Nested is <- Curr (2.3)
6846 -- <declarations> <- Curr (2.2)
6847 -- begin
6848 -- <statements> <- Curr (2.1)
6849 -- end Nested;
6850 -- <construct> <- Start
6852 -- In this case, the algorithm enters a handled body by starting from
6853 -- the last statement (2.1), or the last declaration (2.2), or the
6854 -- body is consumed (2.3) because it is empty and thus preelaborable.
6856 -- 3) Entering package declarations
6858 -- package Nested is <- Curr (2.3)
6859 -- <visible declarations> <- Curr (2.2)
6860 -- private
6861 -- <private declarations> <- Curr (2.1)
6862 -- end Nested;
6863 -- <construct> <- Start
6865 -- In this case, the algorithm enters a package declaration by
6866 -- starting from the last private declaration (2.1), the last visible
6867 -- declaration (2.2), or the package is consumed (2.3) because it is
6868 -- empty and thus preelaborable.
6870 -- 4) Transitioning from list to list of the same construct
6872 -- Certain constructs have two eligible lists. The algorithm must
6873 -- thus transition from the second to the first list when the second
6874 -- list is exhausted.
6876 -- declare <- Curr (4.2)
6877 -- <declarations> <- Curr (4.1)
6878 -- begin
6879 -- <statements> <- Start
6880 -- end;
6882 -- In this case, the algorithm has exhausted the second list (the
6883 -- statements in the example above), and continues with the last
6884 -- declaration (4.1) or the construct is consumed (4.2) because it
6885 -- contains only preelaborable code.
6887 -- 5) Transitioning from list to construct
6889 -- tack body Task is <- Curr (5.1)
6890 -- <- Curr (Empty)
6891 -- <construct 1> <- Start
6893 -- In this case, the algorithm has exhausted a list, Curr is Empty,
6894 -- and the owner of the list is consumed (5.1).
6896 -- 6) Transitioning from unit to unit
6898 -- A package body with a spec subject to pragma Elaborate_Body
6899 -- extends the possible range of the early call region to the package
6900 -- spec.
6902 -- package Pack is <- Curr (6.3)
6903 -- pragma Elaborate_Body; <- Curr (6.2)
6904 -- <visible declarations> <- Curr (6.2)
6905 -- private
6906 -- <private declarations> <- Curr (6.1)
6907 -- end Pack;
6909 -- package body Pack is <- Curr, Start
6911 -- In this case, the algorithm has reached a package body compilation
6912 -- unit whose spec is subject to pragma Elaborate_Body, or the caller
6913 -- of the algorithm has specified this behavior. This transition is
6914 -- equivalent to 3).
6916 -- 7) Transitioning from unit to termination
6918 -- Reaching a compilation unit always terminates the algorithm as
6919 -- there are no more lists to examine. This must take case 6) into
6920 -- account.
6922 -- 8) Transitioning from subunit to stub
6924 -- package body Pack is separate; <- Curr (8.1)
6926 -- separate (...)
6927 -- package body Pack is <- Curr, Start
6929 -- Reaching a subunit continues the search from the corresponding
6930 -- stub (8.1).
6932 procedure Advance (Curr : in out Node_Id);
6933 pragma Inline (Advance);
6934 -- Update the Curr and Start pointers depending on their location
6935 -- in the tree to the next eligible construct. This routine raises
6936 -- ECR_Found.
6938 procedure Enter_Handled_Body (Curr : in out Node_Id);
6939 pragma Inline (Enter_Handled_Body);
6940 -- Update the Curr and Start pointers to enter a nested handled body
6941 -- if applicable. This routine raises ECR_Found.
6943 procedure Enter_Package_Declaration (Curr : in out Node_Id);
6944 pragma Inline (Enter_Package_Declaration);
6945 -- Update the Curr and Start pointers to enter a nested package spec
6946 -- if applicable. This routine raises ECR_Found.
6948 function Find_ECR (N : Node_Id) return Node_Id;
6949 pragma Inline (Find_ECR);
6950 -- Find an early call region starting from arbitrary node N
6952 function Has_Suitable_Construct (List : List_Id) return Boolean;
6953 pragma Inline (Has_Suitable_Construct);
6954 -- Determine whether list List contains a suitable construct for
6955 -- inclusion into an early call region.
6957 procedure Include (N : Node_Id; Curr : out Node_Id);
6958 pragma Inline (Include);
6959 -- Update the Curr and Start pointers to include arbitrary construct
6960 -- N in the early call region. This routine raises ECR_Found.
6962 function Is_OK_Preelaborable_Construct (N : Node_Id) return Boolean;
6963 pragma Inline (Is_OK_Preelaborable_Construct);
6964 -- Determine whether arbitrary node N denotes a preelaboration-safe
6965 -- construct.
6967 function Is_Suitable_Construct (N : Node_Id) return Boolean;
6968 pragma Inline (Is_Suitable_Construct);
6969 -- Determine whether arbitrary node N denotes a suitable construct
6970 -- for inclusion into the early call region.
6972 function Previous_Suitable_Construct (N : Node_Id) return Node_Id;
6973 pragma Inline (Previous_Suitable_Construct);
6974 -- Return the previous node suitable for inclusion into the early
6975 -- call region.
6977 procedure Transition_Body_Declarations
6978 (Bod : Node_Id;
6979 Curr : out Node_Id);
6980 pragma Inline (Transition_Body_Declarations);
6981 -- Update the Curr and Start pointers when construct Bod denotes a
6982 -- block statement or a suitable body. This routine raises ECR_Found.
6984 procedure Transition_Handled_Statements
6985 (HSS : Node_Id;
6986 Curr : out Node_Id);
6987 pragma Inline (Transition_Handled_Statements);
6988 -- Update the Curr and Start pointers when node HSS denotes a handled
6989 -- sequence of statements. This routine raises ECR_Found.
6991 procedure Transition_Spec_Declarations
6992 (Spec : Node_Id;
6993 Curr : out Node_Id);
6994 pragma Inline (Transition_Spec_Declarations);
6995 -- Update the Curr and Start pointers when construct Spec denotes
6996 -- a concurrent definition or a package spec. This routine raises
6997 -- ECR_Found.
6999 procedure Transition_Unit (Unit : Node_Id; Curr : out Node_Id);
7000 pragma Inline (Transition_Unit);
7001 -- Update the Curr and Start pointers when node Unit denotes a
7002 -- potential compilation unit. This routine raises ECR_Found.
7004 -------------
7005 -- Advance --
7006 -------------
7008 procedure Advance (Curr : in out Node_Id) is
7009 Context : Node_Id;
7011 begin
7012 -- Curr denotes one of the following cases upon entry into this
7013 -- routine:
7015 -- * Empty - There is no current construct when a declarative or
7016 -- a statement list has been exhausted. This does not indicate
7017 -- that the early call region has been computed as it is still
7018 -- possible to transition to another list.
7020 -- * Encapsulator - The current construct wraps declarations
7021 -- and/or statements. This indicates that the early call
7022 -- region may extend within the nested construct.
7024 -- * Preelaborable - The current construct is preelaborable
7025 -- because Find_ECR would not invoke Advance if this was not
7026 -- the case.
7028 -- The current construct is an encapsulator or is preelaborable
7030 if Present (Curr) then
7032 -- Enter encapsulators by inspecting their declarations and/or
7033 -- statements.
7035 if Nkind (Curr) in N_Block_Statement | N_Package_Body then
7036 Enter_Handled_Body (Curr);
7038 elsif Nkind (Curr) = N_Package_Declaration then
7039 Enter_Package_Declaration (Curr);
7041 -- Early call regions have a property which can be exploited to
7042 -- optimize the algorithm.
7044 -- <preceding subprogram body>
7045 -- <preelaborable construct 1>
7046 -- ...
7047 -- <preelaborable construct N>
7048 -- <initiating subprogram body>
7050 -- If a traversal initiated from a subprogram body reaches a
7051 -- preceding subprogram body, then both bodies share the same
7052 -- early call region.
7054 -- The property results in the following desirable effects:
7056 -- * If the preceding body already has an early call region,
7057 -- then the initiating body can reuse it. This minimizes the
7058 -- amount of processing performed by the algorithm.
7060 -- * If the preceding body lack an early call region, then the
7061 -- algorithm can compute the early call region, and reuse it
7062 -- for the initiating body. This processing performs the same
7063 -- amount of work, but has the beneficial effect of computing
7064 -- the early call regions of all preceding bodies.
7066 elsif Nkind (Curr) in N_Entry_Body | N_Subprogram_Body then
7067 Start :=
7068 Find_Early_Call_Region
7069 (Body_Decl => Curr,
7070 Assume_Elab_Body => Assume_Elab_Body,
7071 Skip_Memoization => Skip_Memoization);
7073 raise ECR_Found;
7075 -- Otherwise current construct is preelaborable. Unpdate the
7076 -- early call region to include it.
7078 else
7079 Include (Curr, Curr);
7080 end if;
7082 -- Otherwise the current construct is missing, indicating that the
7083 -- current list has been exhausted. Depending on the context of
7084 -- the list, several transitions are possible.
7086 else
7087 -- The invariant of the algorithm ensures that Curr and Start
7088 -- are at the same level of nesting at the point of transition.
7089 -- The algorithm can determine which list the traversal came
7090 -- from by examining Start.
7092 Context := Parent (Start);
7094 -- Attempt the following transitions:
7096 -- private declarations -> visible declarations
7097 -- private declarations -> upper level
7098 -- private declarations -> terminate
7099 -- visible declarations -> upper level
7100 -- visible declarations -> terminate
7102 if Nkind (Context) in N_Package_Specification
7103 | N_Protected_Definition
7104 | N_Task_Definition
7105 then
7106 Transition_Spec_Declarations (Context, Curr);
7108 -- Attempt the following transitions:
7110 -- statements -> declarations
7111 -- statements -> upper level
7112 -- statements -> corresponding package spec (Elab_Body)
7113 -- statements -> terminate
7115 elsif Nkind (Context) = N_Handled_Sequence_Of_Statements then
7116 Transition_Handled_Statements (Context, Curr);
7118 -- Attempt the following transitions:
7120 -- declarations -> upper level
7121 -- declarations -> corresponding package spec (Elab_Body)
7122 -- declarations -> terminate
7124 elsif Nkind (Context) in N_Block_Statement
7125 | N_Entry_Body
7126 | N_Package_Body
7127 | N_Protected_Body
7128 | N_Subprogram_Body
7129 | N_Task_Body
7130 then
7131 Transition_Body_Declarations (Context, Curr);
7133 -- Otherwise it is not possible to transition. Stop the search
7134 -- because there are no more declarations or statements to
7135 -- check.
7137 else
7138 raise ECR_Found;
7139 end if;
7140 end if;
7141 end Advance;
7143 --------------------------
7144 -- Enter_Handled_Body --
7145 --------------------------
7147 procedure Enter_Handled_Body (Curr : in out Node_Id) is
7148 Decls : constant List_Id := Declarations (Curr);
7149 HSS : constant Node_Id := Handled_Statement_Sequence (Curr);
7150 Stmts : List_Id := No_List;
7152 begin
7153 if Present (HSS) then
7154 Stmts := Statements (HSS);
7155 end if;
7157 -- The handled body has a non-empty statement sequence. The
7158 -- construct to inspect is the last statement.
7160 if Has_Suitable_Construct (Stmts) then
7161 Curr := Last (Stmts);
7163 -- The handled body lacks statements, but has non-empty
7164 -- declarations. The construct to inspect is the last declaration.
7166 elsif Has_Suitable_Construct (Decls) then
7167 Curr := Last (Decls);
7169 -- Otherwise the handled body lacks both declarations and
7170 -- statements. The construct to inspect is the node which precedes
7171 -- the handled body. Update the early call region to include the
7172 -- handled body.
7174 else
7175 Include (Curr, Curr);
7176 end if;
7177 end Enter_Handled_Body;
7179 -------------------------------
7180 -- Enter_Package_Declaration --
7181 -------------------------------
7183 procedure Enter_Package_Declaration (Curr : in out Node_Id) is
7184 Pack_Spec : constant Node_Id := Specification (Curr);
7185 Prv_Decls : constant List_Id := Private_Declarations (Pack_Spec);
7186 Vis_Decls : constant List_Id := Visible_Declarations (Pack_Spec);
7188 begin
7189 -- The package has a non-empty private declarations. The construct
7190 -- to inspect is the last private declaration.
7192 if Has_Suitable_Construct (Prv_Decls) then
7193 Curr := Last (Prv_Decls);
7195 -- The package lacks private declarations, but has non-empty
7196 -- visible declarations. In this case the construct to inspect
7197 -- is the last visible declaration.
7199 elsif Has_Suitable_Construct (Vis_Decls) then
7200 Curr := Last (Vis_Decls);
7202 -- Otherwise the package lacks any declarations. The construct
7203 -- to inspect is the node which precedes the package. Update the
7204 -- early call region to include the package declaration.
7206 else
7207 Include (Curr, Curr);
7208 end if;
7209 end Enter_Package_Declaration;
7211 --------------
7212 -- Find_ECR --
7213 --------------
7215 function Find_ECR (N : Node_Id) return Node_Id is
7216 Curr : Node_Id;
7218 begin
7219 -- The early call region starts at N
7221 Curr := Previous_Suitable_Construct (N);
7222 Start := N;
7224 -- Inspect each node in reverse declarative order while going in
7225 -- and out of nested and enclosing constructs. Note that the only
7226 -- way to terminate this infinite loop is to raise ECR_Found.
7228 loop
7229 -- The current construct is not preelaboration-safe. Terminate
7230 -- the traversal.
7232 if Present (Curr)
7233 and then not Is_OK_Preelaborable_Construct (Curr)
7234 then
7235 raise ECR_Found;
7236 end if;
7238 -- Advance to the next suitable construct. This may terminate
7239 -- the traversal by raising ECR_Found.
7241 Advance (Curr);
7242 end loop;
7244 exception
7245 when ECR_Found =>
7246 return Start;
7247 end Find_ECR;
7249 ----------------------------
7250 -- Has_Suitable_Construct --
7251 ----------------------------
7253 function Has_Suitable_Construct (List : List_Id) return Boolean is
7254 Item : Node_Id;
7256 begin
7257 -- Examine the list in reverse declarative order, looking for a
7258 -- suitable construct.
7260 if Present (List) then
7261 Item := Last (List);
7262 while Present (Item) loop
7263 if Is_Suitable_Construct (Item) then
7264 return True;
7265 end if;
7267 Prev (Item);
7268 end loop;
7269 end if;
7271 return False;
7272 end Has_Suitable_Construct;
7274 -------------
7275 -- Include --
7276 -------------
7278 procedure Include (N : Node_Id; Curr : out Node_Id) is
7279 begin
7280 Start := N;
7282 -- The input node is a compilation unit. This terminates the
7283 -- search because there are no more lists to inspect and there are
7284 -- no more enclosing constructs to climb up to. The transitions
7285 -- are:
7287 -- private declarations -> terminate
7288 -- visible declarations -> terminate
7289 -- statements -> terminate
7290 -- declarations -> terminate
7292 if Nkind (Parent (Start)) = N_Compilation_Unit then
7293 raise ECR_Found;
7295 -- Otherwise the input node is still within some list
7297 else
7298 Curr := Previous_Suitable_Construct (Start);
7299 end if;
7300 end Include;
7302 -----------------------------------
7303 -- Is_OK_Preelaborable_Construct --
7304 -----------------------------------
7306 function Is_OK_Preelaborable_Construct (N : Node_Id) return Boolean is
7307 begin
7308 -- Assignment statements are acceptable as long as they were
7309 -- produced by the ABE mechanism to update elaboration flags.
7311 if Nkind (N) = N_Assignment_Statement then
7312 return Is_Elaboration_Code (N);
7314 -- Block statements are acceptable even though they directly
7315 -- violate preelaborability. The intention is not to penalize
7316 -- the early call region when a block contains only preelaborable
7317 -- constructs.
7319 -- declare
7320 -- Val : constant Integer := 1;
7321 -- begin
7322 -- pragma Assert (Val = 1);
7323 -- null;
7324 -- end;
7326 -- Note that the Advancement phase does enter blocks, and will
7327 -- detect any non-preelaborable declarations or statements within.
7329 elsif Nkind (N) = N_Block_Statement then
7330 return True;
7331 end if;
7333 -- Otherwise the construct must be preelaborable. The check must
7334 -- take the syntactic and semantic structure of the construct. DO
7335 -- NOT use Is_Preelaborable_Construct here.
7337 return not Is_Non_Preelaborable_Construct (N);
7338 end Is_OK_Preelaborable_Construct;
7340 ---------------------------
7341 -- Is_Suitable_Construct --
7342 ---------------------------
7344 function Is_Suitable_Construct (N : Node_Id) return Boolean is
7345 Context : constant Node_Id := Parent (N);
7347 begin
7348 -- An internally-generated statement sequence which contains only
7349 -- a single null statement is not a suitable construct because it
7350 -- is a byproduct of the parser. Such a null statement should be
7351 -- excluded from the early call region because it carries the
7352 -- source location of the "end" keyword, and may lead to confusing
7353 -- diagnostics.
7355 if Nkind (N) = N_Null_Statement
7356 and then not Comes_From_Source (N)
7357 and then Present (Context)
7358 and then Nkind (Context) = N_Handled_Sequence_Of_Statements
7359 then
7360 return False;
7362 -- Similarly, internally-generated objects and types may have
7363 -- out-of-order source locations that confuse diagnostics, e.g.
7364 -- source locations in the body for objects/types generated in
7365 -- the spec.
7367 elsif Nkind (N) in N_Full_Type_Declaration | N_Object_Declaration
7368 and then not Comes_From_Source (N)
7369 then
7370 return False;
7371 end if;
7373 -- Otherwise only constructs which correspond to pure Ada
7374 -- constructs are considered suitable.
7376 case Nkind (N) is
7377 when N_Call_Marker
7378 | N_Freeze_Entity
7379 | N_Freeze_Generic_Entity
7380 | N_Implicit_Label_Declaration
7381 | N_Itype_Reference
7382 | N_Pop_Constraint_Error_Label
7383 | N_Pop_Program_Error_Label
7384 | N_Pop_Storage_Error_Label
7385 | N_Push_Constraint_Error_Label
7386 | N_Push_Program_Error_Label
7387 | N_Push_Storage_Error_Label
7388 | N_SCIL_Dispatch_Table_Tag_Init
7389 | N_SCIL_Dispatching_Call
7390 | N_SCIL_Membership_Test
7391 | N_Variable_Reference_Marker
7393 return False;
7395 when others =>
7396 return True;
7397 end case;
7398 end Is_Suitable_Construct;
7400 ---------------------------------
7401 -- Previous_Suitable_Construct --
7402 ---------------------------------
7404 function Previous_Suitable_Construct (N : Node_Id) return Node_Id is
7405 P : Node_Id;
7407 begin
7408 P := Prev (N);
7410 while Present (P) and then not Is_Suitable_Construct (P) loop
7411 Prev (P);
7412 end loop;
7414 return P;
7415 end Previous_Suitable_Construct;
7417 ----------------------------------
7418 -- Transition_Body_Declarations --
7419 ----------------------------------
7421 procedure Transition_Body_Declarations
7422 (Bod : Node_Id;
7423 Curr : out Node_Id)
7425 Decls : constant List_Id := Declarations (Bod);
7427 begin
7428 -- The search must come from the declarations of the body
7430 pragma Assert
7431 (Is_Non_Empty_List (Decls)
7432 and then List_Containing (Start) = Decls);
7434 -- The search finished inspecting the declarations. The construct
7435 -- to inspect is the node which precedes the handled body, unless
7436 -- the body is a compilation unit. The transitions are:
7438 -- declarations -> upper level
7439 -- declarations -> corresponding package spec (Elab_Body)
7440 -- declarations -> terminate
7442 Transition_Unit (Bod, Curr);
7443 end Transition_Body_Declarations;
7445 -----------------------------------
7446 -- Transition_Handled_Statements --
7447 -----------------------------------
7449 procedure Transition_Handled_Statements
7450 (HSS : Node_Id;
7451 Curr : out Node_Id)
7453 Bod : constant Node_Id := Parent (HSS);
7454 Decls : constant List_Id := Declarations (Bod);
7455 Stmts : constant List_Id := Statements (HSS);
7457 begin
7458 -- The search must come from the statements of certain bodies or
7459 -- statements.
7461 pragma Assert
7462 (Nkind (Bod) in
7463 N_Block_Statement |
7464 N_Entry_Body |
7465 N_Package_Body |
7466 N_Protected_Body |
7467 N_Subprogram_Body |
7468 N_Task_Body);
7470 -- The search must come from the statements of the handled
7471 -- sequence.
7473 pragma Assert
7474 (Is_Non_Empty_List (Stmts)
7475 and then List_Containing (Start) = Stmts);
7477 -- The search finished inspecting the statements. The handled body
7478 -- has non-empty declarations. The construct to inspect is the
7479 -- last declaration. The transitions are:
7481 -- statements -> declarations
7483 if Has_Suitable_Construct (Decls) then
7484 Curr := Last (Decls);
7486 -- Otherwise the handled body lacks declarations. The construct to
7487 -- inspect is the node which precedes the handled body, unless the
7488 -- body is a compilation unit. The transitions are:
7490 -- statements -> upper level
7491 -- statements -> corresponding package spec (Elab_Body)
7492 -- statements -> terminate
7494 else
7495 Transition_Unit (Bod, Curr);
7496 end if;
7497 end Transition_Handled_Statements;
7499 ----------------------------------
7500 -- Transition_Spec_Declarations --
7501 ----------------------------------
7503 procedure Transition_Spec_Declarations
7504 (Spec : Node_Id;
7505 Curr : out Node_Id)
7507 Prv_Decls : constant List_Id := Private_Declarations (Spec);
7508 Vis_Decls : constant List_Id := Visible_Declarations (Spec);
7510 begin
7511 pragma Assert (Present (Start) and then Is_List_Member (Start));
7513 -- The search came from the private declarations and finished
7514 -- their inspection.
7516 if Has_Suitable_Construct (Prv_Decls)
7517 and then List_Containing (Start) = Prv_Decls
7518 then
7519 -- The context has non-empty visible declarations. The node to
7520 -- inspect is the last visible declaration. The transitions
7521 -- are:
7523 -- private declarations -> visible declarations
7525 if Has_Suitable_Construct (Vis_Decls) then
7526 Curr := Last (Vis_Decls);
7528 -- Otherwise the context lacks visible declarations. The
7529 -- construct to inspect is the node which precedes the context
7530 -- unless the context is a compilation unit. The transitions
7531 -- are:
7533 -- private declarations -> upper level
7534 -- private declarations -> terminate
7536 else
7537 Transition_Unit (Parent (Spec), Curr);
7538 end if;
7540 -- The search came from the visible declarations and finished
7541 -- their inspections. The construct to inspect is the node which
7542 -- precedes the context, unless the context is a compilaton unit.
7543 -- The transitions are:
7545 -- visible declarations -> upper level
7546 -- visible declarations -> terminate
7548 elsif Has_Suitable_Construct (Vis_Decls)
7549 and then List_Containing (Start) = Vis_Decls
7550 then
7551 Transition_Unit (Parent (Spec), Curr);
7553 -- At this point both declarative lists are empty, but the
7554 -- traversal still came from within the spec. This indicates
7555 -- that the invariant of the algorithm has been violated.
7557 else
7558 pragma Assert (False);
7559 raise ECR_Found;
7560 end if;
7561 end Transition_Spec_Declarations;
7563 ---------------------
7564 -- Transition_Unit --
7565 ---------------------
7567 procedure Transition_Unit
7568 (Unit : Node_Id;
7569 Curr : out Node_Id)
7571 Context : constant Node_Id := Parent (Unit);
7573 begin
7574 -- The unit is a compilation unit. This terminates the search
7575 -- because there are no more lists to inspect and there are no
7576 -- more enclosing constructs to climb up to.
7578 if Nkind (Context) = N_Compilation_Unit then
7580 -- A package body with a corresponding spec subject to pragma
7581 -- Elaborate_Body is an exception to the above. The annotation
7582 -- allows the search to continue into the package declaration.
7583 -- The transitions are:
7585 -- statements -> corresponding package spec (Elab_Body)
7586 -- declarations -> corresponding package spec (Elab_Body)
7588 if Nkind (Unit) = N_Package_Body
7589 and then (Assume_Elab_Body
7590 or else Has_Pragma_Elaborate_Body
7591 (Corresponding_Spec (Unit)))
7592 then
7593 Curr := Unit_Declaration_Node (Corresponding_Spec (Unit));
7594 Enter_Package_Declaration (Curr);
7596 -- Otherwise terminate the search. The transitions are:
7598 -- private declarations -> terminate
7599 -- visible declarations -> terminate
7600 -- statements -> terminate
7601 -- declarations -> terminate
7603 else
7604 raise ECR_Found;
7605 end if;
7607 -- The unit is a subunit. The construct to inspect is the node
7608 -- which precedes the corresponding stub. Update the early call
7609 -- region to include the unit.
7611 elsif Nkind (Context) = N_Subunit then
7612 Start := Unit;
7613 Curr := Corresponding_Stub (Context);
7615 -- Otherwise the unit is nested. The construct to inspect is the
7616 -- node which precedes the unit. Update the early call region to
7617 -- include the unit.
7619 else
7620 Include (Unit, Curr);
7621 end if;
7622 end Transition_Unit;
7624 -- Local variables
7626 Body_Id : constant Entity_Id := Unique_Defining_Entity (Body_Decl);
7627 Region : Node_Id;
7629 -- Start of processing for Find_Early_Call_Region
7631 begin
7632 -- The caller demands the start of the early call region without
7633 -- saving or retrieving it to/from internal data structures.
7635 if Skip_Memoization then
7636 Region := Find_ECR (Body_Decl);
7638 -- Default behavior
7640 else
7641 -- Check whether the early call region of the subprogram body is
7642 -- available.
7644 Region := Early_Call_Region (Body_Id);
7646 if No (Region) then
7647 Region := Find_ECR (Body_Decl);
7649 -- Associate the early call region with the subprogram body in
7650 -- case other scenarios need it.
7652 Set_Early_Call_Region (Body_Id, Region);
7653 end if;
7654 end if;
7656 -- A subprogram body must always have an early call region
7658 pragma Assert (Present (Region));
7660 return Region;
7661 end Find_Early_Call_Region;
7663 --------------------------------------------
7664 -- Initialize_Early_Call_Region_Processor --
7665 --------------------------------------------
7667 procedure Initialize_Early_Call_Region_Processor is
7668 begin
7669 Early_Call_Regions_Map := ECR_Map.Create (100);
7670 end Initialize_Early_Call_Region_Processor;
7672 ---------------------------
7673 -- Set_Early_Call_Region --
7674 ---------------------------
7676 procedure Set_Early_Call_Region (Body_Id : Entity_Id; Start : Node_Id) is
7677 pragma Assert (Present (Body_Id));
7678 pragma Assert (Present (Start));
7680 begin
7681 ECR_Map.Put (Early_Call_Regions_Map, Body_Id, Start);
7682 end Set_Early_Call_Region;
7683 end Early_Call_Region_Processor;
7685 ----------------------
7686 -- Elaborated_Units --
7687 ----------------------
7689 package body Elaborated_Units is
7691 -----------
7692 -- Types --
7693 -----------
7695 -- The following type idenfities the elaboration attributes of a unit
7697 type Elaboration_Attributes_Id is new Natural;
7699 No_Elaboration_Attributes : constant Elaboration_Attributes_Id :=
7700 Elaboration_Attributes_Id'First;
7701 First_Elaboration_Attributes : constant Elaboration_Attributes_Id :=
7702 No_Elaboration_Attributes + 1;
7704 -- The following type represents the elaboration attributes of a unit
7706 type Elaboration_Attributes_Record is record
7707 Elab_Pragma : Node_Id := Empty;
7708 -- This attribute denotes a source Elaborate or Elaborate_All pragma
7709 -- which guarantees the prior elaboration of some unit with respect
7710 -- to the main unit. The pragma may come from the following contexts:
7712 -- * The main unit
7713 -- * The spec of the main unit (if applicable)
7714 -- * Any parent spec of the main unit (if applicable)
7715 -- * Any parent subunit of the main unit (if applicable)
7717 -- The attribute remains Empty if no such pragma is available. Source
7718 -- pragmas play a role in satisfying SPARK elaboration requirements.
7720 With_Clause : Node_Id := Empty;
7721 -- This attribute denotes an internally-generated or a source with
7722 -- clause for some unit withed by the main unit. With clauses carry
7723 -- flags which represent implicit Elaborate or Elaborate_All pragmas.
7724 -- These clauses play a role in supplying elaboration dependencies to
7725 -- binde.
7726 end record;
7728 ---------------------
7729 -- Data structures --
7730 ---------------------
7732 -- The following table stores all elaboration attributes
7734 package Elaboration_Attributes is new Table.Table
7735 (Table_Index_Type => Elaboration_Attributes_Id,
7736 Table_Component_Type => Elaboration_Attributes_Record,
7737 Table_Low_Bound => First_Elaboration_Attributes,
7738 Table_Initial => 250,
7739 Table_Increment => 200,
7740 Table_Name => "Elaboration_Attributes");
7742 procedure Destroy (EA_Id : in out Elaboration_Attributes_Id);
7743 -- Destroy elaboration attributes EA_Id
7745 package UA_Map is new Dynamic_Hash_Tables
7746 (Key_Type => Entity_Id,
7747 Value_Type => Elaboration_Attributes_Id,
7748 No_Value => No_Elaboration_Attributes,
7749 Expansion_Threshold => 1.5,
7750 Expansion_Factor => 2,
7751 Compression_Threshold => 0.3,
7752 Compression_Factor => 2,
7753 "=" => "=",
7754 Destroy_Value => Destroy,
7755 Hash => Hash);
7757 -- The following map relates an elaboration attributes of a unit to the
7758 -- unit.
7760 Unit_To_Attributes_Map : UA_Map.Dynamic_Hash_Table := UA_Map.Nil;
7762 ------------------
7763 -- Constructors --
7764 ------------------
7766 function Elaboration_Attributes_Of
7767 (Unit_Id : Entity_Id) return Elaboration_Attributes_Id;
7768 pragma Inline (Elaboration_Attributes_Of);
7769 -- Obtain the elaboration attributes of unit Unit_Id
7771 -----------------------
7772 -- Local subprograms --
7773 -----------------------
7775 function Elab_Pragma (EA_Id : Elaboration_Attributes_Id) return Node_Id;
7776 pragma Inline (Elab_Pragma);
7777 -- Obtain the Elaborate[_All] pragma of elaboration attributes EA_Id
7779 procedure Ensure_Prior_Elaboration_Dynamic
7780 (N : Node_Id;
7781 Unit_Id : Entity_Id;
7782 Prag_Nam : Name_Id;
7783 In_State : Processing_In_State);
7784 pragma Inline (Ensure_Prior_Elaboration_Dynamic);
7785 -- Guarantee the elaboration of unit Unit_Id with respect to the main
7786 -- unit by suggesting the use of Elaborate[_All] with name Prag_Nam. N
7787 -- denotes the related scenario. In_State is the current state of the
7788 -- Processing phase.
7790 procedure Ensure_Prior_Elaboration_Static
7791 (N : Node_Id;
7792 Unit_Id : Entity_Id;
7793 Prag_Nam : Name_Id;
7794 In_State : Processing_In_State);
7795 pragma Inline (Ensure_Prior_Elaboration_Static);
7796 -- Guarantee the elaboration of unit Unit_Id with respect to the main
7797 -- unit by installing an implicit Elaborate[_All] pragma with name
7798 -- Prag_Nam. N denotes the related scenario. In_State is the current
7799 -- state of the Processing phase.
7801 function Present (EA_Id : Elaboration_Attributes_Id) return Boolean;
7802 pragma Inline (Present);
7803 -- Determine whether elaboration attributes UA_Id exist
7805 procedure Set_Elab_Pragma
7806 (EA_Id : Elaboration_Attributes_Id;
7807 Prag : Node_Id);
7808 pragma Inline (Set_Elab_Pragma);
7809 -- Set the Elaborate[_All] pragma of elaboration attributes EA_Id to
7810 -- Prag.
7812 procedure Set_With_Clause
7813 (EA_Id : Elaboration_Attributes_Id;
7814 Clause : Node_Id);
7815 pragma Inline (Set_With_Clause);
7816 -- Set the with clause of elaboration attributes EA_Id to Clause
7818 function With_Clause (EA_Id : Elaboration_Attributes_Id) return Node_Id;
7819 pragma Inline (With_Clause);
7820 -- Obtain the implicit or source with clause of elaboration attributes
7821 -- EA_Id.
7823 ------------------------------
7824 -- Collect_Elaborated_Units --
7825 ------------------------------
7827 procedure Collect_Elaborated_Units is
7828 procedure Add_Pragma (Prag : Node_Id);
7829 pragma Inline (Add_Pragma);
7830 -- Determine whether pragma Prag denotes a legal Elaborate[_All]
7831 -- pragma. If this is the case, add the related unit to the context.
7832 -- For pragma Elaborate_All, include recursively all units withed by
7833 -- the related unit.
7835 procedure Add_Unit
7836 (Unit_Id : Entity_Id;
7837 Prag : Node_Id;
7838 Full_Context : Boolean);
7839 pragma Inline (Add_Unit);
7840 -- Add unit Unit_Id to the elaboration context. Prag denotes the
7841 -- pragma which prompted the inclusion of the unit to the context.
7842 -- If flag Full_Context is set, examine the nonlimited clauses of
7843 -- unit Unit_Id and add each withed unit to the context.
7845 procedure Find_Elaboration_Context (Comp_Unit : Node_Id);
7846 pragma Inline (Find_Elaboration_Context);
7847 -- Examine the context items of compilation unit Comp_Unit for
7848 -- suitable elaboration-related pragmas and add all related units
7849 -- to the context.
7851 ----------------
7852 -- Add_Pragma --
7853 ----------------
7855 procedure Add_Pragma (Prag : Node_Id) is
7856 Prag_Args : constant List_Id :=
7857 Pragma_Argument_Associations (Prag);
7858 Prag_Nam : constant Name_Id := Pragma_Name (Prag);
7859 Unit_Arg : Node_Id;
7861 begin
7862 -- Nothing to do if the pragma is not related to elaboration
7864 if Prag_Nam not in Name_Elaborate | Name_Elaborate_All then
7865 return;
7867 -- Nothing to do when the pragma is illegal
7869 elsif Error_Posted (Prag) then
7870 return;
7871 end if;
7873 Unit_Arg := Get_Pragma_Arg (First (Prag_Args));
7875 -- The argument of the pragma may appear in package.package form
7877 if Nkind (Unit_Arg) = N_Selected_Component then
7878 Unit_Arg := Selector_Name (Unit_Arg);
7879 end if;
7881 Add_Unit
7882 (Unit_Id => Entity (Unit_Arg),
7883 Prag => Prag,
7884 Full_Context => Prag_Nam = Name_Elaborate_All);
7885 end Add_Pragma;
7887 --------------
7888 -- Add_Unit --
7889 --------------
7891 procedure Add_Unit
7892 (Unit_Id : Entity_Id;
7893 Prag : Node_Id;
7894 Full_Context : Boolean)
7896 Clause : Node_Id;
7897 EA_Id : Elaboration_Attributes_Id;
7898 Unit_Prag : Node_Id;
7900 begin
7901 -- Nothing to do when some previous error left a with clause or a
7902 -- pragma in a bad state.
7904 if No (Unit_Id) then
7905 return;
7906 end if;
7908 EA_Id := Elaboration_Attributes_Of (Unit_Id);
7909 Unit_Prag := Elab_Pragma (EA_Id);
7911 -- The unit is already included in the context by means of pragma
7912 -- Elaborate[_All].
7914 if Present (Unit_Prag) then
7916 -- Upgrade an existing pragma Elaborate when the unit is
7917 -- subject to Elaborate_All because the new pragma covers a
7918 -- larger set of units.
7920 if Pragma_Name (Unit_Prag) = Name_Elaborate
7921 and then Pragma_Name (Prag) = Name_Elaborate_All
7922 then
7923 Set_Elab_Pragma (EA_Id, Prag);
7925 -- Otherwise the unit retains its existing pragma and does not
7926 -- need to be included in the context again.
7928 else
7929 return;
7930 end if;
7932 -- Otherwise the current unit is not included in the context
7934 else
7935 Set_Elab_Pragma (EA_Id, Prag);
7936 end if;
7938 -- Includes all units withed by the current one when computing the
7939 -- full context.
7941 if Full_Context then
7943 -- Process all nonlimited with clauses found in the context of
7944 -- the current unit. Note that limited clauses do not impose an
7945 -- elaboration order.
7947 Clause := First (Context_Items (Compilation_Unit (Unit_Id)));
7948 while Present (Clause) loop
7949 if Nkind (Clause) = N_With_Clause
7950 and then not Error_Posted (Clause)
7951 and then not Limited_Present (Clause)
7952 then
7953 Add_Unit
7954 (Unit_Id => Entity (Name (Clause)),
7955 Prag => Prag,
7956 Full_Context => Full_Context);
7957 end if;
7959 Next (Clause);
7960 end loop;
7961 end if;
7962 end Add_Unit;
7964 ------------------------------
7965 -- Find_Elaboration_Context --
7966 ------------------------------
7968 procedure Find_Elaboration_Context (Comp_Unit : Node_Id) is
7969 pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit);
7971 Prag : Node_Id;
7973 begin
7974 -- Process all elaboration-related pragmas found in the context of
7975 -- the compilation unit.
7977 Prag := First (Context_Items (Comp_Unit));
7978 while Present (Prag) loop
7979 if Nkind (Prag) = N_Pragma then
7980 Add_Pragma (Prag);
7981 end if;
7983 Next (Prag);
7984 end loop;
7985 end Find_Elaboration_Context;
7987 -- Local variables
7989 Par_Id : Entity_Id;
7990 Unit_Id : Node_Id;
7992 -- Start of processing for Collect_Elaborated_Units
7994 begin
7995 -- Perform a traversal to examines the context of the main unit. The
7996 -- traversal performs the following jumps:
7998 -- subunit -> parent subunit
7999 -- parent subunit -> body
8000 -- body -> spec
8001 -- spec -> parent spec
8002 -- parent spec -> grandparent spec and so on
8004 -- The traversal relies on units rather than scopes because the scope
8005 -- of a subunit is some spec, while this traversal must process the
8006 -- body as well. Given that protected and task bodies can also be
8007 -- subunits, this complicates the scope approach even further.
8009 Unit_Id := Unit (Cunit (Main_Unit));
8011 -- Perform the following traversals when the main unit is a subunit
8013 -- subunit -> parent subunit
8014 -- parent subunit -> body
8016 while Present (Unit_Id) and then Nkind (Unit_Id) = N_Subunit loop
8017 Find_Elaboration_Context (Parent (Unit_Id));
8019 -- Continue the traversal by going to the unit which contains the
8020 -- corresponding stub.
8022 if Present (Corresponding_Stub (Unit_Id)) then
8023 Unit_Id :=
8024 Unit (Cunit (Get_Source_Unit (Corresponding_Stub (Unit_Id))));
8026 -- Otherwise the subunit may be erroneous or left in a bad state
8028 else
8029 exit;
8030 end if;
8031 end loop;
8033 -- Perform the following traversal now that subunits have been taken
8034 -- care of, or the main unit is a body.
8036 -- body -> spec
8038 if Present (Unit_Id)
8039 and then Nkind (Unit_Id) in N_Package_Body | N_Subprogram_Body
8040 then
8041 Find_Elaboration_Context (Parent (Unit_Id));
8043 -- Continue the traversal by going to the unit which contains the
8044 -- corresponding spec.
8046 if Present (Corresponding_Spec (Unit_Id)) then
8047 Unit_Id :=
8048 Unit (Cunit (Get_Source_Unit (Corresponding_Spec (Unit_Id))));
8049 end if;
8050 end if;
8052 -- Perform the following traversals now that the body has been taken
8053 -- care of, or the main unit is a spec.
8055 -- spec -> parent spec
8056 -- parent spec -> grandparent spec and so on
8058 if Present (Unit_Id)
8059 and then Nkind (Unit_Id) in N_Generic_Package_Declaration
8060 | N_Generic_Subprogram_Declaration
8061 | N_Package_Declaration
8062 | N_Subprogram_Declaration
8063 then
8064 Find_Elaboration_Context (Parent (Unit_Id));
8066 -- Process a potential chain of parent units which ends with the
8067 -- main unit spec. The traversal can now safely rely on the scope
8068 -- chain.
8070 Par_Id := Scope (Defining_Entity (Unit_Id));
8071 while Present (Par_Id) and then Par_Id /= Standard_Standard loop
8072 Find_Elaboration_Context (Compilation_Unit (Par_Id));
8074 Par_Id := Scope (Par_Id);
8075 end loop;
8076 end if;
8077 end Collect_Elaborated_Units;
8079 -------------
8080 -- Destroy --
8081 -------------
8083 procedure Destroy (EA_Id : in out Elaboration_Attributes_Id) is
8084 pragma Unreferenced (EA_Id);
8085 begin
8086 null;
8087 end Destroy;
8089 -----------------
8090 -- Elab_Pragma --
8091 -----------------
8093 function Elab_Pragma
8094 (EA_Id : Elaboration_Attributes_Id) return Node_Id
8096 pragma Assert (Present (EA_Id));
8097 begin
8098 return Elaboration_Attributes.Table (EA_Id).Elab_Pragma;
8099 end Elab_Pragma;
8101 -------------------------------
8102 -- Elaboration_Attributes_Of --
8103 -------------------------------
8105 function Elaboration_Attributes_Of
8106 (Unit_Id : Entity_Id) return Elaboration_Attributes_Id
8108 EA_Id : Elaboration_Attributes_Id;
8110 begin
8111 EA_Id := UA_Map.Get (Unit_To_Attributes_Map, Unit_Id);
8113 -- The unit lacks elaboration attributes. This indicates that the
8114 -- unit is encountered for the first time. Create the elaboration
8115 -- attributes for it.
8117 if not Present (EA_Id) then
8118 Elaboration_Attributes.Append
8119 ((Elab_Pragma => Empty,
8120 With_Clause => Empty));
8121 EA_Id := Elaboration_Attributes.Last;
8123 -- Associate the elaboration attributes with the unit
8125 UA_Map.Put (Unit_To_Attributes_Map, Unit_Id, EA_Id);
8126 end if;
8128 pragma Assert (Present (EA_Id));
8130 return EA_Id;
8131 end Elaboration_Attributes_Of;
8133 ------------------------------
8134 -- Ensure_Prior_Elaboration --
8135 ------------------------------
8137 procedure Ensure_Prior_Elaboration
8138 (N : Node_Id;
8139 Unit_Id : Entity_Id;
8140 Prag_Nam : Name_Id;
8141 In_State : Processing_In_State)
8143 pragma Assert (Prag_Nam in Name_Elaborate | Name_Elaborate_All);
8145 begin
8146 -- Nothing to do when the need for prior elaboration came from a
8147 -- partial finalization routine which occurs in an initialization
8148 -- context. This behavior parallels that of the old ABE mechanism.
8150 if In_State.Within_Partial_Finalization then
8151 return;
8153 -- Nothing to do when the need for prior elaboration came from a task
8154 -- body and switch -gnatd.y (disable implicit pragma Elaborate_All on
8155 -- task bodies) is in effect.
8157 elsif Debug_Flag_Dot_Y and then In_State.Within_Task_Body then
8158 return;
8160 -- Nothing to do when the unit is elaborated prior to the main unit.
8161 -- This check must also consider the following cases:
8163 -- * No check is made against the context of the main unit because
8164 -- this is specific to the elaboration model in effect and requires
8165 -- custom handling (see Ensure_xxx_Prior_Elaboration).
8167 -- * Unit_Id is subject to pragma Elaborate_Body. An implicit pragma
8168 -- Elaborate[_All] MUST be generated even though Unit_Id is always
8169 -- elaborated prior to the main unit. This conservative strategy
8170 -- ensures that other units withed by Unit_Id will not lead to an
8171 -- ABE.
8173 -- package A is package body A is
8174 -- procedure ABE; procedure ABE is ... end ABE;
8175 -- end A; end A;
8177 -- with A;
8178 -- package B is package body B is
8179 -- pragma Elaborate_Body; procedure Proc is
8180 -- begin
8181 -- procedure Proc; A.ABE;
8182 -- package B; end Proc;
8183 -- end B;
8185 -- with B;
8186 -- package C is package body C is
8187 -- ... ...
8188 -- end C; begin
8189 -- B.Proc;
8190 -- end C;
8192 -- In the example above, the elaboration of C invokes B.Proc. B is
8193 -- subject to pragma Elaborate_Body. If no pragma Elaborate[_All]
8194 -- is gnerated for B in C, then the following elaboratio order will
8195 -- lead to an ABE:
8197 -- spec of A elaborated
8198 -- spec of B elaborated
8199 -- body of B elaborated
8200 -- spec of C elaborated
8201 -- body of C elaborated <-- calls B.Proc which calls A.ABE
8202 -- body of A elaborated <-- problem
8204 -- The generation of an implicit pragma Elaborate_All (B) ensures
8205 -- that the elaboration-order mechanism will not pick the above
8206 -- order.
8208 -- An implicit Elaborate is NOT generated when the unit is subject
8209 -- to Elaborate_Body because both pragmas have the same effect.
8211 -- * Unit_Id is the main unit. An implicit pragma Elaborate[_All]
8212 -- MUST NOT be generated in this case because a unit cannot depend
8213 -- on its own elaboration. This case is therefore treated as valid
8214 -- prior elaboration.
8216 elsif Has_Prior_Elaboration
8217 (Unit_Id => Unit_Id,
8218 Same_Unit_OK => True,
8219 Elab_Body_OK => Prag_Nam = Name_Elaborate)
8220 then
8221 return;
8222 end if;
8224 -- Suggest the use of pragma Prag_Nam when the dynamic model is in
8225 -- effect.
8227 if Dynamic_Elaboration_Checks then
8228 Ensure_Prior_Elaboration_Dynamic
8229 (N => N,
8230 Unit_Id => Unit_Id,
8231 Prag_Nam => Prag_Nam,
8232 In_State => In_State);
8234 -- Install an implicit pragma Prag_Nam when the static model is in
8235 -- effect.
8237 else
8238 pragma Assert (Static_Elaboration_Checks);
8240 Ensure_Prior_Elaboration_Static
8241 (N => N,
8242 Unit_Id => Unit_Id,
8243 Prag_Nam => Prag_Nam,
8244 In_State => In_State);
8245 end if;
8246 end Ensure_Prior_Elaboration;
8248 --------------------------------------
8249 -- Ensure_Prior_Elaboration_Dynamic --
8250 --------------------------------------
8252 procedure Ensure_Prior_Elaboration_Dynamic
8253 (N : Node_Id;
8254 Unit_Id : Entity_Id;
8255 Prag_Nam : Name_Id;
8256 In_State : Processing_In_State)
8258 procedure Info_Missing_Pragma;
8259 pragma Inline (Info_Missing_Pragma);
8260 -- Output information concerning missing Elaborate or Elaborate_All
8261 -- pragma with name Prag_Nam for scenario N, which would ensure the
8262 -- prior elaboration of Unit_Id.
8264 -------------------------
8265 -- Info_Missing_Pragma --
8266 -------------------------
8268 procedure Info_Missing_Pragma is
8269 begin
8270 -- Internal units are ignored as they cause unnecessary noise
8272 if not In_Internal_Unit (Unit_Id) then
8274 -- The name of the unit subjected to the elaboration pragma is
8275 -- fully qualified to improve the clarity of the info message.
8277 Error_Msg_Name_1 := Prag_Nam;
8278 Error_Msg_Qual_Level := Nat'Last;
8280 Error_Msg_NE ("info: missing pragma % for unit &", N, Unit_Id);
8281 Error_Msg_Qual_Level := 0;
8282 end if;
8283 end Info_Missing_Pragma;
8285 -- Local variables
8287 EA_Id : constant Elaboration_Attributes_Id :=
8288 Elaboration_Attributes_Of (Unit_Id);
8289 N_Lvl : Enclosing_Level_Kind;
8290 N_Rep : Scenario_Rep_Id;
8292 -- Start of processing for Ensure_Prior_Elaboration_Dynamic
8294 begin
8295 -- Nothing to do when the unit is guaranteed prior elaboration by
8296 -- means of a source Elaborate[_All] pragma.
8298 if Present (Elab_Pragma (EA_Id)) then
8299 return;
8300 end if;
8302 -- Output extra information on a missing Elaborate[_All] pragma when
8303 -- switch -gnatel (info messages on implicit Elaborate[_All] pragmas
8304 -- is in effect.
8306 if Elab_Info_Messages
8307 and then not In_State.Suppress_Info_Messages
8308 then
8309 N_Rep := Scenario_Representation_Of (N, In_State);
8310 N_Lvl := Level (N_Rep);
8312 -- Declaration-level scenario
8314 if (Is_Suitable_Call (N) or else Is_Suitable_Instantiation (N))
8315 and then N_Lvl = Declaration_Level
8316 then
8317 null;
8319 -- Library-level scenario
8321 elsif N_Lvl in Library_Level then
8322 null;
8324 -- Instantiation library-level scenario
8326 elsif N_Lvl = Instantiation_Level then
8327 null;
8329 -- Otherwise the scenario does not appear at the proper level
8331 else
8332 return;
8333 end if;
8335 Info_Missing_Pragma;
8336 end if;
8337 end Ensure_Prior_Elaboration_Dynamic;
8339 -------------------------------------
8340 -- Ensure_Prior_Elaboration_Static --
8341 -------------------------------------
8343 procedure Ensure_Prior_Elaboration_Static
8344 (N : Node_Id;
8345 Unit_Id : Entity_Id;
8346 Prag_Nam : Name_Id;
8347 In_State : Processing_In_State)
8349 function Find_With_Clause
8350 (Items : List_Id;
8351 Withed_Id : Entity_Id) return Node_Id;
8352 pragma Inline (Find_With_Clause);
8353 -- Find a nonlimited with clause in the list of context items Items
8354 -- that withs unit Withed_Id. Return Empty if no such clause exists.
8356 procedure Info_Implicit_Pragma;
8357 pragma Inline (Info_Implicit_Pragma);
8358 -- Output information concerning an implicitly generated Elaborate
8359 -- or Elaborate_All pragma with name Prag_Nam for scenario N which
8360 -- ensures the prior elaboration of unit Unit_Id.
8362 ----------------------
8363 -- Find_With_Clause --
8364 ----------------------
8366 function Find_With_Clause
8367 (Items : List_Id;
8368 Withed_Id : Entity_Id) return Node_Id
8370 Item : Node_Id;
8372 begin
8373 -- Examine the context clauses looking for a suitable with. Note
8374 -- that limited clauses do not affect the elaboration order.
8376 Item := First (Items);
8377 while Present (Item) loop
8378 if Nkind (Item) = N_With_Clause
8379 and then not Error_Posted (Item)
8380 and then not Limited_Present (Item)
8381 and then Entity (Name (Item)) = Withed_Id
8382 then
8383 return Item;
8384 end if;
8386 Next (Item);
8387 end loop;
8389 return Empty;
8390 end Find_With_Clause;
8392 --------------------------
8393 -- Info_Implicit_Pragma --
8394 --------------------------
8396 procedure Info_Implicit_Pragma is
8397 begin
8398 -- Internal units are ignored as they cause unnecessary noise
8400 if not In_Internal_Unit (Unit_Id) then
8402 -- The name of the unit subjected to the elaboration pragma is
8403 -- fully qualified to improve the clarity of the info message.
8405 Error_Msg_Name_1 := Prag_Nam;
8406 Error_Msg_Qual_Level := Nat'Last;
8408 Error_Msg_NE
8409 ("info: implicit pragma % generated for unit &", N, Unit_Id);
8411 Error_Msg_Qual_Level := 0;
8412 Output_Active_Scenarios (N, In_State);
8413 end if;
8414 end Info_Implicit_Pragma;
8416 -- Local variables
8418 EA_Id : constant Elaboration_Attributes_Id :=
8419 Elaboration_Attributes_Of (Unit_Id);
8421 Main_Cunit : constant Node_Id := Cunit (Main_Unit);
8422 Loc : constant Source_Ptr := Sloc (Main_Cunit);
8423 Unit_Cunit : constant Node_Id := Compilation_Unit (Unit_Id);
8424 Unit_Prag : constant Node_Id := Elab_Pragma (EA_Id);
8425 Unit_With : constant Node_Id := With_Clause (EA_Id);
8427 Clause : Node_Id;
8428 Items : List_Id;
8430 -- Start of processing for Ensure_Prior_Elaboration_Static
8432 begin
8433 -- Nothing to do when the caller has suppressed the generation of
8434 -- implicit Elaborate[_All] pragmas.
8436 if In_State.Suppress_Implicit_Pragmas then
8437 return;
8439 -- Nothing to do when the unit is guaranteed prior elaboration by
8440 -- means of a source Elaborate[_All] pragma.
8442 elsif Present (Unit_Prag) then
8443 return;
8445 -- Nothing to do when the unit has an existing implicit Elaborate or
8446 -- Elaborate_All pragma installed by a previous scenario.
8448 elsif Present (Unit_With) then
8450 -- The unit is already guaranteed prior elaboration by means of an
8451 -- implicit Elaborate pragma, however the current scenario imposes
8452 -- a stronger requirement of Elaborate_All. "Upgrade" the existing
8453 -- pragma to match this new requirement.
8455 if Elaborate_Desirable (Unit_With)
8456 and then Prag_Nam = Name_Elaborate_All
8457 then
8458 Set_Elaborate_All_Desirable (Unit_With);
8459 Set_Elaborate_Desirable (Unit_With, False);
8460 end if;
8462 return;
8463 end if;
8465 -- At this point it is known that the unit has no prior elaboration
8466 -- according to pragmas and hierarchical relationships.
8468 Items := Context_Items (Main_Cunit);
8470 if No (Items) then
8471 Items := New_List;
8472 Set_Context_Items (Main_Cunit, Items);
8473 end if;
8475 -- Locate the with clause for the unit. Note that there may not be a
8476 -- clause if the unit is visible through a subunit-body, body-spec,
8477 -- or spec-parent relationship.
8479 Clause :=
8480 Find_With_Clause
8481 (Items => Items,
8482 Withed_Id => Unit_Id);
8484 -- Generate:
8485 -- with Id;
8487 -- Note that adding implicit with clauses is safe because analysis,
8488 -- resolution, and expansion have already taken place and it is not
8489 -- possible to interfere with visibility.
8491 if No (Clause) then
8492 Clause :=
8493 Make_With_Clause (Loc,
8494 Name => New_Occurrence_Of (Unit_Id, Loc));
8496 Set_Implicit_With (Clause);
8497 Set_Library_Unit (Clause, Unit_Cunit);
8499 Append_To (Items, Clause);
8500 end if;
8502 -- Mark the with clause depending on the pragma required
8504 if Prag_Nam = Name_Elaborate then
8505 Set_Elaborate_Desirable (Clause);
8506 else
8507 Set_Elaborate_All_Desirable (Clause);
8508 end if;
8510 -- The implicit Elaborate[_All] ensures the prior elaboration of
8511 -- the unit. Include the unit in the elaboration context of the
8512 -- main unit.
8514 Set_With_Clause (EA_Id, Clause);
8516 -- Output extra information on an implicit Elaborate[_All] pragma
8517 -- when switch -gnatel (info messages on implicit Elaborate[_All]
8518 -- pragmas is in effect.
8520 if Elab_Info_Messages then
8521 Info_Implicit_Pragma;
8522 end if;
8523 end Ensure_Prior_Elaboration_Static;
8525 -------------------------------
8526 -- Finalize_Elaborated_Units --
8527 -------------------------------
8529 procedure Finalize_Elaborated_Units is
8530 begin
8531 UA_Map.Destroy (Unit_To_Attributes_Map);
8532 end Finalize_Elaborated_Units;
8534 ---------------------------
8535 -- Has_Prior_Elaboration --
8536 ---------------------------
8538 function Has_Prior_Elaboration
8539 (Unit_Id : Entity_Id;
8540 Context_OK : Boolean := False;
8541 Elab_Body_OK : Boolean := False;
8542 Same_Unit_OK : Boolean := False) return Boolean
8544 EA_Id : constant Elaboration_Attributes_Id :=
8545 Elaboration_Attributes_Of (Unit_Id);
8546 Main_Id : constant Entity_Id := Main_Unit_Entity;
8547 Unit_Prag : constant Node_Id := Elab_Pragma (EA_Id);
8548 Unit_With : constant Node_Id := With_Clause (EA_Id);
8550 begin
8551 -- A preelaborated unit is always elaborated prior to the main unit
8553 if Is_Preelaborated_Unit (Unit_Id) then
8554 return True;
8556 -- An internal unit is always elaborated prior to a non-internal main
8557 -- unit.
8559 elsif In_Internal_Unit (Unit_Id)
8560 and then not In_Internal_Unit (Main_Id)
8561 then
8562 return True;
8564 -- A unit has prior elaboration if it appears within the context
8565 -- of the main unit. Consider this case only when requested by the
8566 -- caller.
8568 elsif Context_OK
8569 and then (Present (Unit_Prag) or else Present (Unit_With))
8570 then
8571 return True;
8573 -- A unit whose body is elaborated together with its spec has prior
8574 -- elaboration except with respect to itself. Consider this case only
8575 -- when requested by the caller.
8577 elsif Elab_Body_OK
8578 and then Has_Pragma_Elaborate_Body (Unit_Id)
8579 and then not Is_Same_Unit (Unit_Id, Main_Id)
8580 then
8581 return True;
8583 -- A unit has no prior elaboration with respect to itself, but does
8584 -- not require any means of ensuring its own elaboration either.
8585 -- Treat this case as valid prior elaboration only when requested by
8586 -- the caller.
8588 elsif Same_Unit_OK and then Is_Same_Unit (Unit_Id, Main_Id) then
8589 return True;
8590 end if;
8592 return False;
8593 end Has_Prior_Elaboration;
8595 ---------------------------------
8596 -- Initialize_Elaborated_Units --
8597 ---------------------------------
8599 procedure Initialize_Elaborated_Units is
8600 begin
8601 Unit_To_Attributes_Map := UA_Map.Create (250);
8602 end Initialize_Elaborated_Units;
8604 ----------------------------------
8605 -- Meet_Elaboration_Requirement --
8606 ----------------------------------
8608 procedure Meet_Elaboration_Requirement
8609 (N : Node_Id;
8610 Targ_Id : Entity_Id;
8611 Req_Nam : Name_Id;
8612 In_State : Processing_In_State)
8614 pragma Assert (Req_Nam in Name_Elaborate | Name_Elaborate_All);
8616 Main_Id : constant Entity_Id := Main_Unit_Entity;
8617 Unit_Id : constant Entity_Id := Find_Top_Unit (Targ_Id);
8619 procedure Elaboration_Requirement_Error;
8620 pragma Inline (Elaboration_Requirement_Error);
8621 -- Emit an error concerning scenario N which has failed to meet the
8622 -- elaboration requirement.
8624 function Find_Preelaboration_Pragma
8625 (Prag_Nam : Name_Id) return Node_Id;
8626 pragma Inline (Find_Preelaboration_Pragma);
8627 -- Traverse the visible declarations of unit Unit_Id and locate a
8628 -- source preelaboration-related pragma with name Prag_Nam.
8630 procedure Info_Requirement_Met (Prag : Node_Id);
8631 pragma Inline (Info_Requirement_Met);
8632 -- Output information concerning pragma Prag which meets requirement
8633 -- Req_Nam.
8635 -----------------------------------
8636 -- Elaboration_Requirement_Error --
8637 -----------------------------------
8639 procedure Elaboration_Requirement_Error is
8640 begin
8641 if Is_Suitable_Call (N) then
8642 Info_Call
8643 (Call => N,
8644 Subp_Id => Targ_Id,
8645 Info_Msg => False,
8646 In_SPARK => True);
8648 elsif Is_Suitable_Instantiation (N) then
8649 Info_Instantiation
8650 (Inst => N,
8651 Gen_Id => Targ_Id,
8652 Info_Msg => False,
8653 In_SPARK => True);
8655 elsif Is_Suitable_SPARK_Refined_State_Pragma (N) then
8656 Error_Msg_N
8657 ("read of refinement constituents during elaboration in "
8658 & "SPARK", N);
8660 elsif Is_Suitable_Variable_Reference (N) then
8661 Info_Variable_Reference
8662 (Ref => N,
8663 Var_Id => Targ_Id);
8665 -- No other scenario may impose a requirement on the context of
8666 -- the main unit.
8668 else
8669 pragma Assert (False);
8670 return;
8671 end if;
8673 Error_Msg_Name_1 := Req_Nam;
8674 Error_Msg_Node_2 := Unit_Id;
8675 Error_Msg_NE ("\\unit & requires pragma % for &", N, Main_Id);
8677 Output_Active_Scenarios (N, In_State);
8678 end Elaboration_Requirement_Error;
8680 --------------------------------
8681 -- Find_Preelaboration_Pragma --
8682 --------------------------------
8684 function Find_Preelaboration_Pragma
8685 (Prag_Nam : Name_Id) return Node_Id
8687 Spec : constant Node_Id := Parent (Unit_Id);
8688 Decl : Node_Id;
8690 begin
8691 -- A preelaboration-related pragma comes from source and appears
8692 -- at the top of the visible declarations of a package.
8694 if Nkind (Spec) = N_Package_Specification then
8695 Decl := First (Visible_Declarations (Spec));
8696 while Present (Decl) loop
8697 if Comes_From_Source (Decl) then
8698 if Nkind (Decl) = N_Pragma
8699 and then Pragma_Name (Decl) = Prag_Nam
8700 then
8701 return Decl;
8703 -- Otherwise the construct terminates the region where
8704 -- the preelaboration-related pragma may appear.
8706 else
8707 exit;
8708 end if;
8709 end if;
8711 Next (Decl);
8712 end loop;
8713 end if;
8715 return Empty;
8716 end Find_Preelaboration_Pragma;
8718 --------------------------
8719 -- Info_Requirement_Met --
8720 --------------------------
8722 procedure Info_Requirement_Met (Prag : Node_Id) is
8723 pragma Assert (Present (Prag));
8725 begin
8726 Error_Msg_Name_1 := Req_Nam;
8727 Error_Msg_Sloc := Sloc (Prag);
8728 Error_Msg_NE
8729 ("\\% requirement for unit & met by pragma #", N, Unit_Id);
8730 end Info_Requirement_Met;
8732 -- Local variables
8734 EA_Id : Elaboration_Attributes_Id;
8735 Elab_Nam : Name_Id;
8736 Req_Met : Boolean;
8737 Unit_Prag : Node_Id;
8739 -- Start of processing for Meet_Elaboration_Requirement
8741 begin
8742 -- Assume that the requirement has not been met
8744 Req_Met := False;
8746 -- If the target is within the main unit, either at the source level
8747 -- or through an instantiation, then there is no real requirement to
8748 -- meet because the main unit cannot force its own elaboration by
8749 -- means of an Elaborate[_All] pragma. Treat this case as valid
8750 -- coverage.
8752 if In_Extended_Main_Code_Unit (Targ_Id) then
8753 Req_Met := True;
8755 -- Otherwise the target resides in an external unit
8757 -- The requirement is met when the target comes from an internal unit
8758 -- because such a unit is elaborated prior to a non-internal unit.
8760 elsif In_Internal_Unit (Unit_Id)
8761 and then not In_Internal_Unit (Main_Id)
8762 then
8763 Req_Met := True;
8765 -- The requirement is met when the target comes from a preelaborated
8766 -- unit. This portion must parallel predicate Is_Preelaborated_Unit.
8768 elsif Is_Preelaborated_Unit (Unit_Id) then
8769 Req_Met := True;
8771 -- Output extra information when switch -gnatel (info messages on
8772 -- implicit Elaborate[_All] pragmas.
8774 if Elab_Info_Messages
8775 and then not In_State.Suppress_Info_Messages
8776 then
8777 if Is_Preelaborated (Unit_Id) then
8778 Elab_Nam := Name_Preelaborate;
8780 elsif Is_Pure (Unit_Id) then
8781 Elab_Nam := Name_Pure;
8783 elsif Is_Remote_Call_Interface (Unit_Id) then
8784 Elab_Nam := Name_Remote_Call_Interface;
8786 elsif Is_Remote_Types (Unit_Id) then
8787 Elab_Nam := Name_Remote_Types;
8789 else
8790 pragma Assert (Is_Shared_Passive (Unit_Id));
8791 Elab_Nam := Name_Shared_Passive;
8792 end if;
8794 Info_Requirement_Met (Find_Preelaboration_Pragma (Elab_Nam));
8795 end if;
8797 -- Determine whether the context of the main unit has a pragma strong
8798 -- enough to meet the requirement.
8800 else
8801 EA_Id := Elaboration_Attributes_Of (Unit_Id);
8802 Unit_Prag := Elab_Pragma (EA_Id);
8804 -- The pragma must be either Elaborate_All or be as strong as the
8805 -- requirement.
8807 if Present (Unit_Prag)
8808 and then Pragma_Name (Unit_Prag) in Name_Elaborate_All | Req_Nam
8809 then
8810 Req_Met := True;
8812 -- Output extra information when switch -gnatel (info messages
8813 -- on implicit Elaborate[_All] pragmas.
8815 if Elab_Info_Messages
8816 and then not In_State.Suppress_Info_Messages
8817 then
8818 Info_Requirement_Met (Unit_Prag);
8819 end if;
8820 end if;
8821 end if;
8823 -- The requirement was not met by the context of the main unit, issue
8824 -- an error.
8826 if not Req_Met then
8827 Elaboration_Requirement_Error;
8828 end if;
8829 end Meet_Elaboration_Requirement;
8831 -------------
8832 -- Present --
8833 -------------
8835 function Present (EA_Id : Elaboration_Attributes_Id) return Boolean is
8836 begin
8837 return EA_Id /= No_Elaboration_Attributes;
8838 end Present;
8840 ---------------------
8841 -- Set_Elab_Pragma --
8842 ---------------------
8844 procedure Set_Elab_Pragma
8845 (EA_Id : Elaboration_Attributes_Id;
8846 Prag : Node_Id)
8848 pragma Assert (Present (EA_Id));
8849 begin
8850 Elaboration_Attributes.Table (EA_Id).Elab_Pragma := Prag;
8851 end Set_Elab_Pragma;
8853 ---------------------
8854 -- Set_With_Clause --
8855 ---------------------
8857 procedure Set_With_Clause
8858 (EA_Id : Elaboration_Attributes_Id;
8859 Clause : Node_Id)
8861 pragma Assert (Present (EA_Id));
8862 begin
8863 Elaboration_Attributes.Table (EA_Id).With_Clause := Clause;
8864 end Set_With_Clause;
8866 -----------------
8867 -- With_Clause --
8868 -----------------
8870 function With_Clause
8871 (EA_Id : Elaboration_Attributes_Id) return Node_Id
8873 pragma Assert (Present (EA_Id));
8874 begin
8875 return Elaboration_Attributes.Table (EA_Id).With_Clause;
8876 end With_Clause;
8877 end Elaborated_Units;
8879 ------------------------------
8880 -- Elaboration_Phase_Active --
8881 ------------------------------
8883 function Elaboration_Phase_Active return Boolean is
8884 begin
8885 return Elaboration_Phase = Active;
8886 end Elaboration_Phase_Active;
8888 ------------------------------
8889 -- Error_Preelaborated_Call --
8890 ------------------------------
8892 procedure Error_Preelaborated_Call (N : Node_Id) is
8893 begin
8894 -- This is a warning in GNAT mode allowing such calls to be used in the
8895 -- predefined library units with appropriate care.
8897 Error_Msg_Warn := GNAT_Mode;
8899 -- Ada 2022 (AI12-0175): Calls to certain functions that are essentially
8900 -- unchecked conversions are preelaborable.
8902 if Ada_Version >= Ada_2022 then
8903 Error_Msg_N
8904 ("<<non-preelaborable call not allowed in preelaborated unit", N);
8905 else
8906 Error_Msg_N
8907 ("<<non-static call not allowed in preelaborated unit", N);
8908 end if;
8909 end Error_Preelaborated_Call;
8911 ----------------------------------
8912 -- Finalize_All_Data_Structures --
8913 ----------------------------------
8915 procedure Finalize_All_Data_Structures is
8916 begin
8917 Finalize_Body_Processor;
8918 Finalize_Early_Call_Region_Processor;
8919 Finalize_Elaborated_Units;
8920 Finalize_Internal_Representation;
8921 Finalize_Invocation_Graph;
8922 Finalize_Scenario_Storage;
8923 end Finalize_All_Data_Structures;
8925 -----------------------------
8926 -- Find_Enclosing_Instance --
8927 -----------------------------
8929 function Find_Enclosing_Instance (N : Node_Id) return Node_Id is
8930 Par : Node_Id;
8932 begin
8933 -- Climb the parent chain looking for an enclosing instance spec or body
8935 Par := N;
8936 while Present (Par) loop
8937 if Nkind (Par) in N_Package_Body
8938 | N_Package_Declaration
8939 | N_Subprogram_Body
8940 | N_Subprogram_Declaration
8941 and then Is_Generic_Instance (Unique_Defining_Entity (Par))
8942 then
8943 return Par;
8944 end if;
8946 Par := Parent (Par);
8947 end loop;
8949 return Empty;
8950 end Find_Enclosing_Instance;
8952 --------------------------
8953 -- Find_Enclosing_Level --
8954 --------------------------
8956 function Find_Enclosing_Level (N : Node_Id) return Enclosing_Level_Kind is
8957 function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind;
8958 pragma Inline (Level_Of);
8959 -- Obtain the corresponding level of unit Unit
8961 --------------
8962 -- Level_Of --
8963 --------------
8965 function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind is
8966 Spec_Id : Entity_Id;
8968 begin
8969 if Nkind (Unit) in N_Generic_Instantiation then
8970 return Instantiation_Level;
8972 elsif Nkind (Unit) = N_Generic_Package_Declaration then
8973 return Generic_Spec_Level;
8975 elsif Nkind (Unit) = N_Package_Declaration then
8976 return Library_Spec_Level;
8978 elsif Nkind (Unit) = N_Package_Body then
8979 Spec_Id := Corresponding_Spec (Unit);
8981 -- The body belongs to a generic package
8983 if Present (Spec_Id)
8984 and then Ekind (Spec_Id) = E_Generic_Package
8985 then
8986 return Generic_Body_Level;
8988 -- Otherwise the body belongs to a non-generic package. This also
8989 -- treats an illegal package body without a corresponding spec as
8990 -- a non-generic package body.
8992 else
8993 return Library_Body_Level;
8994 end if;
8995 end if;
8997 return No_Level;
8998 end Level_Of;
9000 -- Local variables
9002 Context : Node_Id;
9003 Curr : Node_Id;
9004 Prev : Node_Id;
9006 -- Start of processing for Find_Enclosing_Level
9008 begin
9009 -- Call markers and instantiations which appear at the declaration level
9010 -- but are later relocated in a different context retain their original
9011 -- declaration level.
9013 if Nkind (N) in N_Call_Marker
9014 | N_Function_Instantiation
9015 | N_Package_Instantiation
9016 | N_Procedure_Instantiation
9017 and then Is_Declaration_Level_Node (N)
9018 then
9019 return Declaration_Level;
9020 end if;
9022 -- Climb the parent chain looking at the enclosing levels
9024 Prev := N;
9025 Curr := Parent (Prev);
9026 while Present (Curr) loop
9028 -- A traversal from a subunit continues via the corresponding stub
9030 if Nkind (Curr) = N_Subunit then
9031 Curr := Corresponding_Stub (Curr);
9033 -- The current construct is a package. Packages are ignored because
9034 -- they are always elaborated when the enclosing context is invoked
9035 -- or elaborated.
9037 elsif Nkind (Curr) in N_Package_Body | N_Package_Declaration then
9038 null;
9040 -- The current construct is a block statement
9042 elsif Nkind (Curr) = N_Block_Statement then
9044 -- Ignore internally generated blocks created by the expander for
9045 -- various purposes such as abort defer/undefer.
9047 if not Comes_From_Source (Curr) then
9048 null;
9050 -- If the traversal came from the handled sequence of statements,
9051 -- then the node appears at the level of the enclosing construct.
9052 -- This is a more reliable test because transients scopes within
9053 -- the declarative region of the encapsulator are hard to detect.
9055 elsif Nkind (Prev) = N_Handled_Sequence_Of_Statements
9056 and then Handled_Statement_Sequence (Curr) = Prev
9057 then
9058 return Find_Enclosing_Level (Parent (Curr));
9060 -- Otherwise the traversal came from the declarations, the node is
9061 -- at the declaration level.
9063 else
9064 return Declaration_Level;
9065 end if;
9067 -- The current construct is a declaration-level encapsulator
9069 elsif Nkind (Curr) in
9070 N_Entry_Body | N_Subprogram_Body | N_Task_Body
9071 then
9072 -- If the traversal came from the handled sequence of statements,
9073 -- then the node cannot possibly appear at any level. This is
9074 -- a more reliable test because transients scopes within the
9075 -- declarative region of the encapsulator are hard to detect.
9077 if Nkind (Prev) = N_Handled_Sequence_Of_Statements
9078 and then Handled_Statement_Sequence (Curr) = Prev
9079 then
9080 return No_Level;
9082 -- Otherwise the traversal came from the declarations, the node is
9083 -- at the declaration level.
9085 else
9086 return Declaration_Level;
9087 end if;
9089 -- The current construct is a non-library-level encapsulator which
9090 -- indicates that the node cannot possibly appear at any level. Note
9091 -- that the check must come after the declaration-level check because
9092 -- both predicates share certain nodes.
9094 elsif Is_Non_Library_Level_Encapsulator (Curr) then
9095 Context := Parent (Curr);
9097 -- The sole exception is when the encapsulator is the compilation
9098 -- utit itself because the compilation unit node requires special
9099 -- processing (see below).
9101 if Present (Context)
9102 and then Nkind (Context) = N_Compilation_Unit
9103 then
9104 null;
9106 -- Otherwise the node is not at any level
9108 else
9109 return No_Level;
9110 end if;
9112 -- The current construct is a compilation unit. The node appears at
9113 -- the [generic] library level when the unit is a [generic] package.
9115 elsif Nkind (Curr) = N_Compilation_Unit then
9116 return Level_Of (Unit (Curr));
9117 end if;
9119 Prev := Curr;
9120 Curr := Parent (Prev);
9121 end loop;
9123 return No_Level;
9124 end Find_Enclosing_Level;
9126 -------------------
9127 -- Find_Top_Unit --
9128 -------------------
9130 function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id is
9131 begin
9132 return Find_Unit_Entity (Unit (Cunit (Get_Top_Level_Code_Unit (N))));
9133 end Find_Top_Unit;
9135 ----------------------
9136 -- Find_Unit_Entity --
9137 ----------------------
9139 function Find_Unit_Entity (N : Node_Id) return Entity_Id is
9140 Context : constant Node_Id := Parent (N);
9141 Orig_N : constant Node_Id := Original_Node (N);
9143 begin
9144 -- The unit denotes a package body of an instantiation which acts as
9145 -- a compilation unit. The proper entity is that of the package spec.
9147 if Nkind (N) = N_Package_Body
9148 and then Nkind (Orig_N) = N_Package_Instantiation
9149 and then Nkind (Context) = N_Compilation_Unit
9150 then
9151 return Corresponding_Spec (N);
9153 -- The unit denotes an anonymous package created to wrap a subprogram
9154 -- instantiation which acts as a compilation unit. The proper entity is
9155 -- that of the "related instance".
9157 elsif Nkind (N) = N_Package_Declaration
9158 and then Nkind (Orig_N) in
9159 N_Function_Instantiation | N_Procedure_Instantiation
9160 and then Nkind (Context) = N_Compilation_Unit
9161 then
9162 return Related_Instance (Defining_Entity (N));
9164 -- The unit denotes a concurrent body acting as a subunit. Such bodies
9165 -- are generally rewritten into null statements. The proper entity is
9166 -- that of the "original node".
9168 elsif Nkind (N) = N_Subunit
9169 and then Nkind (Proper_Body (N)) = N_Null_Statement
9170 and then Nkind (Original_Node (Proper_Body (N))) in
9171 N_Protected_Body | N_Task_Body
9172 then
9173 return Defining_Entity (Original_Node (Proper_Body (N)));
9175 -- Otherwise the proper entity is the defining entity
9177 else
9178 return Defining_Entity (N);
9179 end if;
9180 end Find_Unit_Entity;
9182 -----------------------
9183 -- First_Formal_Type --
9184 -----------------------
9186 function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id is
9187 Formal_Id : constant Entity_Id := First_Formal (Subp_Id);
9188 Typ : Entity_Id;
9190 begin
9191 if Present (Formal_Id) then
9192 Typ := Etype (Formal_Id);
9194 -- Handle various combinations of concurrent and private types
9196 loop
9197 if Ekind (Typ) in E_Protected_Type | E_Task_Type
9198 and then Present (Anonymous_Object (Typ))
9199 then
9200 Typ := Anonymous_Object (Typ);
9202 elsif Is_Concurrent_Record_Type (Typ) then
9203 Typ := Corresponding_Concurrent_Type (Typ);
9205 elsif Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
9206 Typ := Full_View (Typ);
9208 else
9209 exit;
9210 end if;
9211 end loop;
9213 return Typ;
9214 end if;
9216 return Empty;
9217 end First_Formal_Type;
9219 ------------------------------
9220 -- Guaranteed_ABE_Processor --
9221 ------------------------------
9223 package body Guaranteed_ABE_Processor is
9224 function Is_Guaranteed_ABE
9225 (N : Node_Id;
9226 Target_Decl : Node_Id;
9227 Target_Body : Node_Id) return Boolean;
9228 pragma Inline (Is_Guaranteed_ABE);
9229 -- Determine whether scenario N with a target described by its initial
9230 -- declaration Target_Decl and body Target_Decl results in a guaranteed
9231 -- ABE.
9233 procedure Process_Guaranteed_ABE_Activation
9234 (Call : Node_Id;
9235 Call_Rep : Scenario_Rep_Id;
9236 Obj_Id : Entity_Id;
9237 Obj_Rep : Target_Rep_Id;
9238 Task_Typ : Entity_Id;
9239 Task_Rep : Target_Rep_Id;
9240 In_State : Processing_In_State);
9241 pragma Inline (Process_Guaranteed_ABE_Activation);
9242 -- Perform common guaranteed ABE checks and diagnostics for activation
9243 -- call Call which activates object Obj_Id of task type Task_Typ. Formal
9244 -- Call_Rep denotes the representation of the call. Obj_Rep denotes the
9245 -- representation of the object. Task_Rep denotes the representation of
9246 -- the task type. In_State is the current state of the Processing phase.
9248 procedure Process_Guaranteed_ABE_Call
9249 (Call : Node_Id;
9250 Call_Rep : Scenario_Rep_Id;
9251 In_State : Processing_In_State);
9252 pragma Inline (Process_Guaranteed_ABE_Call);
9253 -- Perform common guaranteed ABE checks and diagnostics for call Call
9254 -- with representation Call_Rep. In_State denotes the current state of
9255 -- the Processing phase.
9257 procedure Process_Guaranteed_ABE_Instantiation
9258 (Inst : Node_Id;
9259 Inst_Rep : Scenario_Rep_Id;
9260 In_State : Processing_In_State);
9261 pragma Inline (Process_Guaranteed_ABE_Instantiation);
9262 -- Perform common guaranteed ABE checks and diagnostics for instance
9263 -- Inst with representation Inst_Rep. In_State is the current state of
9264 -- the Processing phase.
9266 -----------------------
9267 -- Is_Guaranteed_ABE --
9268 -----------------------
9270 function Is_Guaranteed_ABE
9271 (N : Node_Id;
9272 Target_Decl : Node_Id;
9273 Target_Body : Node_Id) return Boolean
9275 Spec : Node_Id;
9276 begin
9277 -- Avoid cascaded errors if there were previous serious infractions.
9278 -- As a result the scenario will not be treated as a guaranteed ABE.
9279 -- This behavior parallels that of the old ABE mechanism.
9281 if Serious_Errors_Detected > 0 then
9282 return False;
9284 -- The scenario and the target appear in the same context ignoring
9285 -- enclosing library levels.
9287 elsif In_Same_Context (N, Target_Decl) then
9289 -- The target body has already been encountered. The scenario
9290 -- results in a guaranteed ABE if it appears prior to the body.
9292 if Present (Target_Body) then
9293 return Earlier_In_Extended_Unit (N, Target_Body);
9295 -- Otherwise the body has not been encountered yet. The scenario
9296 -- is a guaranteed ABE since the body will appear later, unless
9297 -- this is a null specification, which can occur if expansion is
9298 -- disabled (e.g. -gnatc or GNATprove mode). It is assumed that
9299 -- the caller has already ensured that the scenario is ABE-safe
9300 -- because optional bodies are not considered here.
9302 else
9303 Spec := Specification (Target_Decl);
9305 if Nkind (Spec) /= N_Procedure_Specification
9306 or else not Null_Present (Spec)
9307 then
9308 return True;
9309 end if;
9310 end if;
9311 end if;
9313 return False;
9314 end Is_Guaranteed_ABE;
9316 ----------------------------
9317 -- Process_Guaranteed_ABE --
9318 ----------------------------
9320 procedure Process_Guaranteed_ABE
9321 (N : Node_Id;
9322 In_State : Processing_In_State)
9324 Scen : constant Node_Id := Scenario (N);
9325 Scen_Rep : Scenario_Rep_Id;
9327 begin
9328 -- Add the current scenario to the stack of active scenarios
9330 Push_Active_Scenario (Scen);
9332 -- Only calls, instantiations, and task activations may result in a
9333 -- guaranteed ABE.
9335 -- Call or task activation
9337 if Is_Suitable_Call (Scen) then
9338 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
9340 if Kind (Scen_Rep) = Call_Scenario then
9341 Process_Guaranteed_ABE_Call
9342 (Call => Scen,
9343 Call_Rep => Scen_Rep,
9344 In_State => In_State);
9346 else
9347 pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);
9349 Process_Activation
9350 (Call => Scen,
9351 Call_Rep => Scenario_Representation_Of (Scen, In_State),
9352 Processor => Process_Guaranteed_ABE_Activation'Access,
9353 In_State => In_State);
9354 end if;
9356 -- Instantiation
9358 elsif Is_Suitable_Instantiation (Scen) then
9359 Process_Guaranteed_ABE_Instantiation
9360 (Inst => Scen,
9361 Inst_Rep => Scenario_Representation_Of (Scen, In_State),
9362 In_State => In_State);
9363 end if;
9365 -- Remove the current scenario from the stack of active scenarios
9366 -- once all ABE diagnostics and checks have been performed.
9368 Pop_Active_Scenario (Scen);
9369 end Process_Guaranteed_ABE;
9371 ---------------------------------------
9372 -- Process_Guaranteed_ABE_Activation --
9373 ---------------------------------------
9375 procedure Process_Guaranteed_ABE_Activation
9376 (Call : Node_Id;
9377 Call_Rep : Scenario_Rep_Id;
9378 Obj_Id : Entity_Id;
9379 Obj_Rep : Target_Rep_Id;
9380 Task_Typ : Entity_Id;
9381 Task_Rep : Target_Rep_Id;
9382 In_State : Processing_In_State)
9384 Spec_Decl : constant Node_Id := Spec_Declaration (Task_Rep);
9386 Check_OK : constant Boolean :=
9387 not In_State.Suppress_Checks
9388 and then Ghost_Mode_Of (Obj_Rep) /= Is_Ignored
9389 and then Ghost_Mode_Of (Task_Rep) /= Is_Ignored
9390 and then Elaboration_Checks_OK (Obj_Rep)
9391 and then Elaboration_Checks_OK (Task_Rep);
9392 -- A run-time ABE check may be installed only when the object and the
9393 -- task type have active elaboration checks, and both are not ignored
9394 -- Ghost constructs.
9396 begin
9397 -- Nothing to do when the root scenario appears at the declaration
9398 -- level and the task is in the same unit, but outside this context.
9400 -- task type Task_Typ; -- task declaration
9402 -- procedure Proc is
9403 -- function A ... is
9404 -- begin
9405 -- if Some_Condition then
9406 -- declare
9407 -- T : Task_Typ;
9408 -- begin
9409 -- <activation call> -- activation site
9410 -- end;
9411 -- ...
9412 -- end A;
9414 -- X : ... := A; -- root scenario
9415 -- ...
9417 -- task body Task_Typ is
9418 -- ...
9419 -- end Task_Typ;
9421 -- In the example above, the context of X is the declarative list
9422 -- of Proc. The "elaboration" of X may reach the activation of T
9423 -- whose body is defined outside of X's context. The task body is
9424 -- relevant only when Proc is invoked, but this happens only in
9425 -- "normal" elaboration, therefore the task body must not be
9426 -- considered if this is not the case.
9428 if Is_Up_Level_Target
9429 (Targ_Decl => Spec_Decl,
9430 In_State => In_State)
9431 then
9432 return;
9434 -- Nothing to do when the activation is ABE-safe
9436 -- generic
9437 -- package Gen is
9438 -- task type Task_Typ;
9439 -- end Gen;
9441 -- package body Gen is
9442 -- task body Task_Typ is
9443 -- begin
9444 -- ...
9445 -- end Task_Typ;
9446 -- end Gen;
9448 -- with Gen;
9449 -- procedure Main is
9450 -- package Nested is
9451 -- package Inst is new Gen;
9452 -- T : Inst.Task_Typ;
9453 -- end Nested; -- safe activation
9454 -- ...
9456 elsif Is_Safe_Activation (Call, Task_Rep) then
9457 return;
9459 -- An activation call leads to a guaranteed ABE when the activation
9460 -- call and the task appear within the same context ignoring library
9461 -- levels, and the body of the task has not been seen yet or appears
9462 -- after the activation call.
9464 -- procedure Guaranteed_ABE is
9465 -- task type Task_Typ;
9467 -- package Nested is
9468 -- T : Task_Typ;
9469 -- <activation call> -- guaranteed ABE
9470 -- end Nested;
9472 -- task body Task_Typ is
9473 -- ...
9474 -- end Task_Typ;
9475 -- ...
9477 elsif Is_Guaranteed_ABE
9478 (N => Call,
9479 Target_Decl => Spec_Decl,
9480 Target_Body => Body_Declaration (Task_Rep))
9481 then
9482 if Elaboration_Warnings_OK (Call_Rep) then
9483 Error_Msg_Sloc := Sloc (Call);
9484 Error_Msg_N
9485 ("??task & will be activated # before elaboration of its "
9486 & "body", Obj_Id);
9487 Error_Msg_N
9488 ("\Program_Error will be raised at run time", Obj_Id);
9489 end if;
9491 -- Mark the activation call as a guaranteed ABE
9493 Set_Is_Known_Guaranteed_ABE (Call);
9495 -- Install a run-time ABE failue because this activation call will
9496 -- always result in an ABE.
9498 if Check_OK then
9499 Install_Scenario_ABE_Failure
9500 (N => Call,
9501 Targ_Id => Task_Typ,
9502 Targ_Rep => Task_Rep,
9503 Disable => Obj_Rep);
9504 end if;
9505 end if;
9506 end Process_Guaranteed_ABE_Activation;
9508 ---------------------------------
9509 -- Process_Guaranteed_ABE_Call --
9510 ---------------------------------
9512 procedure Process_Guaranteed_ABE_Call
9513 (Call : Node_Id;
9514 Call_Rep : Scenario_Rep_Id;
9515 In_State : Processing_In_State)
9517 Subp_Id : constant Entity_Id := Target (Call_Rep);
9518 Subp_Rep : constant Target_Rep_Id :=
9519 Target_Representation_Of (Subp_Id, In_State);
9520 Spec_Decl : constant Node_Id := Spec_Declaration (Subp_Rep);
9522 Check_OK : constant Boolean :=
9523 not In_State.Suppress_Checks
9524 and then Ghost_Mode_Of (Call_Rep) /= Is_Ignored
9525 and then Ghost_Mode_Of (Subp_Rep) /= Is_Ignored
9526 and then Elaboration_Checks_OK (Call_Rep)
9527 and then Elaboration_Checks_OK (Subp_Rep);
9528 -- A run-time ABE check may be installed only when both the call
9529 -- and the target have active elaboration checks, and both are not
9530 -- ignored Ghost constructs.
9532 begin
9533 -- Nothing to do when the root scenario appears at the declaration
9534 -- level and the target is in the same unit but outside this context.
9536 -- function B ...; -- target declaration
9538 -- procedure Proc is
9539 -- function A ... is
9540 -- begin
9541 -- if Some_Condition then
9542 -- return B; -- call site
9543 -- ...
9544 -- end A;
9546 -- X : ... := A; -- root scenario
9547 -- ...
9549 -- function B ... is
9550 -- ...
9551 -- end B;
9553 -- In the example above, the context of X is the declarative region
9554 -- of Proc. The "elaboration" of X may eventually reach B which is
9555 -- defined outside of X's context. B is relevant only when Proc is
9556 -- invoked, but this happens only by means of "normal" elaboration,
9557 -- therefore B must not be considered if this is not the case.
9559 if Is_Up_Level_Target
9560 (Targ_Decl => Spec_Decl,
9561 In_State => In_State)
9562 then
9563 return;
9565 -- Nothing to do when the call is ABE-safe
9567 -- generic
9568 -- function Gen ...;
9570 -- function Gen ... is
9571 -- begin
9572 -- ...
9573 -- end Gen;
9575 -- with Gen;
9576 -- procedure Main is
9577 -- function Inst is new Gen;
9578 -- X : ... := Inst; -- safe call
9579 -- ...
9581 elsif Is_Safe_Call (Call, Subp_Id, Subp_Rep) then
9582 return;
9584 -- A call leads to a guaranteed ABE when the call and the target
9585 -- appear within the same context ignoring library levels, and the
9586 -- body of the target has not been seen yet or appears after the
9587 -- call.
9589 -- procedure Guaranteed_ABE is
9590 -- function Func ...;
9592 -- package Nested is
9593 -- Obj : ... := Func; -- guaranteed ABE
9594 -- end Nested;
9596 -- function Func ... is
9597 -- ...
9598 -- end Func;
9599 -- ...
9601 elsif Is_Guaranteed_ABE
9602 (N => Call,
9603 Target_Decl => Spec_Decl,
9604 Target_Body => Body_Declaration (Subp_Rep))
9605 then
9606 if Elaboration_Warnings_OK (Call_Rep) then
9607 Error_Msg_NE
9608 ("??cannot call & before body seen", Call, Subp_Id);
9609 Error_Msg_N ("\Program_Error will be raised at run time", Call);
9610 end if;
9612 -- Mark the call as a guaranteed ABE
9614 Set_Is_Known_Guaranteed_ABE (Call);
9616 -- Install a run-time ABE failure because the call will always
9617 -- result in an ABE.
9619 if Check_OK then
9620 Install_Scenario_ABE_Failure
9621 (N => Call,
9622 Targ_Id => Subp_Id,
9623 Targ_Rep => Subp_Rep,
9624 Disable => Call_Rep);
9625 end if;
9626 end if;
9627 end Process_Guaranteed_ABE_Call;
9629 ------------------------------------------
9630 -- Process_Guaranteed_ABE_Instantiation --
9631 ------------------------------------------
9633 procedure Process_Guaranteed_ABE_Instantiation
9634 (Inst : Node_Id;
9635 Inst_Rep : Scenario_Rep_Id;
9636 In_State : Processing_In_State)
9638 Gen_Id : constant Entity_Id := Target (Inst_Rep);
9639 Gen_Rep : constant Target_Rep_Id :=
9640 Target_Representation_Of (Gen_Id, In_State);
9641 Spec_Decl : constant Node_Id := Spec_Declaration (Gen_Rep);
9643 Check_OK : constant Boolean :=
9644 not In_State.Suppress_Checks
9645 and then Ghost_Mode_Of (Inst_Rep) /= Is_Ignored
9646 and then Ghost_Mode_Of (Gen_Rep) /= Is_Ignored
9647 and then Elaboration_Checks_OK (Inst_Rep)
9648 and then Elaboration_Checks_OK (Gen_Rep);
9649 -- A run-time ABE check may be installed only when both the instance
9650 -- and the generic have active elaboration checks and both are not
9651 -- ignored Ghost constructs.
9653 begin
9654 -- Nothing to do when the root scenario appears at the declaration
9655 -- level and the generic is in the same unit, but outside this
9656 -- context.
9658 -- generic
9659 -- procedure Gen is ...; -- generic declaration
9661 -- procedure Proc is
9662 -- function A ... is
9663 -- begin
9664 -- if Some_Condition then
9665 -- declare
9666 -- procedure I is new Gen; -- instantiation site
9667 -- ...
9668 -- ...
9669 -- end A;
9671 -- X : ... := A; -- root scenario
9672 -- ...
9674 -- procedure Gen is
9675 -- ...
9676 -- end Gen;
9678 -- In the example above, the context of X is the declarative region
9679 -- of Proc. The "elaboration" of X may eventually reach Gen which
9680 -- appears outside of X's context. Gen is relevant only when Proc is
9681 -- invoked, but this happens only by means of "normal" elaboration,
9682 -- therefore Gen must not be considered if this is not the case.
9684 if Is_Up_Level_Target
9685 (Targ_Decl => Spec_Decl,
9686 In_State => In_State)
9687 then
9688 return;
9690 -- Nothing to do when the instantiation is ABE-safe
9692 -- generic
9693 -- package Gen is
9694 -- ...
9695 -- end Gen;
9697 -- package body Gen is
9698 -- ...
9699 -- end Gen;
9701 -- with Gen;
9702 -- procedure Main is
9703 -- package Inst is new Gen (ABE); -- safe instantiation
9704 -- ...
9706 elsif Is_Safe_Instantiation (Inst, Gen_Id, Gen_Rep) then
9707 return;
9709 -- An instantiation leads to a guaranteed ABE when the instantiation
9710 -- and the generic appear within the same context ignoring library
9711 -- levels, and the body of the generic has not been seen yet or
9712 -- appears after the instantiation.
9714 -- procedure Guaranteed_ABE is
9715 -- generic
9716 -- procedure Gen;
9718 -- package Nested is
9719 -- procedure Inst is new Gen; -- guaranteed ABE
9720 -- end Nested;
9722 -- procedure Gen is
9723 -- ...
9724 -- end Gen;
9725 -- ...
9727 elsif Is_Guaranteed_ABE
9728 (N => Inst,
9729 Target_Decl => Spec_Decl,
9730 Target_Body => Body_Declaration (Gen_Rep))
9731 then
9732 if Elaboration_Warnings_OK (Inst_Rep) then
9733 Error_Msg_NE
9734 ("??cannot instantiate & before body seen", Inst, Gen_Id);
9735 Error_Msg_N ("\Program_Error will be raised at run time", Inst);
9736 end if;
9738 -- Mark the instantiation as a guarantee ABE. This automatically
9739 -- suppresses the instantiation of the generic body.
9741 Set_Is_Known_Guaranteed_ABE (Inst);
9743 -- Install a run-time ABE failure because the instantiation will
9744 -- always result in an ABE.
9746 if Check_OK then
9747 Install_Scenario_ABE_Failure
9748 (N => Inst,
9749 Targ_Id => Gen_Id,
9750 Targ_Rep => Gen_Rep,
9751 Disable => Inst_Rep);
9752 end if;
9753 end if;
9754 end Process_Guaranteed_ABE_Instantiation;
9755 end Guaranteed_ABE_Processor;
9757 --------------
9758 -- Has_Body --
9759 --------------
9761 function Has_Body (Pack_Decl : Node_Id) return Boolean is
9762 function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id;
9763 pragma Inline (Find_Corresponding_Body);
9764 -- Try to locate the corresponding body of spec Spec_Id. If no body is
9765 -- found, return Empty.
9767 function Find_Body
9768 (Spec_Id : Entity_Id;
9769 From : Node_Id) return Node_Id;
9770 pragma Inline (Find_Body);
9771 -- Try to locate the corresponding body of spec Spec_Id in the node list
9772 -- which follows arbitrary node From. If no body is found, return Empty.
9774 function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id;
9775 pragma Inline (Load_Package_Body);
9776 -- Attempt to load the body of unit Unit_Nam. If the load failed, return
9777 -- Empty. If the compilation will not generate code, return Empty.
9779 -----------------------------
9780 -- Find_Corresponding_Body --
9781 -----------------------------
9783 function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id is
9784 Context : constant Entity_Id := Scope (Spec_Id);
9785 Spec_Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
9786 Body_Decl : Node_Id;
9787 Body_Id : Entity_Id;
9789 begin
9790 if Is_Compilation_Unit (Spec_Id) then
9791 Body_Id := Corresponding_Body (Spec_Decl);
9793 if Present (Body_Id) then
9794 return Unit_Declaration_Node (Body_Id);
9796 -- The package is at the library and requires a body. Load the
9797 -- corresponding body because the optional body may be declared
9798 -- there.
9800 elsif Unit_Requires_Body (Spec_Id) then
9801 return
9802 Load_Package_Body
9803 (Get_Body_Name (Unit_Name (Get_Source_Unit (Spec_Decl))));
9805 -- Otherwise there is no optional body
9807 else
9808 return Empty;
9809 end if;
9811 -- The immediate context is a package. The optional body may be
9812 -- within the body of that package.
9814 -- procedure Proc is
9815 -- package Nested_1 is
9816 -- package Nested_2 is
9817 -- generic
9818 -- package Pack is
9819 -- end Pack;
9820 -- end Nested_2;
9821 -- end Nested_1;
9823 -- package body Nested_1 is
9824 -- package body Nested_2 is separate;
9825 -- end Nested_1;
9827 -- separate (Proc.Nested_1.Nested_2)
9828 -- package body Nested_2 is
9829 -- package body Pack is -- optional body
9830 -- ...
9831 -- end Pack;
9832 -- end Nested_2;
9834 elsif Is_Package_Or_Generic_Package (Context) then
9835 Body_Decl := Find_Corresponding_Body (Context);
9837 -- The optional body is within the body of the enclosing package
9839 if Present (Body_Decl) then
9840 return
9841 Find_Body
9842 (Spec_Id => Spec_Id,
9843 From => First (Declarations (Body_Decl)));
9845 -- Otherwise the enclosing package does not have a body. This may
9846 -- be the result of an error or a genuine lack of a body.
9848 else
9849 return Empty;
9850 end if;
9852 -- Otherwise the immediate context is a body. The optional body may
9853 -- be within the same list as the spec.
9855 -- procedure Proc is
9856 -- generic
9857 -- package Pack is
9858 -- end Pack;
9860 -- package body Pack is -- optional body
9861 -- ...
9862 -- end Pack;
9864 else
9865 return
9866 Find_Body
9867 (Spec_Id => Spec_Id,
9868 From => Next (Spec_Decl));
9869 end if;
9870 end Find_Corresponding_Body;
9872 ---------------
9873 -- Find_Body --
9874 ---------------
9876 function Find_Body
9877 (Spec_Id : Entity_Id;
9878 From : Node_Id) return Node_Id
9880 Spec_Nam : constant Name_Id := Chars (Spec_Id);
9881 Item : Node_Id;
9882 Lib_Unit : Node_Id;
9884 begin
9885 Item := From;
9886 while Present (Item) loop
9888 -- The current item denotes the optional body
9890 if Nkind (Item) = N_Package_Body
9891 and then Chars (Defining_Entity (Item)) = Spec_Nam
9892 then
9893 return Item;
9895 -- The current item denotes a stub, the optional body may be in
9896 -- the subunit.
9898 elsif Nkind (Item) = N_Package_Body_Stub
9899 and then Chars (Defining_Entity (Item)) = Spec_Nam
9900 then
9901 Lib_Unit := Library_Unit (Item);
9903 -- The corresponding subunit was previously loaded
9905 if Present (Lib_Unit) then
9906 return Lib_Unit;
9908 -- Otherwise attempt to load the corresponding subunit
9910 else
9911 return Load_Package_Body (Get_Unit_Name (Item));
9912 end if;
9913 end if;
9915 Next (Item);
9916 end loop;
9918 return Empty;
9919 end Find_Body;
9921 -----------------------
9922 -- Load_Package_Body --
9923 -----------------------
9925 function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id is
9926 Body_Decl : Node_Id;
9927 Unit_Num : Unit_Number_Type;
9929 begin
9930 -- The load is performed only when the compilation will generate code
9932 if Operating_Mode = Generate_Code then
9933 Unit_Num :=
9934 Load_Unit
9935 (Load_Name => Unit_Nam,
9936 Required => False,
9937 Subunit => False,
9938 Error_Node => Pack_Decl);
9940 -- The load failed most likely because the physical file is
9941 -- missing.
9943 if Unit_Num = No_Unit then
9944 return Empty;
9946 -- Otherwise the load was successful, return the body of the unit
9948 else
9949 Body_Decl := Unit (Cunit (Unit_Num));
9951 -- If the unit is a subunit with an available proper body,
9952 -- return the proper body.
9954 if Nkind (Body_Decl) = N_Subunit
9955 and then Present (Proper_Body (Body_Decl))
9956 then
9957 Body_Decl := Proper_Body (Body_Decl);
9958 end if;
9960 return Body_Decl;
9961 end if;
9962 end if;
9964 return Empty;
9965 end Load_Package_Body;
9967 -- Local variables
9969 Pack_Id : constant Entity_Id := Defining_Entity (Pack_Decl);
9971 -- Start of processing for Has_Body
9973 begin
9974 -- The body is available
9976 if Present (Corresponding_Body (Pack_Decl)) then
9977 return True;
9979 -- The body is required if the package spec contains a construct which
9980 -- requires a completion in a body.
9982 elsif Unit_Requires_Body (Pack_Id) then
9983 return True;
9985 -- The body may be optional
9987 else
9988 return Present (Find_Corresponding_Body (Pack_Id));
9989 end if;
9990 end Has_Body;
9992 ----------
9993 -- Hash --
9994 ----------
9996 function Hash (NE : Node_Or_Entity_Id) return Bucket_Range_Type is
9997 pragma Assert (Present (NE));
9998 begin
9999 return Bucket_Range_Type (NE);
10000 end Hash;
10002 --------------------------
10003 -- In_External_Instance --
10004 --------------------------
10006 function In_External_Instance
10007 (N : Node_Id;
10008 Target_Decl : Node_Id) return Boolean
10010 Inst : Node_Id;
10011 Inst_Body : Node_Id;
10012 Inst_Spec : Node_Id;
10014 begin
10015 Inst := Find_Enclosing_Instance (Target_Decl);
10017 -- The target declaration appears within an instance spec. Visibility is
10018 -- ignored because internally generated primitives for private types may
10019 -- reside in the private declarations and still be invoked from outside.
10021 if Present (Inst) and then Nkind (Inst) = N_Package_Declaration then
10023 -- The scenario comes from the main unit and the instance does not
10025 if In_Extended_Main_Code_Unit (N)
10026 and then not In_Extended_Main_Code_Unit (Inst)
10027 then
10028 return True;
10030 -- Otherwise the scenario must not appear within the instance spec or
10031 -- body.
10033 else
10034 Spec_And_Body_From_Node
10035 (N => Inst,
10036 Spec_Decl => Inst_Spec,
10037 Body_Decl => Inst_Body);
10039 return not In_Subtree
10040 (N => N,
10041 Root1 => Inst_Spec,
10042 Root2 => Inst_Body);
10043 end if;
10044 end if;
10046 return False;
10047 end In_External_Instance;
10049 ---------------------
10050 -- In_Main_Context --
10051 ---------------------
10053 function In_Main_Context (N : Node_Id) return Boolean is
10054 begin
10055 -- Scenarios outside the main unit are not considered because the ALI
10056 -- information supplied to binde is for the main unit only.
10058 if not In_Extended_Main_Code_Unit (N) then
10059 return False;
10061 -- Scenarios within internal units are not considered unless switch
10062 -- -gnatdE (elaboration checks on predefined units) is in effect.
10064 elsif not Debug_Flag_EE and then In_Internal_Unit (N) then
10065 return False;
10066 end if;
10068 return True;
10069 end In_Main_Context;
10071 ---------------------
10072 -- In_Same_Context --
10073 ---------------------
10075 function In_Same_Context
10076 (N1 : Node_Id;
10077 N2 : Node_Id;
10078 Nested_OK : Boolean := False) return Boolean
10080 function Find_Enclosing_Context (N : Node_Id) return Node_Id;
10081 pragma Inline (Find_Enclosing_Context);
10082 -- Return the nearest enclosing non-library-level or compilation unit
10083 -- node which encapsulates arbitrary node N. Return Empty is no such
10084 -- context is available.
10086 function In_Nested_Context
10087 (Outer : Node_Id;
10088 Inner : Node_Id) return Boolean;
10089 pragma Inline (In_Nested_Context);
10090 -- Determine whether arbitrary node Outer encapsulates arbitrary node
10091 -- Inner.
10093 ----------------------------
10094 -- Find_Enclosing_Context --
10095 ----------------------------
10097 function Find_Enclosing_Context (N : Node_Id) return Node_Id is
10098 Context : Node_Id;
10099 Par : Node_Id;
10101 begin
10102 Par := Parent (N);
10103 while Present (Par) loop
10105 -- A traversal from a subunit continues via the corresponding stub
10107 if Nkind (Par) = N_Subunit then
10108 Par := Corresponding_Stub (Par);
10110 -- Stop the traversal when the nearest enclosing non-library-level
10111 -- encapsulator has been reached.
10113 elsif Is_Non_Library_Level_Encapsulator (Par) then
10114 Context := Parent (Par);
10116 -- The sole exception is when the encapsulator is the unit of
10117 -- compilation because this case requires special processing
10118 -- (see below).
10120 if Present (Context)
10121 and then Nkind (Context) = N_Compilation_Unit
10122 then
10123 null;
10125 else
10126 return Par;
10127 end if;
10129 -- Reaching a compilation unit node without hitting a non-library-
10130 -- level encapsulator indicates that N is at the library level in
10131 -- which case the compilation unit is the context.
10133 elsif Nkind (Par) = N_Compilation_Unit then
10134 return Par;
10135 end if;
10137 Par := Parent (Par);
10138 end loop;
10140 return Empty;
10141 end Find_Enclosing_Context;
10143 -----------------------
10144 -- In_Nested_Context --
10145 -----------------------
10147 function In_Nested_Context
10148 (Outer : Node_Id;
10149 Inner : Node_Id) return Boolean
10151 Par : Node_Id;
10153 begin
10154 Par := Inner;
10155 while Present (Par) loop
10157 -- A traversal from a subunit continues via the corresponding stub
10159 if Nkind (Par) = N_Subunit then
10160 Par := Corresponding_Stub (Par);
10162 elsif Par = Outer then
10163 return True;
10164 end if;
10166 Par := Parent (Par);
10167 end loop;
10169 return False;
10170 end In_Nested_Context;
10172 -- Local variables
10174 Context_1 : constant Node_Id := Find_Enclosing_Context (N1);
10175 Context_2 : constant Node_Id := Find_Enclosing_Context (N2);
10177 -- Start of processing for In_Same_Context
10179 begin
10180 -- Both nodes appear within the same context
10182 if Context_1 = Context_2 then
10183 return True;
10185 -- Both nodes appear in compilation units. Determine whether one unit
10186 -- is the body of the other.
10188 elsif Nkind (Context_1) = N_Compilation_Unit
10189 and then Nkind (Context_2) = N_Compilation_Unit
10190 then
10191 return
10192 Is_Same_Unit
10193 (Unit_1 => Defining_Entity (Unit (Context_1)),
10194 Unit_2 => Defining_Entity (Unit (Context_2)));
10196 -- The context of N1 encloses the context of N2
10198 elsif Nested_OK and then In_Nested_Context (Context_1, Context_2) then
10199 return True;
10200 end if;
10202 return False;
10203 end In_Same_Context;
10205 ----------------
10206 -- Initialize --
10207 ----------------
10209 procedure Initialize is
10210 begin
10211 -- Set the soft link which enables Atree.Rewrite to update a scenario
10212 -- each time it is transformed into another node.
10214 Set_Rewriting_Proc (Update_Elaboration_Scenario'Access);
10216 -- Create all internal data structures and activate the elaboration
10217 -- phase of the compiler.
10219 Initialize_All_Data_Structures;
10220 Set_Elaboration_Phase (Active);
10221 end Initialize;
10223 ------------------------------------
10224 -- Initialize_All_Data_Structures --
10225 ------------------------------------
10227 procedure Initialize_All_Data_Structures is
10228 begin
10229 Initialize_Body_Processor;
10230 Initialize_Early_Call_Region_Processor;
10231 Initialize_Elaborated_Units;
10232 Initialize_Internal_Representation;
10233 Initialize_Invocation_Graph;
10234 Initialize_Scenario_Storage;
10235 end Initialize_All_Data_Structures;
10237 --------------------------
10238 -- Instantiated_Generic --
10239 --------------------------
10241 function Instantiated_Generic (Inst : Node_Id) return Entity_Id is
10242 begin
10243 -- Traverse a possible chain of renamings to obtain the original generic
10244 -- being instantiatied.
10246 return Get_Renamed_Entity (Entity (Name (Inst)));
10247 end Instantiated_Generic;
10249 -----------------------------
10250 -- Internal_Representation --
10251 -----------------------------
10253 package body Internal_Representation is
10255 -----------
10256 -- Types --
10257 -----------
10259 -- The following type represents the contents of a scenario
10261 type Scenario_Rep_Record is record
10262 Elab_Checks_OK : Boolean := False;
10263 -- The status of elaboration checks for the scenario
10265 Elab_Warnings_OK : Boolean := False;
10266 -- The status of elaboration warnings for the scenario
10268 GM : Extended_Ghost_Mode := Is_Checked_Or_Not_Specified;
10269 -- The Ghost mode of the scenario
10271 Kind : Scenario_Kind := No_Scenario;
10272 -- The nature of the scenario
10274 Level : Enclosing_Level_Kind := No_Level;
10275 -- The enclosing level where the scenario resides
10277 SM : Extended_SPARK_Mode := Is_Off_Or_Not_Specified;
10278 -- The SPARK mode of the scenario
10280 Target : Entity_Id := Empty;
10281 -- The target of the scenario
10283 -- The following attributes are multiplexed and depend on the Kind of
10284 -- the scenario. They are mapped as follows:
10286 -- Call_Scenario
10287 -- Is_Dispatching_Call (Flag_1)
10289 -- Task_Activation_Scenario
10290 -- Activated_Task_Objects (List_1)
10291 -- Activated_Task_Type (Field_1)
10293 -- Variable_Reference
10294 -- Is_Read_Reference (Flag_1)
10296 Flag_1 : Boolean := False;
10297 Field_1 : Node_Or_Entity_Id := Empty;
10298 List_1 : NE_List.Doubly_Linked_List := NE_List.Nil;
10299 end record;
10301 -- The following type represents the contents of a target
10303 type Target_Rep_Record is record
10304 Body_Decl : Node_Id := Empty;
10305 -- The declaration of the target body
10307 Elab_Checks_OK : Boolean := False;
10308 -- The status of elaboration checks for the target
10310 Elab_Warnings_OK : Boolean := False;
10311 -- The status of elaboration warnings for the target
10313 GM : Extended_Ghost_Mode := Is_Checked_Or_Not_Specified;
10314 -- The Ghost mode of the target
10316 Kind : Target_Kind := No_Target;
10317 -- The nature of the target
10319 SM : Extended_SPARK_Mode := Is_Off_Or_Not_Specified;
10320 -- The SPARK mode of the target
10322 Spec_Decl : Node_Id := Empty;
10323 -- The declaration of the target spec
10325 Unit : Entity_Id := Empty;
10326 -- The top unit where the target is declared
10328 Version : Representation_Kind := No_Representation;
10329 -- The version of the target representation
10331 -- The following attributes are multiplexed and depend on the Kind of
10332 -- the target. They are mapped as follows:
10334 -- Subprogram_Target
10335 -- Barrier_Body_Declaration (Field_1)
10337 -- Variable_Target
10338 -- Variable_Declaration (Field_1)
10340 Field_1 : Node_Or_Entity_Id := Empty;
10341 end record;
10343 ---------------------
10344 -- Data structures --
10345 ---------------------
10347 procedure Destroy (T_Id : in out Target_Rep_Id);
10348 -- Destroy a target representation T_Id
10350 package ETT_Map is new Dynamic_Hash_Tables
10351 (Key_Type => Entity_Id,
10352 Value_Type => Target_Rep_Id,
10353 No_Value => No_Target_Rep,
10354 Expansion_Threshold => 1.5,
10355 Expansion_Factor => 2,
10356 Compression_Threshold => 0.3,
10357 Compression_Factor => 2,
10358 "=" => "=",
10359 Destroy_Value => Destroy,
10360 Hash => Hash);
10362 -- The following map relates target representations to entities
10364 Entity_To_Target_Map : ETT_Map.Dynamic_Hash_Table := ETT_Map.Nil;
10366 procedure Destroy (S_Id : in out Scenario_Rep_Id);
10367 -- Destroy a scenario representation S_Id
10369 package NTS_Map is new Dynamic_Hash_Tables
10370 (Key_Type => Node_Id,
10371 Value_Type => Scenario_Rep_Id,
10372 No_Value => No_Scenario_Rep,
10373 Expansion_Threshold => 1.5,
10374 Expansion_Factor => 2,
10375 Compression_Threshold => 0.3,
10376 Compression_Factor => 2,
10377 "=" => "=",
10378 Destroy_Value => Destroy,
10379 Hash => Hash);
10381 -- The following map relates scenario representations to nodes
10383 Node_To_Scenario_Map : NTS_Map.Dynamic_Hash_Table := NTS_Map.Nil;
10385 -- The following table stores all scenario representations
10387 package Scenario_Reps is new Table.Table
10388 (Table_Index_Type => Scenario_Rep_Id,
10389 Table_Component_Type => Scenario_Rep_Record,
10390 Table_Low_Bound => First_Scenario_Rep,
10391 Table_Initial => 1000,
10392 Table_Increment => 200,
10393 Table_Name => "Scenario_Reps");
10395 -- The following table stores all target representations
10397 package Target_Reps is new Table.Table
10398 (Table_Index_Type => Target_Rep_Id,
10399 Table_Component_Type => Target_Rep_Record,
10400 Table_Low_Bound => First_Target_Rep,
10401 Table_Initial => 1000,
10402 Table_Increment => 200,
10403 Table_Name => "Target_Reps");
10405 --------------
10406 -- Builders --
10407 --------------
10409 function Create_Access_Taken_Rep
10410 (Attr : Node_Id) return Scenario_Rep_Record;
10411 pragma Inline (Create_Access_Taken_Rep);
10412 -- Create the representation of 'Access attribute Attr
10414 function Create_Call_Or_Task_Activation_Rep
10415 (Call : Node_Id) return Scenario_Rep_Record;
10416 pragma Inline (Create_Call_Or_Task_Activation_Rep);
10417 -- Create the representation of call or task activation Call
10419 function Create_Derived_Type_Rep
10420 (Typ_Decl : Node_Id) return Scenario_Rep_Record;
10421 pragma Inline (Create_Derived_Type_Rep);
10422 -- Create the representation of a derived type described by declaration
10423 -- Typ_Decl.
10425 function Create_Generic_Rep
10426 (Gen_Id : Entity_Id) return Target_Rep_Record;
10427 pragma Inline (Create_Generic_Rep);
10428 -- Create the representation of generic Gen_Id
10430 function Create_Instantiation_Rep
10431 (Inst : Node_Id) return Scenario_Rep_Record;
10432 pragma Inline (Create_Instantiation_Rep);
10433 -- Create the representation of instantiation Inst
10435 function Create_Package_Rep
10436 (Pack_Id : Entity_Id) return Target_Rep_Record;
10437 pragma Inline (Create_Package_Rep);
10438 -- Create the representation of package Pack_Id
10440 function Create_Protected_Entry_Rep
10441 (PE_Id : Entity_Id) return Target_Rep_Record;
10442 pragma Inline (Create_Protected_Entry_Rep);
10443 -- Create the representation of protected entry PE_Id
10445 function Create_Protected_Subprogram_Rep
10446 (PS_Id : Entity_Id) return Target_Rep_Record;
10447 pragma Inline (Create_Protected_Subprogram_Rep);
10448 -- Create the representation of protected subprogram PS_Id
10450 function Create_Refined_State_Pragma_Rep
10451 (Prag : Node_Id) return Scenario_Rep_Record;
10452 pragma Inline (Create_Refined_State_Pragma_Rep);
10453 -- Create the representation of Refined_State pragma Prag
10455 function Create_Scenario_Rep
10456 (N : Node_Id;
10457 In_State : Processing_In_State) return Scenario_Rep_Record;
10458 pragma Inline (Create_Scenario_Rep);
10459 -- Top level dispatcher. Create the representation of elaboration
10460 -- scenario N. In_State is the current state of the Processing phase.
10462 function Create_Subprogram_Rep
10463 (Subp_Id : Entity_Id) return Target_Rep_Record;
10464 pragma Inline (Create_Subprogram_Rep);
10465 -- Create the representation of entry, operator, or subprogram Subp_Id
10467 function Create_Target_Rep
10468 (Id : Entity_Id;
10469 In_State : Processing_In_State) return Target_Rep_Record;
10470 pragma Inline (Create_Target_Rep);
10471 -- Top level dispatcher. Create the representation of elaboration target
10472 -- Id. In_State is the current state of the Processing phase.
10474 function Create_Task_Entry_Rep
10475 (TE_Id : Entity_Id) return Target_Rep_Record;
10476 pragma Inline (Create_Task_Entry_Rep);
10477 -- Create the representation of task entry TE_Id
10479 function Create_Task_Rep (Task_Typ : Entity_Id) return Target_Rep_Record;
10480 pragma Inline (Create_Task_Rep);
10481 -- Create the representation of task type Typ
10483 function Create_Variable_Assignment_Rep
10484 (Asmt : Node_Id) return Scenario_Rep_Record;
10485 pragma Inline (Create_Variable_Assignment_Rep);
10486 -- Create the representation of variable assignment Asmt
10488 function Create_Variable_Reference_Rep
10489 (Ref : Node_Id) return Scenario_Rep_Record;
10490 pragma Inline (Create_Variable_Reference_Rep);
10491 -- Create the representation of variable reference Ref
10493 function Create_Variable_Rep
10494 (Var_Id : Entity_Id) return Target_Rep_Record;
10495 pragma Inline (Create_Variable_Rep);
10496 -- Create the representation of variable Var_Id
10498 -----------------------
10499 -- Local subprograms --
10500 -----------------------
10502 function Ghost_Mode_Of_Entity
10503 (Id : Entity_Id) return Extended_Ghost_Mode;
10504 pragma Inline (Ghost_Mode_Of_Entity);
10505 -- Obtain the extended Ghost mode of arbitrary entity Id
10507 function Ghost_Mode_Of_Node (N : Node_Id) return Extended_Ghost_Mode;
10508 pragma Inline (Ghost_Mode_Of_Node);
10509 -- Obtain the extended Ghost mode of arbitrary node N
10511 function Present (S_Id : Scenario_Rep_Id) return Boolean;
10512 pragma Inline (Present);
10513 -- Determine whether scenario representation S_Id exists
10515 function Present (T_Id : Target_Rep_Id) return Boolean;
10516 pragma Inline (Present);
10517 -- Determine whether target representation T_Id exists
10519 function SPARK_Mode_Of_Entity
10520 (Id : Entity_Id) return Extended_SPARK_Mode;
10521 pragma Inline (SPARK_Mode_Of_Entity);
10522 -- Obtain the extended SPARK mode of arbitrary entity Id
10524 function SPARK_Mode_Of_Node (N : Node_Id) return Extended_SPARK_Mode;
10525 pragma Inline (SPARK_Mode_Of_Node);
10526 -- Obtain the extended SPARK mode of arbitrary node N
10528 function To_Ghost_Mode
10529 (Ignored_Status : Boolean) return Extended_Ghost_Mode;
10530 pragma Inline (To_Ghost_Mode);
10531 -- Convert a Ghost mode indicated by Ignored_Status into its extended
10532 -- equivalent.
10534 function To_SPARK_Mode (On_Status : Boolean) return Extended_SPARK_Mode;
10535 pragma Inline (To_SPARK_Mode);
10536 -- Convert a SPARK mode indicated by On_Status into its extended
10537 -- equivalent.
10539 function Version (T_Id : Target_Rep_Id) return Representation_Kind;
10540 pragma Inline (Version);
10541 -- Obtain the version of target representation T_Id
10543 ----------------------------
10544 -- Activated_Task_Objects --
10545 ----------------------------
10547 function Activated_Task_Objects
10548 (S_Id : Scenario_Rep_Id) return NE_List.Doubly_Linked_List
10550 pragma Assert (Present (S_Id));
10551 pragma Assert (Kind (S_Id) = Task_Activation_Scenario);
10553 begin
10554 return Scenario_Reps.Table (S_Id).List_1;
10555 end Activated_Task_Objects;
10557 -------------------------
10558 -- Activated_Task_Type --
10559 -------------------------
10561 function Activated_Task_Type
10562 (S_Id : Scenario_Rep_Id) return Entity_Id
10564 pragma Assert (Present (S_Id));
10565 pragma Assert (Kind (S_Id) = Task_Activation_Scenario);
10567 begin
10568 return Scenario_Reps.Table (S_Id).Field_1;
10569 end Activated_Task_Type;
10571 ------------------------------
10572 -- Barrier_Body_Declaration --
10573 ------------------------------
10575 function Barrier_Body_Declaration
10576 (T_Id : Target_Rep_Id) return Node_Id
10578 pragma Assert (Present (T_Id));
10579 pragma Assert (Kind (T_Id) = Subprogram_Target);
10581 begin
10582 return Target_Reps.Table (T_Id).Field_1;
10583 end Barrier_Body_Declaration;
10585 ----------------------
10586 -- Body_Declaration --
10587 ----------------------
10589 function Body_Declaration (T_Id : Target_Rep_Id) return Node_Id is
10590 pragma Assert (Present (T_Id));
10591 begin
10592 return Target_Reps.Table (T_Id).Body_Decl;
10593 end Body_Declaration;
10595 -----------------------------
10596 -- Create_Access_Taken_Rep --
10597 -----------------------------
10599 function Create_Access_Taken_Rep
10600 (Attr : Node_Id) return Scenario_Rep_Record
10602 Rec : Scenario_Rep_Record;
10604 begin
10605 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Attr);
10606 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Attr);
10607 Rec.GM := Is_Checked_Or_Not_Specified;
10608 Rec.SM := SPARK_Mode_Of_Node (Attr);
10609 Rec.Kind := Access_Taken_Scenario;
10610 Rec.Target := Canonical_Subprogram (Entity (Prefix (Attr)));
10612 return Rec;
10613 end Create_Access_Taken_Rep;
10615 ----------------------------------------
10616 -- Create_Call_Or_Task_Activation_Rep --
10617 ----------------------------------------
10619 function Create_Call_Or_Task_Activation_Rep
10620 (Call : Node_Id) return Scenario_Rep_Record
10622 Subp_Id : constant Entity_Id := Canonical_Subprogram (Target (Call));
10623 Kind : Scenario_Kind;
10624 Rec : Scenario_Rep_Record;
10626 begin
10627 if Is_Activation_Proc (Subp_Id) then
10628 Kind := Task_Activation_Scenario;
10629 else
10630 Kind := Call_Scenario;
10631 end if;
10633 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Call);
10634 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Call);
10635 Rec.GM := Ghost_Mode_Of_Node (Call);
10636 Rec.SM := SPARK_Mode_Of_Node (Call);
10637 Rec.Kind := Kind;
10638 Rec.Target := Subp_Id;
10640 -- Scenario-specific attributes
10642 Rec.Flag_1 := Is_Dispatching_Call (Call); -- Dispatching_Call
10644 return Rec;
10645 end Create_Call_Or_Task_Activation_Rep;
10647 -----------------------------
10648 -- Create_Derived_Type_Rep --
10649 -----------------------------
10651 function Create_Derived_Type_Rep
10652 (Typ_Decl : Node_Id) return Scenario_Rep_Record
10654 Typ : constant Entity_Id := Defining_Entity (Typ_Decl);
10655 Rec : Scenario_Rep_Record;
10657 begin
10658 Rec.Elab_Checks_OK := False; -- not relevant
10659 Rec.Elab_Warnings_OK := False; -- not relevant
10660 Rec.GM := Ghost_Mode_Of_Entity (Typ);
10661 Rec.SM := SPARK_Mode_Of_Entity (Typ);
10662 Rec.Kind := Derived_Type_Scenario;
10663 Rec.Target := Typ;
10665 return Rec;
10666 end Create_Derived_Type_Rep;
10668 ------------------------
10669 -- Create_Generic_Rep --
10670 ------------------------
10672 function Create_Generic_Rep
10673 (Gen_Id : Entity_Id) return Target_Rep_Record
10675 Rec : Target_Rep_Record;
10677 begin
10678 Rec.Kind := Generic_Target;
10680 Spec_And_Body_From_Entity
10681 (Id => Gen_Id,
10682 Body_Decl => Rec.Body_Decl,
10683 Spec_Decl => Rec.Spec_Decl);
10685 return Rec;
10686 end Create_Generic_Rep;
10688 ------------------------------
10689 -- Create_Instantiation_Rep --
10690 ------------------------------
10692 function Create_Instantiation_Rep
10693 (Inst : Node_Id) return Scenario_Rep_Record
10695 Rec : Scenario_Rep_Record;
10697 begin
10698 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Inst);
10699 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Inst);
10700 Rec.GM := Ghost_Mode_Of_Node (Inst);
10701 Rec.SM := SPARK_Mode_Of_Node (Inst);
10702 Rec.Kind := Instantiation_Scenario;
10703 Rec.Target := Instantiated_Generic (Inst);
10705 return Rec;
10706 end Create_Instantiation_Rep;
10708 ------------------------
10709 -- Create_Package_Rep --
10710 ------------------------
10712 function Create_Package_Rep
10713 (Pack_Id : Entity_Id) return Target_Rep_Record
10715 Rec : Target_Rep_Record;
10717 begin
10718 Rec.Kind := Package_Target;
10720 Spec_And_Body_From_Entity
10721 (Id => Pack_Id,
10722 Body_Decl => Rec.Body_Decl,
10723 Spec_Decl => Rec.Spec_Decl);
10725 return Rec;
10726 end Create_Package_Rep;
10728 --------------------------------
10729 -- Create_Protected_Entry_Rep --
10730 --------------------------------
10732 function Create_Protected_Entry_Rep
10733 (PE_Id : Entity_Id) return Target_Rep_Record
10735 Prot_Id : constant Entity_Id := Protected_Body_Subprogram (PE_Id);
10737 Barf_Id : Entity_Id;
10738 Dummy : Node_Id;
10739 Rec : Target_Rep_Record;
10740 Spec_Id : Entity_Id;
10742 begin
10743 -- When the entry [family] has already been expanded, it carries both
10744 -- the procedure which emulates the behavior of the entry [family] as
10745 -- well as the barrier function.
10747 if Present (Prot_Id) then
10748 Barf_Id := Barrier_Function (PE_Id);
10749 Spec_Id := Prot_Id;
10751 -- Otherwise no expansion took place
10753 else
10754 Barf_Id := Empty;
10755 Spec_Id := PE_Id;
10756 end if;
10758 Rec.Kind := Subprogram_Target;
10760 Spec_And_Body_From_Entity
10761 (Id => Spec_Id,
10762 Body_Decl => Rec.Body_Decl,
10763 Spec_Decl => Rec.Spec_Decl);
10765 -- Target-specific attributes
10767 if Present (Barf_Id) then
10768 Spec_And_Body_From_Entity
10769 (Id => Barf_Id,
10770 Body_Decl => Rec.Field_1, -- Barrier_Body_Declaration
10771 Spec_Decl => Dummy);
10772 end if;
10774 return Rec;
10775 end Create_Protected_Entry_Rep;
10777 -------------------------------------
10778 -- Create_Protected_Subprogram_Rep --
10779 -------------------------------------
10781 function Create_Protected_Subprogram_Rep
10782 (PS_Id : Entity_Id) return Target_Rep_Record
10784 Prot_Id : constant Entity_Id := Protected_Body_Subprogram (PS_Id);
10785 Rec : Target_Rep_Record;
10786 Spec_Id : Entity_Id;
10788 begin
10789 -- When the protected subprogram has already been expanded, it
10790 -- carries the subprogram which seizes the lock and invokes the
10791 -- original statements.
10793 if Present (Prot_Id) then
10794 Spec_Id := Prot_Id;
10796 -- Otherwise no expansion took place
10798 else
10799 Spec_Id := PS_Id;
10800 end if;
10802 Rec.Kind := Subprogram_Target;
10804 Spec_And_Body_From_Entity
10805 (Id => Spec_Id,
10806 Body_Decl => Rec.Body_Decl,
10807 Spec_Decl => Rec.Spec_Decl);
10809 return Rec;
10810 end Create_Protected_Subprogram_Rep;
10812 -------------------------------------
10813 -- Create_Refined_State_Pragma_Rep --
10814 -------------------------------------
10816 function Create_Refined_State_Pragma_Rep
10817 (Prag : Node_Id) return Scenario_Rep_Record
10819 Rec : Scenario_Rep_Record;
10821 begin
10822 Rec.Elab_Checks_OK := False; -- not relevant
10823 Rec.Elab_Warnings_OK := False; -- not relevant
10824 Rec.GM :=
10825 To_Ghost_Mode (Is_Ignored_Ghost_Pragma (Prag));
10826 Rec.SM := Is_Off_Or_Not_Specified;
10827 Rec.Kind := Refined_State_Pragma_Scenario;
10828 Rec.Target := Empty;
10830 return Rec;
10831 end Create_Refined_State_Pragma_Rep;
10833 -------------------------
10834 -- Create_Scenario_Rep --
10835 -------------------------
10837 function Create_Scenario_Rep
10838 (N : Node_Id;
10839 In_State : Processing_In_State) return Scenario_Rep_Record
10841 pragma Unreferenced (In_State);
10843 Rec : Scenario_Rep_Record;
10845 begin
10846 if Is_Suitable_Access_Taken (N) then
10847 Rec := Create_Access_Taken_Rep (N);
10849 elsif Is_Suitable_Call (N) then
10850 Rec := Create_Call_Or_Task_Activation_Rep (N);
10852 elsif Is_Suitable_Instantiation (N) then
10853 Rec := Create_Instantiation_Rep (N);
10855 elsif Is_Suitable_SPARK_Derived_Type (N) then
10856 Rec := Create_Derived_Type_Rep (N);
10858 elsif Is_Suitable_SPARK_Refined_State_Pragma (N) then
10859 Rec := Create_Refined_State_Pragma_Rep (N);
10861 elsif Is_Suitable_Variable_Assignment (N) then
10862 Rec := Create_Variable_Assignment_Rep (N);
10864 elsif Is_Suitable_Variable_Reference (N) then
10865 Rec := Create_Variable_Reference_Rep (N);
10867 else
10868 pragma Assert (False);
10869 return Rec;
10870 end if;
10872 -- Common scenario attributes
10874 Rec.Level := Find_Enclosing_Level (N);
10876 return Rec;
10877 end Create_Scenario_Rep;
10879 ---------------------------
10880 -- Create_Subprogram_Rep --
10881 ---------------------------
10883 function Create_Subprogram_Rep
10884 (Subp_Id : Entity_Id) return Target_Rep_Record
10886 Rec : Target_Rep_Record;
10887 Spec_Id : Entity_Id;
10889 begin
10890 Spec_Id := Subp_Id;
10892 -- The elaboration target denotes an internal function that returns a
10893 -- constrained array type in a SPARK-to-C compilation. In this case
10894 -- the function receives a corresponding procedure which has an out
10895 -- parameter. The proper body for ABE checks and diagnostics is that
10896 -- of the procedure.
10898 if Ekind (Spec_Id) = E_Function
10899 and then Rewritten_For_C (Spec_Id)
10900 then
10901 Spec_Id := Corresponding_Procedure (Spec_Id);
10902 end if;
10904 Rec.Kind := Subprogram_Target;
10906 Spec_And_Body_From_Entity
10907 (Id => Spec_Id,
10908 Body_Decl => Rec.Body_Decl,
10909 Spec_Decl => Rec.Spec_Decl);
10911 return Rec;
10912 end Create_Subprogram_Rep;
10914 -----------------------
10915 -- Create_Target_Rep --
10916 -----------------------
10918 function Create_Target_Rep
10919 (Id : Entity_Id;
10920 In_State : Processing_In_State) return Target_Rep_Record
10922 Rec : Target_Rep_Record;
10924 begin
10925 if Is_Generic_Unit (Id) then
10926 Rec := Create_Generic_Rep (Id);
10928 elsif Is_Protected_Entry (Id) then
10929 Rec := Create_Protected_Entry_Rep (Id);
10931 elsif Is_Protected_Subp (Id) then
10932 Rec := Create_Protected_Subprogram_Rep (Id);
10934 elsif Is_Task_Entry (Id) then
10935 Rec := Create_Task_Entry_Rep (Id);
10937 elsif Is_Task_Type (Id) then
10938 Rec := Create_Task_Rep (Id);
10940 elsif Ekind (Id) in E_Constant | E_Variable then
10941 Rec := Create_Variable_Rep (Id);
10943 elsif Ekind (Id) in E_Entry | E_Function | E_Operator | E_Procedure
10944 then
10945 Rec := Create_Subprogram_Rep (Id);
10947 elsif Ekind (Id) = E_Package then
10948 Rec := Create_Package_Rep (Id);
10950 else
10951 pragma Assert (False);
10952 return Rec;
10953 end if;
10955 -- Common target attributes
10957 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Id (Id);
10958 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Id (Id);
10959 Rec.GM := Ghost_Mode_Of_Entity (Id);
10960 Rec.SM := SPARK_Mode_Of_Entity (Id);
10961 Rec.Unit := Find_Top_Unit (Id);
10962 Rec.Version := In_State.Representation;
10964 return Rec;
10965 end Create_Target_Rep;
10967 ---------------------------
10968 -- Create_Task_Entry_Rep --
10969 ---------------------------
10971 function Create_Task_Entry_Rep
10972 (TE_Id : Entity_Id) return Target_Rep_Record
10974 Task_Typ : constant Entity_Id := Non_Private_View (Scope (TE_Id));
10975 Task_Body_Id : constant Entity_Id := Task_Body_Procedure (Task_Typ);
10977 Rec : Target_Rep_Record;
10978 Spec_Id : Entity_Id;
10980 begin
10981 -- The task type has already been expanded, it carries the procedure
10982 -- which emulates the behavior of the task body.
10984 if Present (Task_Body_Id) then
10985 Spec_Id := Task_Body_Id;
10987 -- Otherwise no expansion took place
10989 else
10990 Spec_Id := TE_Id;
10991 end if;
10993 Rec.Kind := Subprogram_Target;
10995 Spec_And_Body_From_Entity
10996 (Id => Spec_Id,
10997 Body_Decl => Rec.Body_Decl,
10998 Spec_Decl => Rec.Spec_Decl);
11000 return Rec;
11001 end Create_Task_Entry_Rep;
11003 ---------------------
11004 -- Create_Task_Rep --
11005 ---------------------
11007 function Create_Task_Rep
11008 (Task_Typ : Entity_Id) return Target_Rep_Record
11010 Task_Body_Id : constant Entity_Id := Task_Body_Procedure (Task_Typ);
11012 Rec : Target_Rep_Record;
11013 Spec_Id : Entity_Id;
11015 begin
11016 -- The task type has already been expanded, it carries the procedure
11017 -- which emulates the behavior of the task body.
11019 if Present (Task_Body_Id) then
11020 Spec_Id := Task_Body_Id;
11022 -- Otherwise no expansion took place
11024 else
11025 Spec_Id := Task_Typ;
11026 end if;
11028 Rec.Kind := Task_Target;
11030 Spec_And_Body_From_Entity
11031 (Id => Spec_Id,
11032 Body_Decl => Rec.Body_Decl,
11033 Spec_Decl => Rec.Spec_Decl);
11035 return Rec;
11036 end Create_Task_Rep;
11038 ------------------------------------
11039 -- Create_Variable_Assignment_Rep --
11040 ------------------------------------
11042 function Create_Variable_Assignment_Rep
11043 (Asmt : Node_Id) return Scenario_Rep_Record
11045 Var_Id : constant Entity_Id := Entity (Assignment_Target (Asmt));
11046 Rec : Scenario_Rep_Record;
11048 begin
11049 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Asmt);
11050 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Id (Var_Id);
11051 Rec.GM := Ghost_Mode_Of_Node (Asmt);
11052 Rec.SM := SPARK_Mode_Of_Node (Asmt);
11053 Rec.Kind := Variable_Assignment_Scenario;
11054 Rec.Target := Var_Id;
11056 return Rec;
11057 end Create_Variable_Assignment_Rep;
11059 -----------------------------------
11060 -- Create_Variable_Reference_Rep --
11061 -----------------------------------
11063 function Create_Variable_Reference_Rep
11064 (Ref : Node_Id) return Scenario_Rep_Record
11066 Rec : Scenario_Rep_Record;
11068 begin
11069 Rec.Elab_Checks_OK := Is_Elaboration_Checks_OK_Node (Ref);
11070 Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Ref);
11071 Rec.GM := Ghost_Mode_Of_Node (Ref);
11072 Rec.SM := SPARK_Mode_Of_Node (Ref);
11073 Rec.Kind := Variable_Reference_Scenario;
11074 Rec.Target := Target (Ref);
11076 -- Scenario-specific attributes
11078 Rec.Flag_1 := Is_Read (Ref); -- Is_Read_Reference
11080 return Rec;
11081 end Create_Variable_Reference_Rep;
11083 -------------------------
11084 -- Create_Variable_Rep --
11085 -------------------------
11087 function Create_Variable_Rep
11088 (Var_Id : Entity_Id) return Target_Rep_Record
11090 Rec : Target_Rep_Record;
11092 begin
11093 Rec.Kind := Variable_Target;
11095 -- Target-specific attributes
11097 Rec.Field_1 := Declaration_Node (Var_Id); -- Variable_Declaration
11099 return Rec;
11100 end Create_Variable_Rep;
11102 -------------
11103 -- Destroy --
11104 -------------
11106 procedure Destroy (S_Id : in out Scenario_Rep_Id) is
11107 pragma Unreferenced (S_Id);
11108 begin
11109 null;
11110 end Destroy;
11112 -------------
11113 -- Destroy --
11114 -------------
11116 procedure Destroy (T_Id : in out Target_Rep_Id) is
11117 pragma Unreferenced (T_Id);
11118 begin
11119 null;
11120 end Destroy;
11122 --------------------------------
11123 -- Disable_Elaboration_Checks --
11124 --------------------------------
11126 procedure Disable_Elaboration_Checks (S_Id : Scenario_Rep_Id) is
11127 pragma Assert (Present (S_Id));
11128 begin
11129 Scenario_Reps.Table (S_Id).Elab_Checks_OK := False;
11130 end Disable_Elaboration_Checks;
11132 --------------------------------
11133 -- Disable_Elaboration_Checks --
11134 --------------------------------
11136 procedure Disable_Elaboration_Checks (T_Id : Target_Rep_Id) is
11137 pragma Assert (Present (T_Id));
11138 begin
11139 Target_Reps.Table (T_Id).Elab_Checks_OK := False;
11140 end Disable_Elaboration_Checks;
11142 ---------------------------
11143 -- Elaboration_Checks_OK --
11144 ---------------------------
11146 function Elaboration_Checks_OK (S_Id : Scenario_Rep_Id) return Boolean is
11147 pragma Assert (Present (S_Id));
11148 begin
11149 return Scenario_Reps.Table (S_Id).Elab_Checks_OK;
11150 end Elaboration_Checks_OK;
11152 ---------------------------
11153 -- Elaboration_Checks_OK --
11154 ---------------------------
11156 function Elaboration_Checks_OK (T_Id : Target_Rep_Id) return Boolean is
11157 pragma Assert (Present (T_Id));
11158 begin
11159 return Target_Reps.Table (T_Id).Elab_Checks_OK;
11160 end Elaboration_Checks_OK;
11162 -----------------------------
11163 -- Elaboration_Warnings_OK --
11164 -----------------------------
11166 function Elaboration_Warnings_OK
11167 (S_Id : Scenario_Rep_Id) return Boolean
11169 pragma Assert (Present (S_Id));
11170 begin
11171 return Scenario_Reps.Table (S_Id).Elab_Warnings_OK;
11172 end Elaboration_Warnings_OK;
11174 -----------------------------
11175 -- Elaboration_Warnings_OK --
11176 -----------------------------
11178 function Elaboration_Warnings_OK (T_Id : Target_Rep_Id) return Boolean is
11179 pragma Assert (Present (T_Id));
11180 begin
11181 return Target_Reps.Table (T_Id).Elab_Warnings_OK;
11182 end Elaboration_Warnings_OK;
11184 --------------------------------------
11185 -- Finalize_Internal_Representation --
11186 --------------------------------------
11188 procedure Finalize_Internal_Representation is
11189 begin
11190 ETT_Map.Destroy (Entity_To_Target_Map);
11191 NTS_Map.Destroy (Node_To_Scenario_Map);
11192 end Finalize_Internal_Representation;
11194 -------------------
11195 -- Ghost_Mode_Of --
11196 -------------------
11198 function Ghost_Mode_Of
11199 (S_Id : Scenario_Rep_Id) return Extended_Ghost_Mode
11201 pragma Assert (Present (S_Id));
11202 begin
11203 return Scenario_Reps.Table (S_Id).GM;
11204 end Ghost_Mode_Of;
11206 -------------------
11207 -- Ghost_Mode_Of --
11208 -------------------
11210 function Ghost_Mode_Of
11211 (T_Id : Target_Rep_Id) return Extended_Ghost_Mode
11213 pragma Assert (Present (T_Id));
11214 begin
11215 return Target_Reps.Table (T_Id).GM;
11216 end Ghost_Mode_Of;
11218 --------------------------
11219 -- Ghost_Mode_Of_Entity --
11220 --------------------------
11222 function Ghost_Mode_Of_Entity
11223 (Id : Entity_Id) return Extended_Ghost_Mode
11225 begin
11226 return To_Ghost_Mode (Is_Ignored_Ghost_Entity (Id));
11227 end Ghost_Mode_Of_Entity;
11229 ------------------------
11230 -- Ghost_Mode_Of_Node --
11231 ------------------------
11233 function Ghost_Mode_Of_Node (N : Node_Id) return Extended_Ghost_Mode is
11234 begin
11235 return To_Ghost_Mode (Is_Ignored_Ghost_Node (N));
11236 end Ghost_Mode_Of_Node;
11238 ----------------------------------------
11239 -- Initialize_Internal_Representation --
11240 ----------------------------------------
11242 procedure Initialize_Internal_Representation is
11243 begin
11244 Entity_To_Target_Map := ETT_Map.Create (500);
11245 Node_To_Scenario_Map := NTS_Map.Create (500);
11246 end Initialize_Internal_Representation;
11248 -------------------------
11249 -- Is_Dispatching_Call --
11250 -------------------------
11252 function Is_Dispatching_Call (S_Id : Scenario_Rep_Id) return Boolean is
11253 pragma Assert (Present (S_Id));
11254 pragma Assert (Kind (S_Id) = Call_Scenario);
11256 begin
11257 return Scenario_Reps.Table (S_Id).Flag_1;
11258 end Is_Dispatching_Call;
11260 -----------------------
11261 -- Is_Read_Reference --
11262 -----------------------
11264 function Is_Read_Reference (S_Id : Scenario_Rep_Id) return Boolean is
11265 pragma Assert (Present (S_Id));
11266 pragma Assert (Kind (S_Id) = Variable_Reference_Scenario);
11268 begin
11269 return Scenario_Reps.Table (S_Id).Flag_1;
11270 end Is_Read_Reference;
11272 ----------
11273 -- Kind --
11274 ----------
11276 function Kind (S_Id : Scenario_Rep_Id) return Scenario_Kind is
11277 pragma Assert (Present (S_Id));
11278 begin
11279 return Scenario_Reps.Table (S_Id).Kind;
11280 end Kind;
11282 ----------
11283 -- Kind --
11284 ----------
11286 function Kind (T_Id : Target_Rep_Id) return Target_Kind is
11287 pragma Assert (Present (T_Id));
11288 begin
11289 return Target_Reps.Table (T_Id).Kind;
11290 end Kind;
11292 -----------
11293 -- Level --
11294 -----------
11296 function Level (S_Id : Scenario_Rep_Id) return Enclosing_Level_Kind is
11297 pragma Assert (Present (S_Id));
11298 begin
11299 return Scenario_Reps.Table (S_Id).Level;
11300 end Level;
11302 -------------
11303 -- Present --
11304 -------------
11306 function Present (S_Id : Scenario_Rep_Id) return Boolean is
11307 begin
11308 return S_Id /= No_Scenario_Rep;
11309 end Present;
11311 -------------
11312 -- Present --
11313 -------------
11315 function Present (T_Id : Target_Rep_Id) return Boolean is
11316 begin
11317 return T_Id /= No_Target_Rep;
11318 end Present;
11320 --------------------------------
11321 -- Scenario_Representation_Of --
11322 --------------------------------
11324 function Scenario_Representation_Of
11325 (N : Node_Id;
11326 In_State : Processing_In_State) return Scenario_Rep_Id
11328 S_Id : Scenario_Rep_Id;
11330 begin
11331 S_Id := NTS_Map.Get (Node_To_Scenario_Map, N);
11333 -- The elaboration scenario lacks a representation. This indicates
11334 -- that the scenario is encountered for the first time. Create the
11335 -- representation of it.
11337 if not Present (S_Id) then
11338 Scenario_Reps.Append (Create_Scenario_Rep (N, In_State));
11339 S_Id := Scenario_Reps.Last;
11341 -- Associate the internal representation with the elaboration
11342 -- scenario.
11344 NTS_Map.Put (Node_To_Scenario_Map, N, S_Id);
11345 end if;
11347 pragma Assert (Present (S_Id));
11349 return S_Id;
11350 end Scenario_Representation_Of;
11352 --------------------------------
11353 -- Set_Activated_Task_Objects --
11354 --------------------------------
11356 procedure Set_Activated_Task_Objects
11357 (S_Id : Scenario_Rep_Id;
11358 Task_Objs : NE_List.Doubly_Linked_List)
11360 pragma Assert (Present (S_Id));
11361 pragma Assert (Kind (S_Id) = Task_Activation_Scenario);
11363 begin
11364 Scenario_Reps.Table (S_Id).List_1 := Task_Objs;
11365 end Set_Activated_Task_Objects;
11367 -----------------------------
11368 -- Set_Activated_Task_Type --
11369 -----------------------------
11371 procedure Set_Activated_Task_Type
11372 (S_Id : Scenario_Rep_Id;
11373 Task_Typ : Entity_Id)
11375 pragma Assert (Present (S_Id));
11376 pragma Assert (Kind (S_Id) = Task_Activation_Scenario);
11378 begin
11379 Scenario_Reps.Table (S_Id).Field_1 := Task_Typ;
11380 end Set_Activated_Task_Type;
11382 -------------------
11383 -- SPARK_Mode_Of --
11384 -------------------
11386 function SPARK_Mode_Of
11387 (S_Id : Scenario_Rep_Id) return Extended_SPARK_Mode
11389 pragma Assert (Present (S_Id));
11390 begin
11391 return Scenario_Reps.Table (S_Id).SM;
11392 end SPARK_Mode_Of;
11394 -------------------
11395 -- SPARK_Mode_Of --
11396 -------------------
11398 function SPARK_Mode_Of
11399 (T_Id : Target_Rep_Id) return Extended_SPARK_Mode
11401 pragma Assert (Present (T_Id));
11402 begin
11403 return Target_Reps.Table (T_Id).SM;
11404 end SPARK_Mode_Of;
11406 --------------------------
11407 -- SPARK_Mode_Of_Entity --
11408 --------------------------
11410 function SPARK_Mode_Of_Entity
11411 (Id : Entity_Id) return Extended_SPARK_Mode
11413 Prag : constant Node_Id := SPARK_Pragma (Id);
11415 begin
11416 return
11417 To_SPARK_Mode
11418 (Present (Prag)
11419 and then Get_SPARK_Mode_From_Annotation (Prag) = On);
11420 end SPARK_Mode_Of_Entity;
11422 ------------------------
11423 -- SPARK_Mode_Of_Node --
11424 ------------------------
11426 function SPARK_Mode_Of_Node (N : Node_Id) return Extended_SPARK_Mode is
11427 begin
11428 return To_SPARK_Mode (Is_SPARK_Mode_On_Node (N));
11429 end SPARK_Mode_Of_Node;
11431 ----------------------
11432 -- Spec_Declaration --
11433 ----------------------
11435 function Spec_Declaration (T_Id : Target_Rep_Id) return Node_Id is
11436 pragma Assert (Present (T_Id));
11437 begin
11438 return Target_Reps.Table (T_Id).Spec_Decl;
11439 end Spec_Declaration;
11441 ------------
11442 -- Target --
11443 ------------
11445 function Target (S_Id : Scenario_Rep_Id) return Entity_Id is
11446 pragma Assert (Present (S_Id));
11447 begin
11448 return Scenario_Reps.Table (S_Id).Target;
11449 end Target;
11451 ------------------------------
11452 -- Target_Representation_Of --
11453 ------------------------------
11455 function Target_Representation_Of
11456 (Id : Entity_Id;
11457 In_State : Processing_In_State) return Target_Rep_Id
11459 T_Id : Target_Rep_Id;
11461 begin
11462 T_Id := ETT_Map.Get (Entity_To_Target_Map, Id);
11464 -- The elaboration target lacks an internal representation. This
11465 -- indicates that the target is encountered for the first time.
11466 -- Create the internal representation of it.
11468 if not Present (T_Id) then
11469 Target_Reps.Append (Create_Target_Rep (Id, In_State));
11470 T_Id := Target_Reps.Last;
11472 -- Associate the internal representation with the elaboration
11473 -- target.
11475 ETT_Map.Put (Entity_To_Target_Map, Id, T_Id);
11477 -- The Processing phase is working with a partially analyzed tree,
11478 -- where various attributes become available as analysis continues.
11479 -- This case arrises in the context of guaranteed ABE processing.
11480 -- Update the existing representation by including new attributes.
11482 elsif In_State.Representation = Inconsistent_Representation then
11483 Target_Reps.Table (T_Id) := Create_Target_Rep (Id, In_State);
11485 -- Otherwise the Processing phase imposes a particular representation
11486 -- version which is not satisfied by the target. This case arrises
11487 -- when the Processing phase switches from guaranteed ABE checks and
11488 -- diagnostics to some other mode of operation. Update the existing
11489 -- representation to include all attributes.
11491 elsif In_State.Representation /= Version (T_Id) then
11492 Target_Reps.Table (T_Id) := Create_Target_Rep (Id, In_State);
11493 end if;
11495 pragma Assert (Present (T_Id));
11497 return T_Id;
11498 end Target_Representation_Of;
11500 -------------------
11501 -- To_Ghost_Mode --
11502 -------------------
11504 function To_Ghost_Mode
11505 (Ignored_Status : Boolean) return Extended_Ghost_Mode
11507 begin
11508 if Ignored_Status then
11509 return Is_Ignored;
11510 else
11511 return Is_Checked_Or_Not_Specified;
11512 end if;
11513 end To_Ghost_Mode;
11515 -------------------
11516 -- To_SPARK_Mode --
11517 -------------------
11519 function To_SPARK_Mode
11520 (On_Status : Boolean) return Extended_SPARK_Mode
11522 begin
11523 if On_Status then
11524 return Is_On;
11525 else
11526 return Is_Off_Or_Not_Specified;
11527 end if;
11528 end To_SPARK_Mode;
11530 ----------
11531 -- Unit --
11532 ----------
11534 function Unit (T_Id : Target_Rep_Id) return Entity_Id is
11535 pragma Assert (Present (T_Id));
11536 begin
11537 return Target_Reps.Table (T_Id).Unit;
11538 end Unit;
11540 --------------------------
11541 -- Variable_Declaration --
11542 --------------------------
11544 function Variable_Declaration (T_Id : Target_Rep_Id) return Node_Id is
11545 pragma Assert (Present (T_Id));
11546 pragma Assert (Kind (T_Id) = Variable_Target);
11548 begin
11549 return Target_Reps.Table (T_Id).Field_1;
11550 end Variable_Declaration;
11552 -------------
11553 -- Version --
11554 -------------
11556 function Version (T_Id : Target_Rep_Id) return Representation_Kind is
11557 pragma Assert (Present (T_Id));
11558 begin
11559 return Target_Reps.Table (T_Id).Version;
11560 end Version;
11561 end Internal_Representation;
11563 ----------------------
11564 -- Invocation_Graph --
11565 ----------------------
11567 package body Invocation_Graph is
11569 -----------
11570 -- Types --
11571 -----------
11573 -- The following type represents simplified version of an invocation
11574 -- relation.
11576 type Invoker_Target_Relation is record
11577 Invoker : Entity_Id := Empty;
11578 Target : Entity_Id := Empty;
11579 end record;
11581 -- The following variables define the entities of the dummy elaboration
11582 -- procedures used as origins of library level paths.
11584 Elab_Body_Id : Entity_Id := Empty;
11585 Elab_Spec_Id : Entity_Id := Empty;
11587 ---------------------
11588 -- Data structures --
11589 ---------------------
11591 -- The following set contains all declared invocation constructs. It
11592 -- ensures that the same construct is not declared multiple times in
11593 -- the ALI file of the main unit.
11595 Saved_Constructs_Set : NE_Set.Membership_Set := NE_Set.Nil;
11597 function Hash (Key : Invoker_Target_Relation) return Bucket_Range_Type;
11598 -- Obtain the hash value of pair Key
11600 package IR_Set is new Membership_Sets
11601 (Element_Type => Invoker_Target_Relation,
11602 "=" => "=",
11603 Hash => Hash);
11605 -- The following set contains all recorded simple invocation relations.
11606 -- It ensures that multiple relations involving the same invoker and
11607 -- target do not appear in the ALI file of the main unit.
11609 Saved_Relations_Set : IR_Set.Membership_Set := IR_Set.Nil;
11611 --------------
11612 -- Builders --
11613 --------------
11615 function Signature_Of (Id : Entity_Id) return Invocation_Signature_Id;
11616 pragma Inline (Signature_Of);
11617 -- Obtain the invication signature id of arbitrary entity Id
11619 -----------------------
11620 -- Local subprograms --
11621 -----------------------
11623 procedure Build_Elaborate_Body_Procedure;
11624 pragma Inline (Build_Elaborate_Body_Procedure);
11625 -- Create a dummy elaborate body procedure and store its entity in
11626 -- Elab_Body_Id.
11628 procedure Build_Elaborate_Procedure
11629 (Proc_Id : out Entity_Id;
11630 Proc_Nam : Name_Id;
11631 Loc : Source_Ptr);
11632 pragma Inline (Build_Elaborate_Procedure);
11633 -- Create a dummy elaborate procedure with name Proc_Nam and source
11634 -- location Loc. The entity is returned in Proc_Id.
11636 procedure Build_Elaborate_Spec_Procedure;
11637 pragma Inline (Build_Elaborate_Spec_Procedure);
11638 -- Create a dummy elaborate spec procedure and store its entity in
11639 -- Elab_Spec_Id.
11641 function Build_Subprogram_Invocation
11642 (Subp_Id : Entity_Id) return Node_Id;
11643 pragma Inline (Build_Subprogram_Invocation);
11644 -- Create a dummy call marker that invokes subprogram Subp_Id
11646 function Build_Task_Activation
11647 (Task_Typ : Entity_Id;
11648 In_State : Processing_In_State) return Node_Id;
11649 pragma Inline (Build_Task_Activation);
11650 -- Create a dummy call marker that activates an anonymous task object of
11651 -- type Task_Typ.
11653 procedure Declare_Invocation_Construct
11654 (Constr_Id : Entity_Id;
11655 In_State : Processing_In_State);
11656 pragma Inline (Declare_Invocation_Construct);
11657 -- Declare invocation construct Constr_Id by creating a declaration for
11658 -- it in the ALI file of the main unit. In_State is the current state of
11659 -- the Processing phase.
11661 function Invocation_Graph_Recording_OK return Boolean;
11662 pragma Inline (Invocation_Graph_Recording_OK);
11663 -- Determine whether the invocation graph can be recorded
11665 function Is_Invocation_Scenario (N : Node_Id) return Boolean;
11666 pragma Inline (Is_Invocation_Scenario);
11667 -- Determine whether node N is a suitable scenario for invocation graph
11668 -- recording purposes.
11670 function Is_Invocation_Target (Id : Entity_Id) return Boolean;
11671 pragma Inline (Is_Invocation_Target);
11672 -- Determine whether arbitrary entity Id denotes an invocation target
11674 function Is_Saved_Construct (Constr : Entity_Id) return Boolean;
11675 pragma Inline (Is_Saved_Construct);
11676 -- Determine whether invocation construct Constr has already been
11677 -- declared in the ALI file of the main unit.
11679 function Is_Saved_Relation
11680 (Rel : Invoker_Target_Relation) return Boolean;
11681 pragma Inline (Is_Saved_Relation);
11682 -- Determine whether simple invocation relation Rel has already been
11683 -- recorded in the ALI file of the main unit.
11685 procedure Process_Declarations
11686 (Decls : List_Id;
11687 In_State : Processing_In_State);
11688 pragma Inline (Process_Declarations);
11689 -- Process declaration list Decls by processing all invocation scenarios
11690 -- within it.
11692 procedure Process_Freeze_Node
11693 (Fnode : Node_Id;
11694 In_State : Processing_In_State);
11695 pragma Inline (Process_Freeze_Node);
11696 -- Process freeze node Fnode by processing all invocation scenarios in
11697 -- its Actions list.
11699 procedure Process_Invocation_Activation
11700 (Call : Node_Id;
11701 Call_Rep : Scenario_Rep_Id;
11702 Obj_Id : Entity_Id;
11703 Obj_Rep : Target_Rep_Id;
11704 Task_Typ : Entity_Id;
11705 Task_Rep : Target_Rep_Id;
11706 In_State : Processing_In_State);
11707 pragma Inline (Process_Invocation_Activation);
11708 -- Process activation call Call which activates object Obj_Id of task
11709 -- type Task_Typ by processing all invocation scenarios within the task
11710 -- body. Call_Rep is the representation of the call. Obj_Rep denotes the
11711 -- representation of the object. Task_Rep is the representation of the
11712 -- task type. In_State is the current state of the Processing phase.
11714 procedure Process_Invocation_Body_Scenarios;
11715 pragma Inline (Process_Invocation_Body_Scenarios);
11716 -- Process all library level body scenarios
11718 procedure Process_Invocation_Call
11719 (Call : Node_Id;
11720 Call_Rep : Scenario_Rep_Id;
11721 In_State : Processing_In_State);
11722 pragma Inline (Process_Invocation_Call);
11723 -- Process invocation call scenario Call with representation Call_Rep.
11724 -- In_State is the current state of the Processing phase.
11726 procedure Process_Invocation_Instantiation
11727 (Inst : Node_Id;
11728 Inst_Rep : Scenario_Rep_Id;
11729 In_State : Processing_In_State);
11730 pragma Inline (Process_Invocation_Instantiation);
11731 -- Process invocation instantiation scenario Inst with representation
11732 -- Inst_Rep. In_State is the current state of the Processing phase.
11734 procedure Process_Invocation_Scenario
11735 (N : Node_Id;
11736 In_State : Processing_In_State);
11737 pragma Inline (Process_Invocation_Scenario);
11738 -- Process single invocation scenario N. In_State is the current state
11739 -- of the Processing phase.
11741 procedure Process_Invocation_Scenarios
11742 (Iter : in out NE_Set.Iterator;
11743 In_State : Processing_In_State);
11744 pragma Inline (Process_Invocation_Scenarios);
11745 -- Process all invocation scenarios obtained via iterator Iter. In_State
11746 -- is the current state of the Processing phase.
11748 procedure Process_Invocation_Spec_Scenarios;
11749 pragma Inline (Process_Invocation_Spec_Scenarios);
11750 -- Process all library level spec scenarios
11752 procedure Process_Main_Unit;
11753 pragma Inline (Process_Main_Unit);
11754 -- Process all invocation scenarios within the main unit
11756 procedure Process_Package_Declaration
11757 (Pack_Decl : Node_Id;
11758 In_State : Processing_In_State);
11759 pragma Inline (Process_Package_Declaration);
11760 -- Process package declaration Pack_Decl by processing all invocation
11761 -- scenarios in its visible and private declarations. If the main unit
11762 -- contains a generic, the declarations of the body are also examined.
11763 -- In_State is the current state of the Processing phase.
11765 procedure Process_Protected_Type_Declaration
11766 (Prot_Decl : Node_Id;
11767 In_State : Processing_In_State);
11768 pragma Inline (Process_Protected_Type_Declaration);
11769 -- Process the declarations of protected type Prot_Decl. In_State is the
11770 -- current state of the Processing phase.
11772 procedure Process_Subprogram_Declaration
11773 (Subp_Decl : Node_Id;
11774 In_State : Processing_In_State);
11775 pragma Inline (Process_Subprogram_Declaration);
11776 -- Process subprogram declaration Subp_Decl by processing all invocation
11777 -- scenarios within its body. In_State denotes the current state of the
11778 -- Processing phase.
11780 procedure Process_Subprogram_Instantiation
11781 (Inst : Node_Id;
11782 In_State : Processing_In_State);
11783 pragma Inline (Process_Subprogram_Instantiation);
11784 -- Process subprogram instantiation Inst. In_State is the current state
11785 -- of the Processing phase.
11787 procedure Process_Task_Type_Declaration
11788 (Task_Decl : Node_Id;
11789 In_State : Processing_In_State);
11790 pragma Inline (Process_Task_Type_Declaration);
11791 -- Process task declaration Task_Decl by processing all invocation
11792 -- scenarios within its body. In_State is the current state of the
11793 -- Processing phase.
11795 procedure Record_Full_Invocation_Path (In_State : Processing_In_State);
11796 pragma Inline (Record_Full_Invocation_Path);
11797 -- Record all relations between scenario pairs found in the stack of
11798 -- active scenarios. In_State is the current state of the Processing
11799 -- phase.
11801 procedure Record_Invocation_Graph_Encoding;
11802 pragma Inline (Record_Invocation_Graph_Encoding);
11803 -- Record the encoding format used to capture information related to
11804 -- invocation constructs and relations.
11806 procedure Record_Invocation_Path (In_State : Processing_In_State);
11807 pragma Inline (Record_Invocation_Path);
11808 -- Record the invocation relations found within the path represented in
11809 -- the active scenario stack. In_State denotes the current state of the
11810 -- Processing phase.
11812 procedure Record_Simple_Invocation_Path (In_State : Processing_In_State);
11813 pragma Inline (Record_Simple_Invocation_Path);
11814 -- Record a single relation from the start to the end of the stack of
11815 -- active scenarios. In_State is the current state of the Processing
11816 -- phase.
11818 procedure Record_Invocation_Relation
11819 (Invk_Id : Entity_Id;
11820 Targ_Id : Entity_Id;
11821 In_State : Processing_In_State);
11822 pragma Inline (Record_Invocation_Relation);
11823 -- Record an invocation relation with invoker Invk_Id and target Targ_Id
11824 -- by creating an entry for it in the ALI file of the main unit. Formal
11825 -- In_State denotes the current state of the Processing phase.
11827 procedure Set_Is_Saved_Construct (Constr : Entity_Id);
11828 pragma Inline (Set_Is_Saved_Construct);
11829 -- Mark invocation construct Constr as declared in the ALI file of the
11830 -- main unit.
11832 procedure Set_Is_Saved_Relation (Rel : Invoker_Target_Relation);
11833 pragma Inline (Set_Is_Saved_Relation);
11834 -- Mark simple invocation relation Rel as recorded in the ALI file of
11835 -- the main unit.
11837 function Target_Of
11838 (Pos : Active_Scenario_Pos;
11839 In_State : Processing_In_State) return Entity_Id;
11840 pragma Inline (Target_Of);
11841 -- Given position within the active scenario stack Pos, obtain the
11842 -- target of the indicated scenario. In_State is the current state
11843 -- of the Processing phase.
11845 procedure Traverse_Invocation_Body
11846 (N : Node_Id;
11847 In_State : Processing_In_State);
11848 pragma Inline (Traverse_Invocation_Body);
11849 -- Traverse subprogram body N looking for suitable invocation scenarios
11850 -- that need to be processed for invocation graph recording purposes.
11851 -- In_State is the current state of the Processing phase.
11853 procedure Write_Invocation_Path (In_State : Processing_In_State);
11854 pragma Inline (Write_Invocation_Path);
11855 -- Write out a path represented by the active scenario on the stack to
11856 -- standard output. In_State denotes the current state of the Processing
11857 -- phase.
11859 ------------------------------------
11860 -- Build_Elaborate_Body_Procedure --
11861 ------------------------------------
11863 procedure Build_Elaborate_Body_Procedure is
11864 Body_Decl : Node_Id;
11865 Spec_Decl : Node_Id;
11867 begin
11868 -- Nothing to do when a previous call already created the procedure
11870 if Present (Elab_Body_Id) then
11871 return;
11872 end if;
11874 Spec_And_Body_From_Entity
11875 (Id => Main_Unit_Entity,
11876 Body_Decl => Body_Decl,
11877 Spec_Decl => Spec_Decl);
11879 pragma Assert (Present (Body_Decl));
11881 Build_Elaborate_Procedure
11882 (Proc_Id => Elab_Body_Id,
11883 Proc_Nam => Name_B,
11884 Loc => Sloc (Body_Decl));
11885 end Build_Elaborate_Body_Procedure;
11887 -------------------------------
11888 -- Build_Elaborate_Procedure --
11889 -------------------------------
11891 procedure Build_Elaborate_Procedure
11892 (Proc_Id : out Entity_Id;
11893 Proc_Nam : Name_Id;
11894 Loc : Source_Ptr)
11896 Proc_Decl : Node_Id;
11897 pragma Unreferenced (Proc_Decl);
11899 begin
11900 Proc_Id := Make_Defining_Identifier (Loc, Proc_Nam);
11902 -- Partially decorate the elaboration procedure because it will not
11903 -- be insertred into the tree and analyzed.
11905 Mutate_Ekind (Proc_Id, E_Procedure);
11906 Set_Etype (Proc_Id, Standard_Void_Type);
11907 Set_Scope (Proc_Id, Unique_Entity (Main_Unit_Entity));
11909 -- Create a dummy declaration for the elaboration procedure. The
11910 -- declaration does not need to be syntactically legal, but must
11911 -- carry an accurate source location.
11913 Proc_Decl :=
11914 Make_Subprogram_Body (Loc,
11915 Specification =>
11916 Make_Procedure_Specification (Loc,
11917 Defining_Unit_Name => Proc_Id),
11918 Declarations => No_List,
11919 Handled_Statement_Sequence => Empty);
11920 end Build_Elaborate_Procedure;
11922 ------------------------------------
11923 -- Build_Elaborate_Spec_Procedure --
11924 ------------------------------------
11926 procedure Build_Elaborate_Spec_Procedure is
11927 Body_Decl : Node_Id;
11928 Spec_Decl : Node_Id;
11930 begin
11931 -- Nothing to do when a previous call already created the procedure
11933 if Present (Elab_Spec_Id) then
11934 return;
11935 end if;
11937 Spec_And_Body_From_Entity
11938 (Id => Main_Unit_Entity,
11939 Body_Decl => Body_Decl,
11940 Spec_Decl => Spec_Decl);
11942 pragma Assert (Present (Spec_Decl));
11944 Build_Elaborate_Procedure
11945 (Proc_Id => Elab_Spec_Id,
11946 Proc_Nam => Name_S,
11947 Loc => Sloc (Spec_Decl));
11948 end Build_Elaborate_Spec_Procedure;
11950 ---------------------------------
11951 -- Build_Subprogram_Invocation --
11952 ---------------------------------
11954 function Build_Subprogram_Invocation
11955 (Subp_Id : Entity_Id) return Node_Id
11957 Marker : constant Node_Id := Make_Call_Marker (Sloc (Subp_Id));
11958 Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id);
11960 begin
11961 -- Create a dummy call marker which invokes the subprogram
11963 Set_Is_Declaration_Level_Node (Marker, False);
11964 Set_Is_Dispatching_Call (Marker, False);
11965 Set_Is_Elaboration_Checks_OK_Node (Marker, False);
11966 Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
11967 Set_Is_Ignored_Ghost_Node (Marker, False);
11968 Set_Is_Preelaborable_Call (Marker, False);
11969 Set_Is_Source_Call (Marker, False);
11970 Set_Is_SPARK_Mode_On_Node (Marker, False);
11972 -- Invoke the uniform canonical entity of the subprogram
11974 Set_Target (Marker, Canonical_Subprogram (Subp_Id));
11976 -- Partially insert the marker into the tree
11978 Set_Parent (Marker, Parent (Subp_Decl));
11980 return Marker;
11981 end Build_Subprogram_Invocation;
11983 ---------------------------
11984 -- Build_Task_Activation --
11985 ---------------------------
11987 function Build_Task_Activation
11988 (Task_Typ : Entity_Id;
11989 In_State : Processing_In_State) return Node_Id
11991 Loc : constant Source_Ptr := Sloc (Task_Typ);
11992 Marker : constant Node_Id := Make_Call_Marker (Loc);
11993 Task_Decl : constant Node_Id := Unit_Declaration_Node (Task_Typ);
11995 Activ_Id : Entity_Id;
11996 Marker_Rep_Id : Scenario_Rep_Id;
11997 Task_Obj : Entity_Id;
11998 Task_Objs : NE_List.Doubly_Linked_List;
12000 begin
12001 -- Create a dummy call marker which activates some tasks
12003 Set_Is_Declaration_Level_Node (Marker, False);
12004 Set_Is_Dispatching_Call (Marker, False);
12005 Set_Is_Elaboration_Checks_OK_Node (Marker, False);
12006 Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
12007 Set_Is_Ignored_Ghost_Node (Marker, False);
12008 Set_Is_Preelaborable_Call (Marker, False);
12009 Set_Is_Source_Call (Marker, False);
12010 Set_Is_SPARK_Mode_On_Node (Marker, False);
12012 -- Invoke the appropriate version of Activate_Tasks
12014 if Restricted_Profile then
12015 Activ_Id := RTE (RE_Activate_Restricted_Tasks);
12016 else
12017 Activ_Id := RTE (RE_Activate_Tasks);
12018 end if;
12020 Set_Target (Marker, Activ_Id);
12022 -- Partially insert the marker into the tree
12024 Set_Parent (Marker, Parent (Task_Decl));
12026 -- Create a dummy task object. Partially decorate the object because
12027 -- it will not be inserted into the tree and analyzed.
12029 Task_Obj := Make_Temporary (Loc, 'T');
12030 Mutate_Ekind (Task_Obj, E_Variable);
12031 Set_Etype (Task_Obj, Task_Typ);
12033 -- Associate the dummy task object with the activation call
12035 Task_Objs := NE_List.Create;
12036 NE_List.Append (Task_Objs, Task_Obj);
12038 Marker_Rep_Id := Scenario_Representation_Of (Marker, In_State);
12039 Set_Activated_Task_Objects (Marker_Rep_Id, Task_Objs);
12040 Set_Activated_Task_Type (Marker_Rep_Id, Task_Typ);
12042 return Marker;
12043 end Build_Task_Activation;
12045 ----------------------------------
12046 -- Declare_Invocation_Construct --
12047 ----------------------------------
12049 procedure Declare_Invocation_Construct
12050 (Constr_Id : Entity_Id;
12051 In_State : Processing_In_State)
12053 function Body_Placement_Of
12054 (Id : Entity_Id) return Declaration_Placement_Kind;
12055 pragma Inline (Body_Placement_Of);
12056 -- Obtain the placement of arbitrary entity Id's body
12058 function Declaration_Placement_Of_Node
12059 (N : Node_Id) return Declaration_Placement_Kind;
12060 pragma Inline (Declaration_Placement_Of_Node);
12061 -- Obtain the placement of arbitrary node N
12063 function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind;
12064 pragma Inline (Kind_Of);
12065 -- Obtain the invocation construct kind of arbitrary entity Id
12067 function Spec_Placement_Of
12068 (Id : Entity_Id) return Declaration_Placement_Kind;
12069 pragma Inline (Spec_Placement_Of);
12070 -- Obtain the placement of arbitrary entity Id's spec
12072 -----------------------
12073 -- Body_Placement_Of --
12074 -----------------------
12076 function Body_Placement_Of
12077 (Id : Entity_Id) return Declaration_Placement_Kind
12079 Id_Rep : constant Target_Rep_Id :=
12080 Target_Representation_Of (Id, In_State);
12081 Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
12082 Spec_Decl : constant Node_Id := Spec_Declaration (Id_Rep);
12084 begin
12085 -- The entity has a body
12087 if Present (Body_Decl) then
12088 return Declaration_Placement_Of_Node (Body_Decl);
12090 -- Otherwise the entity must have a spec
12092 else
12093 pragma Assert (Present (Spec_Decl));
12094 return Declaration_Placement_Of_Node (Spec_Decl);
12095 end if;
12096 end Body_Placement_Of;
12098 -----------------------------------
12099 -- Declaration_Placement_Of_Node --
12100 -----------------------------------
12102 function Declaration_Placement_Of_Node
12103 (N : Node_Id) return Declaration_Placement_Kind
12105 Main_Unit_Id : constant Entity_Id := Main_Unit_Entity;
12106 N_Unit_Id : constant Entity_Id := Find_Top_Unit (N);
12108 begin
12109 -- The node is in the main unit, its placement depends on the main
12110 -- unit kind.
12112 if N_Unit_Id = Main_Unit_Id then
12114 -- The main unit is a body
12116 if Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
12117 then
12118 return In_Body;
12120 -- The main unit is a stand-alone subprogram body
12122 elsif Ekind (Main_Unit_Id) in E_Function | E_Procedure
12123 and then Nkind (Unit_Declaration_Node (Main_Unit_Id)) =
12124 N_Subprogram_Body
12125 then
12126 return In_Body;
12128 -- Otherwise the main unit is a spec
12130 else
12131 return In_Spec;
12132 end if;
12134 -- Otherwise the node is in the complementary unit of the main
12135 -- unit. The main unit is a body, the node is in the spec.
12137 elsif Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
12138 then
12139 return In_Spec;
12141 -- The main unit is a spec, the node is in the body
12143 else
12144 return In_Body;
12145 end if;
12146 end Declaration_Placement_Of_Node;
12148 -------------
12149 -- Kind_Of --
12150 -------------
12152 function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind is
12153 begin
12154 if Id = Elab_Body_Id then
12155 return Elaborate_Body_Procedure;
12157 elsif Id = Elab_Spec_Id then
12158 return Elaborate_Spec_Procedure;
12160 else
12161 return Regular_Construct;
12162 end if;
12163 end Kind_Of;
12165 -----------------------
12166 -- Spec_Placement_Of --
12167 -----------------------
12169 function Spec_Placement_Of
12170 (Id : Entity_Id) return Declaration_Placement_Kind
12172 Id_Rep : constant Target_Rep_Id :=
12173 Target_Representation_Of (Id, In_State);
12174 Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
12175 Spec_Decl : constant Node_Id := Spec_Declaration (Id_Rep);
12177 begin
12178 -- The entity has a spec
12180 if Present (Spec_Decl) then
12181 return Declaration_Placement_Of_Node (Spec_Decl);
12183 -- Otherwise the entity must have a body
12185 else
12186 pragma Assert (Present (Body_Decl));
12187 return Declaration_Placement_Of_Node (Body_Decl);
12188 end if;
12189 end Spec_Placement_Of;
12191 -- Start of processing for Declare_Invocation_Construct
12193 begin
12194 -- Nothing to do when the construct has already been declared in the
12195 -- ALI file.
12197 if Is_Saved_Construct (Constr_Id) then
12198 return;
12199 end if;
12201 -- Mark the construct as declared in the ALI file
12203 Set_Is_Saved_Construct (Constr_Id);
12205 -- Add the construct in the ALI file
12207 Add_Invocation_Construct
12208 (Body_Placement => Body_Placement_Of (Constr_Id),
12209 Kind => Kind_Of (Constr_Id),
12210 Signature => Signature_Of (Constr_Id),
12211 Spec_Placement => Spec_Placement_Of (Constr_Id),
12212 Update_Units => False);
12213 end Declare_Invocation_Construct;
12215 -------------------------------
12216 -- Finalize_Invocation_Graph --
12217 -------------------------------
12219 procedure Finalize_Invocation_Graph is
12220 begin
12221 NE_Set.Destroy (Saved_Constructs_Set);
12222 IR_Set.Destroy (Saved_Relations_Set);
12223 end Finalize_Invocation_Graph;
12225 ----------
12226 -- Hash --
12227 ----------
12229 function Hash (Key : Invoker_Target_Relation) return Bucket_Range_Type is
12230 pragma Assert (Present (Key.Invoker));
12231 pragma Assert (Present (Key.Target));
12233 begin
12234 return
12235 Hash_Two_Keys
12236 (Bucket_Range_Type (Key.Invoker),
12237 Bucket_Range_Type (Key.Target));
12238 end Hash;
12240 ---------------------------------
12241 -- Initialize_Invocation_Graph --
12242 ---------------------------------
12244 procedure Initialize_Invocation_Graph is
12245 begin
12246 Saved_Constructs_Set := NE_Set.Create (100);
12247 Saved_Relations_Set := IR_Set.Create (200);
12248 end Initialize_Invocation_Graph;
12250 -----------------------------------
12251 -- Invocation_Graph_Recording_OK --
12252 -----------------------------------
12254 function Invocation_Graph_Recording_OK return Boolean is
12255 Main_Cunit : constant Node_Id := Cunit (Main_Unit);
12257 begin
12258 -- Nothing to do when compiling for GNATprove because the invocation
12259 -- graph is not needed.
12261 if GNATprove_Mode then
12262 return False;
12264 -- Nothing to do when the compilation will not produce an ALI file
12266 elsif Serious_Errors_Detected > 0 then
12267 return False;
12269 -- Nothing to do when the main unit requires a body. Processing the
12270 -- completing body will create the ALI file for the unit and record
12271 -- the invocation graph.
12273 elsif Body_Required (Main_Cunit) then
12274 return False;
12275 end if;
12277 return True;
12278 end Invocation_Graph_Recording_OK;
12280 ----------------------------
12281 -- Is_Invocation_Scenario --
12282 ----------------------------
12284 function Is_Invocation_Scenario (N : Node_Id) return Boolean is
12285 begin
12286 return
12287 Is_Suitable_Access_Taken (N)
12288 or else Is_Suitable_Call (N)
12289 or else Is_Suitable_Instantiation (N);
12290 end Is_Invocation_Scenario;
12292 --------------------------
12293 -- Is_Invocation_Target --
12294 --------------------------
12296 function Is_Invocation_Target (Id : Entity_Id) return Boolean is
12297 begin
12298 -- To qualify, the entity must either come from source, or denote an
12299 -- Ada, bridge, or SPARK target.
12301 return
12302 Comes_From_Source (Id)
12303 or else Is_Ada_Semantic_Target (Id)
12304 or else Is_Bridge_Target (Id)
12305 or else Is_SPARK_Semantic_Target (Id);
12306 end Is_Invocation_Target;
12308 ------------------------
12309 -- Is_Saved_Construct --
12310 ------------------------
12312 function Is_Saved_Construct (Constr : Entity_Id) return Boolean is
12313 pragma Assert (Present (Constr));
12314 begin
12315 return NE_Set.Contains (Saved_Constructs_Set, Constr);
12316 end Is_Saved_Construct;
12318 -----------------------
12319 -- Is_Saved_Relation --
12320 -----------------------
12322 function Is_Saved_Relation
12323 (Rel : Invoker_Target_Relation) return Boolean
12325 pragma Assert (Present (Rel.Invoker));
12326 pragma Assert (Present (Rel.Target));
12328 begin
12329 return IR_Set.Contains (Saved_Relations_Set, Rel);
12330 end Is_Saved_Relation;
12332 --------------------------
12333 -- Process_Declarations --
12334 --------------------------
12336 procedure Process_Declarations
12337 (Decls : List_Id;
12338 In_State : Processing_In_State)
12340 Decl : Node_Id;
12342 begin
12343 Decl := First (Decls);
12344 while Present (Decl) loop
12346 -- Freeze node
12348 if Nkind (Decl) = N_Freeze_Entity then
12349 Process_Freeze_Node
12350 (Fnode => Decl,
12351 In_State => In_State);
12353 -- Package (nested)
12355 elsif Nkind (Decl) = N_Package_Declaration then
12356 Process_Package_Declaration
12357 (Pack_Decl => Decl,
12358 In_State => In_State);
12360 -- Protected type
12362 elsif Nkind (Decl) in N_Protected_Type_Declaration
12363 | N_Single_Protected_Declaration
12364 then
12365 Process_Protected_Type_Declaration
12366 (Prot_Decl => Decl,
12367 In_State => In_State);
12369 -- Subprogram or entry
12371 elsif Nkind (Decl) in N_Entry_Declaration
12372 | N_Subprogram_Declaration
12373 then
12374 Process_Subprogram_Declaration
12375 (Subp_Decl => Decl,
12376 In_State => In_State);
12378 -- Subprogram body (stand alone)
12380 elsif Nkind (Decl) = N_Subprogram_Body
12381 and then No (Corresponding_Spec (Decl))
12382 then
12383 Process_Subprogram_Declaration
12384 (Subp_Decl => Decl,
12385 In_State => In_State);
12387 -- Subprogram instantiation
12389 elsif Nkind (Decl) in N_Subprogram_Instantiation then
12390 Process_Subprogram_Instantiation
12391 (Inst => Decl,
12392 In_State => In_State);
12394 -- Task type
12396 elsif Nkind (Decl) in N_Single_Task_Declaration
12397 | N_Task_Type_Declaration
12398 then
12399 Process_Task_Type_Declaration
12400 (Task_Decl => Decl,
12401 In_State => In_State);
12403 -- Task type (derived)
12405 elsif Nkind (Decl) = N_Full_Type_Declaration
12406 and then Is_Task_Type (Defining_Entity (Decl))
12407 then
12408 Process_Task_Type_Declaration
12409 (Task_Decl => Decl,
12410 In_State => In_State);
12411 end if;
12413 Next (Decl);
12414 end loop;
12415 end Process_Declarations;
12417 -------------------------
12418 -- Process_Freeze_Node --
12419 -------------------------
12421 procedure Process_Freeze_Node
12422 (Fnode : Node_Id;
12423 In_State : Processing_In_State)
12425 begin
12426 Process_Declarations
12427 (Decls => Actions (Fnode),
12428 In_State => In_State);
12429 end Process_Freeze_Node;
12431 -----------------------------------
12432 -- Process_Invocation_Activation --
12433 -----------------------------------
12435 procedure Process_Invocation_Activation
12436 (Call : Node_Id;
12437 Call_Rep : Scenario_Rep_Id;
12438 Obj_Id : Entity_Id;
12439 Obj_Rep : Target_Rep_Id;
12440 Task_Typ : Entity_Id;
12441 Task_Rep : Target_Rep_Id;
12442 In_State : Processing_In_State)
12444 pragma Unreferenced (Call);
12445 pragma Unreferenced (Call_Rep);
12446 pragma Unreferenced (Obj_Id);
12447 pragma Unreferenced (Obj_Rep);
12449 begin
12450 -- Nothing to do when the task type appears within an internal unit
12452 if In_Internal_Unit (Task_Typ) then
12453 return;
12454 end if;
12456 -- The task type being activated is within the main unit. Extend the
12457 -- DFS traversal into its body.
12459 if In_Extended_Main_Code_Unit (Task_Typ) then
12460 Traverse_Invocation_Body
12461 (N => Body_Declaration (Task_Rep),
12462 In_State => In_State);
12464 -- The task type being activated resides within an external unit
12466 -- Main unit External unit
12467 -- +-----------+ +-------------+
12468 -- | | | |
12469 -- | Start ------------> Task_Typ |
12470 -- | | | |
12471 -- +-----------+ +-------------+
12473 -- Record the invocation path which originates from Start and reaches
12474 -- the task type.
12476 else
12477 Record_Invocation_Path (In_State);
12478 end if;
12479 end Process_Invocation_Activation;
12481 ---------------------------------------
12482 -- Process_Invocation_Body_Scenarios --
12483 ---------------------------------------
12485 procedure Process_Invocation_Body_Scenarios is
12486 Iter : NE_Set.Iterator := Iterate_Library_Body_Scenarios;
12487 begin
12488 Process_Invocation_Scenarios
12489 (Iter => Iter,
12490 In_State => Invocation_Body_State);
12491 end Process_Invocation_Body_Scenarios;
12493 -----------------------------
12494 -- Process_Invocation_Call --
12495 -----------------------------
12497 procedure Process_Invocation_Call
12498 (Call : Node_Id;
12499 Call_Rep : Scenario_Rep_Id;
12500 In_State : Processing_In_State)
12502 pragma Unreferenced (Call);
12504 Subp_Id : constant Entity_Id := Target (Call_Rep);
12505 Subp_Rep : constant Target_Rep_Id :=
12506 Target_Representation_Of (Subp_Id, In_State);
12508 begin
12509 -- Nothing to do when the subprogram appears within an internal unit
12511 if In_Internal_Unit (Subp_Id) then
12512 return;
12514 -- Nothing to do for an abstract subprogram because it has no body to
12515 -- examine.
12517 elsif Ekind (Subp_Id) in E_Function | E_Procedure
12518 and then Is_Abstract_Subprogram (Subp_Id)
12519 then
12520 return;
12522 -- Nothin to do for a formal subprogram because it has no body to
12523 -- examine.
12525 elsif Is_Formal_Subprogram (Subp_Id) then
12526 return;
12527 end if;
12529 -- The subprogram being called is within the main unit. Extend the
12530 -- DFS traversal into its barrier function and body.
12532 if In_Extended_Main_Code_Unit (Subp_Id) then
12533 if Ekind (Subp_Id) in E_Entry | E_Entry_Family | E_Procedure then
12534 Traverse_Invocation_Body
12535 (N => Barrier_Body_Declaration (Subp_Rep),
12536 In_State => In_State);
12537 end if;
12539 Traverse_Invocation_Body
12540 (N => Body_Declaration (Subp_Rep),
12541 In_State => In_State);
12543 -- The subprogram being called resides within an external unit
12545 -- Main unit External unit
12546 -- +-----------+ +-------------+
12547 -- | | | |
12548 -- | Start ------------> Subp_Id |
12549 -- | | | |
12550 -- +-----------+ +-------------+
12552 -- Record the invocation path which originates from Start and reaches
12553 -- the subprogram.
12555 else
12556 Record_Invocation_Path (In_State);
12557 end if;
12558 end Process_Invocation_Call;
12560 --------------------------------------
12561 -- Process_Invocation_Instantiation --
12562 --------------------------------------
12564 procedure Process_Invocation_Instantiation
12565 (Inst : Node_Id;
12566 Inst_Rep : Scenario_Rep_Id;
12567 In_State : Processing_In_State)
12569 pragma Unreferenced (Inst);
12571 Gen_Id : constant Entity_Id := Target (Inst_Rep);
12573 begin
12574 -- Nothing to do when the generic appears within an internal unit
12576 if In_Internal_Unit (Gen_Id) then
12577 return;
12578 end if;
12580 -- The generic being instantiated resides within an external unit
12582 -- Main unit External unit
12583 -- +-----------+ +-------------+
12584 -- | | | |
12585 -- | Start ------------> Generic |
12586 -- | | | |
12587 -- +-----------+ +-------------+
12589 -- Record the invocation path which originates from Start and reaches
12590 -- the generic.
12592 if not In_Extended_Main_Code_Unit (Gen_Id) then
12593 Record_Invocation_Path (In_State);
12594 end if;
12595 end Process_Invocation_Instantiation;
12597 ---------------------------------
12598 -- Process_Invocation_Scenario --
12599 ---------------------------------
12601 procedure Process_Invocation_Scenario
12602 (N : Node_Id;
12603 In_State : Processing_In_State)
12605 Scen : constant Node_Id := Scenario (N);
12606 Scen_Rep : Scenario_Rep_Id;
12608 begin
12609 -- Add the current scenario to the stack of active scenarios
12611 Push_Active_Scenario (Scen);
12613 -- Call or task activation
12615 if Is_Suitable_Call (Scen) then
12616 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
12618 -- Routine Build_Call_Marker creates call markers regardless of
12619 -- whether the call occurs within the main unit or not. This way
12620 -- the serialization of internal names is kept consistent. Only
12621 -- call markers found within the main unit must be processed.
12623 if In_Main_Context (Scen) then
12624 Scen_Rep := Scenario_Representation_Of (Scen, In_State);
12626 if Kind (Scen_Rep) = Call_Scenario then
12627 Process_Invocation_Call
12628 (Call => Scen,
12629 Call_Rep => Scen_Rep,
12630 In_State => In_State);
12632 else
12633 pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);
12635 Process_Activation
12636 (Call => Scen,
12637 Call_Rep => Scen_Rep,
12638 Processor => Process_Invocation_Activation'Access,
12639 In_State => In_State);
12640 end if;
12641 end if;
12643 -- Instantiation
12645 elsif Is_Suitable_Instantiation (Scen) then
12646 Process_Invocation_Instantiation
12647 (Inst => Scen,
12648 Inst_Rep => Scenario_Representation_Of (Scen, In_State),
12649 In_State => In_State);
12650 end if;
12652 -- Remove the current scenario from the stack of active scenarios
12653 -- once all invocation constructs and paths have been saved.
12655 Pop_Active_Scenario (Scen);
12656 end Process_Invocation_Scenario;
12658 ----------------------------------
12659 -- Process_Invocation_Scenarios --
12660 ----------------------------------
12662 procedure Process_Invocation_Scenarios
12663 (Iter : in out NE_Set.Iterator;
12664 In_State : Processing_In_State)
12666 N : Node_Id;
12668 begin
12669 while NE_Set.Has_Next (Iter) loop
12670 NE_Set.Next (Iter, N);
12672 -- Reset the traversed status of all subprogram bodies because the
12673 -- current invocation scenario acts as a new DFS traversal root.
12675 Reset_Traversed_Bodies;
12677 Process_Invocation_Scenario (N, In_State);
12678 end loop;
12679 end Process_Invocation_Scenarios;
12681 ---------------------------------------
12682 -- Process_Invocation_Spec_Scenarios --
12683 ---------------------------------------
12685 procedure Process_Invocation_Spec_Scenarios is
12686 Iter : NE_Set.Iterator := Iterate_Library_Spec_Scenarios;
12687 begin
12688 Process_Invocation_Scenarios
12689 (Iter => Iter,
12690 In_State => Invocation_Spec_State);
12691 end Process_Invocation_Spec_Scenarios;
12693 -----------------------
12694 -- Process_Main_Unit --
12695 -----------------------
12697 procedure Process_Main_Unit is
12698 Unit_Decl : constant Node_Id := Unit (Cunit (Main_Unit));
12699 Spec_Id : Entity_Id;
12701 begin
12702 -- The main unit is a [generic] package body
12704 if Nkind (Unit_Decl) = N_Package_Body then
12705 Spec_Id := Corresponding_Spec (Unit_Decl);
12706 pragma Assert (Present (Spec_Id));
12708 Process_Package_Declaration
12709 (Pack_Decl => Unit_Declaration_Node (Spec_Id),
12710 In_State => Invocation_Construct_State);
12712 -- The main unit is a [generic] package declaration
12714 elsif Nkind (Unit_Decl) = N_Package_Declaration then
12715 Process_Package_Declaration
12716 (Pack_Decl => Unit_Decl,
12717 In_State => Invocation_Construct_State);
12719 -- The main unit is a [generic] subprogram body
12721 elsif Nkind (Unit_Decl) = N_Subprogram_Body then
12722 Spec_Id := Corresponding_Spec (Unit_Decl);
12724 -- The body completes a previous declaration
12726 if Present (Spec_Id) then
12727 Process_Subprogram_Declaration
12728 (Subp_Decl => Unit_Declaration_Node (Spec_Id),
12729 In_State => Invocation_Construct_State);
12731 -- Otherwise the body is stand-alone
12733 else
12734 Process_Subprogram_Declaration
12735 (Subp_Decl => Unit_Decl,
12736 In_State => Invocation_Construct_State);
12737 end if;
12739 -- The main unit is a subprogram instantiation
12741 elsif Nkind (Unit_Decl) in N_Subprogram_Instantiation then
12742 Process_Subprogram_Instantiation
12743 (Inst => Unit_Decl,
12744 In_State => Invocation_Construct_State);
12746 -- The main unit is an imported subprogram declaration
12748 elsif Nkind (Unit_Decl) = N_Subprogram_Declaration then
12749 Process_Subprogram_Declaration
12750 (Subp_Decl => Unit_Decl,
12751 In_State => Invocation_Construct_State);
12752 end if;
12753 end Process_Main_Unit;
12755 ---------------------------------
12756 -- Process_Package_Declaration --
12757 ---------------------------------
12759 procedure Process_Package_Declaration
12760 (Pack_Decl : Node_Id;
12761 In_State : Processing_In_State)
12763 Body_Id : constant Entity_Id := Corresponding_Body (Pack_Decl);
12764 Spec : constant Node_Id := Specification (Pack_Decl);
12765 Spec_Id : constant Entity_Id := Defining_Entity (Pack_Decl);
12767 begin
12768 -- Add a declaration for the generic package in the ALI of the main
12769 -- unit in case a client unit instantiates it.
12771 if Ekind (Spec_Id) = E_Generic_Package then
12772 Declare_Invocation_Construct
12773 (Constr_Id => Spec_Id,
12774 In_State => In_State);
12776 -- Otherwise inspect the visible and private declarations of the
12777 -- package for invocation constructs.
12779 else
12780 Process_Declarations
12781 (Decls => Visible_Declarations (Spec),
12782 In_State => In_State);
12784 Process_Declarations
12785 (Decls => Private_Declarations (Spec),
12786 In_State => In_State);
12788 -- The package body containst at least one generic unit or an
12789 -- inlinable subprogram. Such constructs may grant clients of
12790 -- the main unit access to the private enclosing contexts of
12791 -- the constructs. Process the main unit body to discover and
12792 -- encode relevant invocation constructs and relations that
12793 -- may ultimately reach an external unit.
12795 if Present (Body_Id)
12796 and then Save_Invocation_Graph_Of_Body (Cunit (Main_Unit))
12797 then
12798 Process_Declarations
12799 (Decls => Declarations (Unit_Declaration_Node (Body_Id)),
12800 In_State => In_State);
12801 end if;
12802 end if;
12803 end Process_Package_Declaration;
12805 ----------------------------------------
12806 -- Process_Protected_Type_Declaration --
12807 ----------------------------------------
12809 procedure Process_Protected_Type_Declaration
12810 (Prot_Decl : Node_Id;
12811 In_State : Processing_In_State)
12813 Prot_Def : constant Node_Id := Protected_Definition (Prot_Decl);
12815 begin
12816 if Present (Prot_Def) then
12817 Process_Declarations
12818 (Decls => Visible_Declarations (Prot_Def),
12819 In_State => In_State);
12820 end if;
12821 end Process_Protected_Type_Declaration;
12823 ------------------------------------
12824 -- Process_Subprogram_Declaration --
12825 ------------------------------------
12827 procedure Process_Subprogram_Declaration
12828 (Subp_Decl : Node_Id;
12829 In_State : Processing_In_State)
12831 Subp_Id : constant Entity_Id := Defining_Entity (Subp_Decl);
12833 begin
12834 -- Nothing to do when the subprogram is not an invocation target
12836 if not Is_Invocation_Target (Subp_Id) then
12837 return;
12838 end if;
12840 -- Add a declaration for the subprogram in the ALI file of the main
12841 -- unit in case a client unit calls or instantiates it.
12843 Declare_Invocation_Construct
12844 (Constr_Id => Subp_Id,
12845 In_State => In_State);
12847 -- Do not process subprograms without a body because they do not
12848 -- contain any invocation scenarios.
12850 if Is_Bodiless_Subprogram (Subp_Id) then
12851 null;
12853 -- Do not process generic subprograms because generics must not be
12854 -- examined.
12856 elsif Is_Generic_Subprogram (Subp_Id) then
12857 null;
12859 -- Otherwise create a dummy scenario which calls the subprogram to
12860 -- act as a root for a DFS traversal.
12862 else
12863 -- Reset the traversed status of all subprogram bodies because the
12864 -- subprogram acts as a new DFS traversal root.
12866 Reset_Traversed_Bodies;
12868 Process_Invocation_Scenario
12869 (N => Build_Subprogram_Invocation (Subp_Id),
12870 In_State => In_State);
12871 end if;
12872 end Process_Subprogram_Declaration;
12874 --------------------------------------
12875 -- Process_Subprogram_Instantiation --
12876 --------------------------------------
12878 procedure Process_Subprogram_Instantiation
12879 (Inst : Node_Id;
12880 In_State : Processing_In_State)
12882 begin
12883 -- Add a declaration for the instantiation in the ALI file of the
12884 -- main unit in case a client unit calls it.
12886 Declare_Invocation_Construct
12887 (Constr_Id => Defining_Entity (Inst),
12888 In_State => In_State);
12889 end Process_Subprogram_Instantiation;
12891 -----------------------------------
12892 -- Process_Task_Type_Declaration --
12893 -----------------------------------
12895 procedure Process_Task_Type_Declaration
12896 (Task_Decl : Node_Id;
12897 In_State : Processing_In_State)
12899 Task_Typ : constant Entity_Id := Defining_Entity (Task_Decl);
12900 Task_Def : Node_Id;
12902 begin
12903 -- Add a declaration for the task type the ALI file of the main unit
12904 -- in case a client unit creates a task object and activates it.
12906 Declare_Invocation_Construct
12907 (Constr_Id => Task_Typ,
12908 In_State => In_State);
12910 -- Process the entries of the task type because they represent valid
12911 -- entry points into the task body.
12913 if Nkind (Task_Decl) in N_Single_Task_Declaration
12914 | N_Task_Type_Declaration
12915 then
12916 Task_Def := Task_Definition (Task_Decl);
12918 if Present (Task_Def) then
12919 Process_Declarations
12920 (Decls => Visible_Declarations (Task_Def),
12921 In_State => In_State);
12922 end if;
12923 end if;
12925 -- Reset the traversed status of all subprogram bodies because the
12926 -- task type acts as a new DFS traversal root.
12928 Reset_Traversed_Bodies;
12930 -- Create a dummy scenario which activates an anonymous object of the
12931 -- task type to acts as a root of a DFS traversal.
12933 Process_Invocation_Scenario
12934 (N => Build_Task_Activation (Task_Typ, In_State),
12935 In_State => In_State);
12936 end Process_Task_Type_Declaration;
12938 ---------------------------------
12939 -- Record_Full_Invocation_Path --
12940 ---------------------------------
12942 procedure Record_Full_Invocation_Path (In_State : Processing_In_State) is
12943 package Scenarios renames Active_Scenario_Stack;
12945 begin
12946 -- The path originates from the elaboration of the body. Add an extra
12947 -- relation from the elaboration body procedure to the first active
12948 -- scenario.
12950 if In_State.Processing = Invocation_Body_Processing then
12951 Build_Elaborate_Body_Procedure;
12953 Record_Invocation_Relation
12954 (Invk_Id => Elab_Body_Id,
12955 Targ_Id => Target_Of (Scenarios.First, In_State),
12956 In_State => In_State);
12958 -- The path originates from the elaboration of the spec. Add an extra
12959 -- relation from the elaboration spec procedure to the first active
12960 -- scenario.
12962 elsif In_State.Processing = Invocation_Spec_Processing then
12963 Build_Elaborate_Spec_Procedure;
12965 Record_Invocation_Relation
12966 (Invk_Id => Elab_Spec_Id,
12967 Targ_Id => Target_Of (Scenarios.First, In_State),
12968 In_State => In_State);
12969 end if;
12971 -- Record individual relations formed by pairs of scenarios
12973 for Index in Scenarios.First .. Scenarios.Last - 1 loop
12974 Record_Invocation_Relation
12975 (Invk_Id => Target_Of (Index, In_State),
12976 Targ_Id => Target_Of (Index + 1, In_State),
12977 In_State => In_State);
12978 end loop;
12979 end Record_Full_Invocation_Path;
12981 -----------------------------
12982 -- Record_Invocation_Graph --
12983 -----------------------------
12985 procedure Record_Invocation_Graph is
12986 begin
12987 -- Nothing to do when the invocation graph is not recorded
12989 if not Invocation_Graph_Recording_OK then
12990 return;
12991 end if;
12993 -- Save the encoding format used to capture information about the
12994 -- invocation constructs and relations in the ALI file of the main
12995 -- unit.
12997 Record_Invocation_Graph_Encoding;
12999 -- Examine all library level invocation scenarios and perform DFS
13000 -- traversals from each one. Encode a path in the ALI file of the
13001 -- main unit if it reaches into an external unit.
13003 Process_Invocation_Body_Scenarios;
13004 Process_Invocation_Spec_Scenarios;
13006 -- Examine all invocation constructs within the spec and body of the
13007 -- main unit and perform DFS traversals from each one. Encode a path
13008 -- in the ALI file of the main unit if it reaches into an external
13009 -- unit.
13011 Process_Main_Unit;
13012 end Record_Invocation_Graph;
13014 --------------------------------------
13015 -- Record_Invocation_Graph_Encoding --
13016 --------------------------------------
13018 procedure Record_Invocation_Graph_Encoding is
13019 Kind : Invocation_Graph_Encoding_Kind := No_Encoding;
13021 begin
13022 -- Switch -gnatd_F (encode full invocation paths in ALI files) is in
13023 -- effect.
13025 if Debug_Flag_Underscore_FF then
13026 Kind := Full_Path_Encoding;
13027 else
13028 Kind := Endpoints_Encoding;
13029 end if;
13031 -- Save the encoding format in the ALI file of the main unit
13033 Set_Invocation_Graph_Encoding
13034 (Kind => Kind,
13035 Update_Units => False);
13036 end Record_Invocation_Graph_Encoding;
13038 ----------------------------
13039 -- Record_Invocation_Path --
13040 ----------------------------
13042 procedure Record_Invocation_Path (In_State : Processing_In_State) is
13043 package Scenarios renames Active_Scenario_Stack;
13045 begin
13046 -- Save a path when the active scenario stack contains at least one
13047 -- invocation scenario.
13049 if Scenarios.Last - Scenarios.First < 0 then
13050 return;
13051 end if;
13053 -- Register all relations in the path when switch -gnatd_F (encode
13054 -- full invocation paths in ALI files) is in effect.
13056 if Debug_Flag_Underscore_FF then
13057 Record_Full_Invocation_Path (In_State);
13059 -- Otherwise register a single relation
13061 else
13062 Record_Simple_Invocation_Path (In_State);
13063 end if;
13065 Write_Invocation_Path (In_State);
13066 end Record_Invocation_Path;
13068 --------------------------------
13069 -- Record_Invocation_Relation --
13070 --------------------------------
13072 procedure Record_Invocation_Relation
13073 (Invk_Id : Entity_Id;
13074 Targ_Id : Entity_Id;
13075 In_State : Processing_In_State)
13077 pragma Assert (Present (Invk_Id));
13078 pragma Assert (Present (Targ_Id));
13080 procedure Get_Invocation_Attributes
13081 (Extra : out Entity_Id;
13082 Kind : out Invocation_Kind);
13083 pragma Inline (Get_Invocation_Attributes);
13084 -- Return the additional entity used in error diagnostics in Extra
13085 -- and the invocation kind in Kind which pertain to the invocation
13086 -- relation with invoker Invk_Id and target Targ_Id.
13088 -------------------------------
13089 -- Get_Invocation_Attributes --
13090 -------------------------------
13092 procedure Get_Invocation_Attributes
13093 (Extra : out Entity_Id;
13094 Kind : out Invocation_Kind)
13096 begin
13097 -- Accept within a task body
13099 if Is_Accept_Alternative_Proc (Targ_Id) then
13100 Extra := Receiving_Entry (Targ_Id);
13101 Kind := Accept_Alternative;
13103 -- Activation of a task object
13105 elsif Is_Activation_Proc (Targ_Id)
13106 or else Is_Task_Type (Targ_Id)
13107 then
13108 Extra := Empty;
13109 Kind := Task_Activation;
13111 -- Controlled adjustment actions
13113 elsif Is_Controlled_Proc (Targ_Id, Name_Adjust) then
13114 Extra := First_Formal_Type (Targ_Id);
13115 Kind := Controlled_Adjustment;
13117 -- Controlled finalization actions
13119 elsif Is_Controlled_Proc (Targ_Id, Name_Finalize)
13120 or else Is_Finalizer_Proc (Targ_Id)
13121 then
13122 Extra := First_Formal_Type (Targ_Id);
13123 Kind := Controlled_Finalization;
13125 -- Controlled initialization actions
13127 elsif Is_Controlled_Proc (Targ_Id, Name_Initialize) then
13128 Extra := First_Formal_Type (Targ_Id);
13129 Kind := Controlled_Initialization;
13131 -- Default_Initial_Condition verification
13133 elsif Is_Default_Initial_Condition_Proc (Targ_Id) then
13134 Extra := First_Formal_Type (Targ_Id);
13135 Kind := Default_Initial_Condition_Verification;
13137 -- Initialization of object
13139 elsif Is_Init_Proc (Targ_Id) then
13140 Extra := First_Formal_Type (Targ_Id);
13141 Kind := Type_Initialization;
13143 -- Initial_Condition verification
13145 elsif Is_Initial_Condition_Proc (Targ_Id) then
13146 Extra := First_Formal_Type (Targ_Id);
13147 Kind := Initial_Condition_Verification;
13149 -- Instantiation
13151 elsif Is_Generic_Unit (Targ_Id) then
13152 Extra := Empty;
13153 Kind := Instantiation;
13155 -- Internal controlled adjustment actions
13157 elsif Is_TSS (Targ_Id, TSS_Deep_Adjust) then
13158 Extra := First_Formal_Type (Targ_Id);
13159 Kind := Internal_Controlled_Adjustment;
13161 -- Internal controlled finalization actions
13163 elsif Is_TSS (Targ_Id, TSS_Deep_Finalize) then
13164 Extra := First_Formal_Type (Targ_Id);
13165 Kind := Internal_Controlled_Finalization;
13167 -- Internal controlled initialization actions
13169 elsif Is_TSS (Targ_Id, TSS_Deep_Initialize) then
13170 Extra := First_Formal_Type (Targ_Id);
13171 Kind := Internal_Controlled_Initialization;
13173 -- Invariant verification
13175 elsif Is_Invariant_Proc (Targ_Id)
13176 or else Is_Partial_Invariant_Proc (Targ_Id)
13177 then
13178 Extra := First_Formal_Type (Targ_Id);
13179 Kind := Invariant_Verification;
13181 -- Protected entry call
13183 elsif Is_Protected_Entry (Targ_Id) then
13184 Extra := Empty;
13185 Kind := Protected_Entry_Call;
13187 -- Protected subprogram call
13189 elsif Is_Protected_Subp (Targ_Id) then
13190 Extra := Empty;
13191 Kind := Protected_Subprogram_Call;
13193 -- Task entry call
13195 elsif Is_Task_Entry (Targ_Id) then
13196 Extra := Empty;
13197 Kind := Task_Entry_Call;
13199 -- Entry, operator, or subprogram call. This case must come last
13200 -- because most invocations above are variations of this case.
13202 elsif Ekind (Targ_Id) in
13203 E_Entry | E_Function | E_Operator | E_Procedure
13204 then
13205 Extra := Empty;
13206 Kind := Call;
13208 else
13209 pragma Assert (False);
13210 Extra := Empty;
13211 Kind := No_Invocation;
13212 end if;
13213 end Get_Invocation_Attributes;
13215 -- Local variables
13217 Extra : Entity_Id;
13218 Extra_Nam : Name_Id;
13219 Kind : Invocation_Kind;
13220 Rel : Invoker_Target_Relation;
13222 -- Start of processing for Record_Invocation_Relation
13224 begin
13225 Rel.Invoker := Invk_Id;
13226 Rel.Target := Targ_Id;
13228 -- Nothing to do when the invocation relation has already been
13229 -- recorded in ALI file of the main unit.
13231 if Is_Saved_Relation (Rel) then
13232 return;
13233 end if;
13235 -- Mark the relation as recorded in the ALI file
13237 Set_Is_Saved_Relation (Rel);
13239 -- Declare the invoker in the ALI file
13241 Declare_Invocation_Construct
13242 (Constr_Id => Invk_Id,
13243 In_State => In_State);
13245 -- Obtain the invocation-specific attributes of the relation
13247 Get_Invocation_Attributes (Extra, Kind);
13249 -- Certain invocations lack an extra entity used in error diagnostics
13251 if Present (Extra) then
13252 Extra_Nam := Chars (Extra);
13253 else
13254 Extra_Nam := No_Name;
13255 end if;
13257 -- Add the relation in the ALI file
13259 Add_Invocation_Relation
13260 (Extra => Extra_Nam,
13261 Invoker => Signature_Of (Invk_Id),
13262 Kind => Kind,
13263 Target => Signature_Of (Targ_Id),
13264 Update_Units => False);
13265 end Record_Invocation_Relation;
13267 -----------------------------------
13268 -- Record_Simple_Invocation_Path --
13269 -----------------------------------
13271 procedure Record_Simple_Invocation_Path
13272 (In_State : Processing_In_State)
13274 package Scenarios renames Active_Scenario_Stack;
13276 Last_Targ : constant Entity_Id :=
13277 Target_Of (Scenarios.Last, In_State);
13278 First_Targ : Entity_Id;
13280 begin
13281 -- The path originates from the elaboration of the body. Add an extra
13282 -- relation from the elaboration body procedure to the first active
13283 -- scenario.
13285 if In_State.Processing = Invocation_Body_Processing then
13286 Build_Elaborate_Body_Procedure;
13287 First_Targ := Elab_Body_Id;
13289 -- The path originates from the elaboration of the spec. Add an extra
13290 -- relation from the elaboration spec procedure to the first active
13291 -- scenario.
13293 elsif In_State.Processing = Invocation_Spec_Processing then
13294 Build_Elaborate_Spec_Procedure;
13295 First_Targ := Elab_Spec_Id;
13297 else
13298 First_Targ := Target_Of (Scenarios.First, In_State);
13299 end if;
13301 -- Record a single relation from the first to the last scenario
13303 if First_Targ /= Last_Targ then
13304 Record_Invocation_Relation
13305 (Invk_Id => First_Targ,
13306 Targ_Id => Last_Targ,
13307 In_State => In_State);
13308 end if;
13309 end Record_Simple_Invocation_Path;
13311 ----------------------------
13312 -- Set_Is_Saved_Construct --
13313 ----------------------------
13315 procedure Set_Is_Saved_Construct (Constr : Entity_Id) is
13316 pragma Assert (Present (Constr));
13318 begin
13319 NE_Set.Insert (Saved_Constructs_Set, Constr);
13320 end Set_Is_Saved_Construct;
13322 ---------------------------
13323 -- Set_Is_Saved_Relation --
13324 ---------------------------
13326 procedure Set_Is_Saved_Relation (Rel : Invoker_Target_Relation) is
13327 begin
13328 IR_Set.Insert (Saved_Relations_Set, Rel);
13329 end Set_Is_Saved_Relation;
13331 ------------------
13332 -- Signature_Of --
13333 ------------------
13335 function Signature_Of (Id : Entity_Id) return Invocation_Signature_Id is
13336 Loc : constant Source_Ptr := Sloc (Id);
13338 function Instantiation_Locations return Name_Id;
13339 pragma Inline (Instantiation_Locations);
13340 -- Create a concatenation of all lines and colums of each instance
13341 -- where source location Loc appears. Return No_Name if no instances
13342 -- exist.
13344 function Qualified_Scope return Name_Id;
13345 pragma Inline (Qualified_Scope);
13346 -- Obtain the qualified name of Id's scope
13348 -----------------------------
13349 -- Instantiation_Locations --
13350 -----------------------------
13352 function Instantiation_Locations return Name_Id is
13353 Buffer : Bounded_String (2052);
13354 Inst : Source_Ptr;
13355 Loc_Nam : Name_Id;
13356 SFI : Source_File_Index;
13358 begin
13359 SFI := Get_Source_File_Index (Loc);
13360 Inst := Instantiation (SFI);
13362 -- The location is within an instance. Construct a concatenation
13363 -- of all lines and colums of each individual instance using the
13364 -- following format:
13366 -- line1_column1_line2_column2_ ... _lineN_columnN
13368 if Inst /= No_Location then
13369 loop
13370 Append (Buffer, Nat (Get_Logical_Line_Number (Inst)));
13371 Append (Buffer, '_');
13372 Append (Buffer, Nat (Get_Column_Number (Inst)));
13374 SFI := Get_Source_File_Index (Inst);
13375 Inst := Instantiation (SFI);
13377 exit when Inst = No_Location;
13379 Append (Buffer, '_');
13380 end loop;
13382 Loc_Nam := Name_Find (Buffer);
13383 return Loc_Nam;
13385 -- Otherwise there no instances are involved
13387 else
13388 return No_Name;
13389 end if;
13390 end Instantiation_Locations;
13392 ---------------------
13393 -- Qualified_Scope --
13394 ---------------------
13396 function Qualified_Scope return Name_Id is
13397 Scop : Entity_Id;
13399 begin
13400 Scop := Scope (Id);
13402 -- The entity appears within an anonymous concurrent type created
13403 -- for a single protected or task type declaration. Use the entity
13404 -- of the anonymous object as it represents the original scope.
13406 if Is_Concurrent_Type (Scop)
13407 and then Present (Anonymous_Object (Scop))
13408 then
13409 Scop := Anonymous_Object (Scop);
13410 end if;
13412 return Get_Qualified_Name (Scop);
13413 end Qualified_Scope;
13415 -- Start of processing for Signature_Of
13417 begin
13418 return
13419 Invocation_Signature_Of
13420 (Column => Nat (Get_Column_Number (Loc)),
13421 Line => Nat (Get_Logical_Line_Number (Loc)),
13422 Locations => Instantiation_Locations,
13423 Name => Chars (Id),
13424 Scope => Qualified_Scope);
13425 end Signature_Of;
13427 ---------------
13428 -- Target_Of --
13429 ---------------
13431 function Target_Of
13432 (Pos : Active_Scenario_Pos;
13433 In_State : Processing_In_State) return Entity_Id
13435 package Scenarios renames Active_Scenario_Stack;
13437 -- Ensure that the position is within the bounds of the active
13438 -- scenario stack.
13440 pragma Assert (Scenarios.First <= Pos);
13441 pragma Assert (Pos <= Scenarios.Last);
13443 Scen_Rep : constant Scenario_Rep_Id :=
13444 Scenario_Representation_Of
13445 (Scenarios.Table (Pos), In_State);
13447 begin
13448 -- The true target of an activation call is the current task type
13449 -- rather than routine Activate_Tasks.
13451 if Kind (Scen_Rep) = Task_Activation_Scenario then
13452 return Activated_Task_Type (Scen_Rep);
13453 else
13454 return Target (Scen_Rep);
13455 end if;
13456 end Target_Of;
13458 ------------------------------
13459 -- Traverse_Invocation_Body --
13460 ------------------------------
13462 procedure Traverse_Invocation_Body
13463 (N : Node_Id;
13464 In_State : Processing_In_State)
13466 begin
13467 Traverse_Body
13468 (N => N,
13469 Requires_Processing => Is_Invocation_Scenario'Access,
13470 Processor => Process_Invocation_Scenario'Access,
13471 In_State => In_State);
13472 end Traverse_Invocation_Body;
13474 ---------------------------
13475 -- Write_Invocation_Path --
13476 ---------------------------
13478 procedure Write_Invocation_Path (In_State : Processing_In_State) is
13479 procedure Write_Target (Targ_Id : Entity_Id; Is_First : Boolean);
13480 pragma Inline (Write_Target);
13481 -- Write out invocation target Targ_Id to standard output. Flag
13482 -- Is_First should be set when the target is first in a path.
13484 -------------
13485 -- Targ_Id --
13486 -------------
13488 procedure Write_Target (Targ_Id : Entity_Id; Is_First : Boolean) is
13489 begin
13490 if not Is_First then
13491 Write_Str (" --> ");
13492 end if;
13494 Write_Name (Get_Qualified_Name (Targ_Id));
13495 Write_Eol;
13496 end Write_Target;
13498 -- Local variables
13500 package Scenarios renames Active_Scenario_Stack;
13502 First_Seen : Boolean := False;
13504 -- Start of processing for Write_Invocation_Path
13506 begin
13507 -- Nothing to do when flag -gnatd_T (output trace information on
13508 -- invocation path recording) is not in effect.
13510 if not Debug_Flag_Underscore_TT then
13511 return;
13512 end if;
13514 -- The path originates from the elaboration of the body. Write the
13515 -- elaboration body procedure.
13517 if In_State.Processing = Invocation_Body_Processing then
13518 Write_Target (Elab_Body_Id, True);
13519 First_Seen := True;
13521 -- The path originates from the elaboration of the spec. Write the
13522 -- elaboration spec procedure.
13524 elsif In_State.Processing = Invocation_Spec_Processing then
13525 Write_Target (Elab_Spec_Id, True);
13526 First_Seen := True;
13527 end if;
13529 -- Write each individual target invoked by its corresponding scenario
13530 -- on the active scenario stack.
13532 for Index in Scenarios.First .. Scenarios.Last loop
13533 Write_Target
13534 (Targ_Id => Target_Of (Index, In_State),
13535 Is_First => Index = Scenarios.First and then not First_Seen);
13536 end loop;
13538 Write_Eol;
13539 end Write_Invocation_Path;
13540 end Invocation_Graph;
13542 ------------------------
13543 -- Is_Safe_Activation --
13544 ------------------------
13546 function Is_Safe_Activation
13547 (Call : Node_Id;
13548 Task_Rep : Target_Rep_Id) return Boolean
13550 begin
13551 -- The activation of a task coming from an external instance cannot
13552 -- cause an ABE because the generic was already instantiated. Note
13553 -- that the instantiation itself may lead to an ABE.
13555 return
13556 In_External_Instance
13557 (N => Call,
13558 Target_Decl => Spec_Declaration (Task_Rep));
13559 end Is_Safe_Activation;
13561 ------------------
13562 -- Is_Safe_Call --
13563 ------------------
13565 function Is_Safe_Call
13566 (Call : Node_Id;
13567 Subp_Id : Entity_Id;
13568 Subp_Rep : Target_Rep_Id) return Boolean
13570 Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
13571 Spec_Decl : constant Node_Id := Spec_Declaration (Subp_Rep);
13573 begin
13574 -- The target is either an abstract subprogram, formal subprogram, or
13575 -- imported, in which case it does not have a body at compile or bind
13576 -- time. Assume that the call is ABE-safe.
13578 if Is_Bodiless_Subprogram (Subp_Id) then
13579 return True;
13581 -- The target is an instantiation of a generic subprogram. The call
13582 -- cannot cause an ABE because the generic was already instantiated.
13583 -- Note that the instantiation itself may lead to an ABE.
13585 elsif Is_Generic_Instance (Subp_Id) then
13586 return True;
13588 -- The invocation of a target coming from an external instance cannot
13589 -- cause an ABE because the generic was already instantiated. Note that
13590 -- the instantiation itself may lead to an ABE.
13592 elsif In_External_Instance
13593 (N => Call,
13594 Target_Decl => Spec_Decl)
13595 then
13596 return True;
13598 -- The target is a subprogram body without a previous declaration. The
13599 -- call cannot cause an ABE because the body has already been seen.
13601 elsif Nkind (Spec_Decl) = N_Subprogram_Body
13602 and then No (Corresponding_Spec (Spec_Decl))
13603 then
13604 return True;
13606 -- The target is a subprogram body stub without a prior declaration.
13607 -- The call cannot cause an ABE because the proper body substitutes
13608 -- the stub.
13610 elsif Nkind (Spec_Decl) = N_Subprogram_Body_Stub
13611 and then No (Corresponding_Spec_Of_Stub (Spec_Decl))
13612 then
13613 return True;
13615 -- A call to an expression function that is not a completion cannot
13616 -- cause an ABE because it has no prior declaration; this remains
13617 -- true even if the FE transforms the callee into something else.
13619 elsif Nkind (Original_Node (Spec_Decl)) = N_Expression_Function then
13620 return True;
13622 -- Subprogram bodies which wrap attribute references used as actuals
13623 -- in instantiations are always ABE-safe. These bodies are artifacts
13624 -- of expansion.
13626 elsif Present (Body_Decl)
13627 and then Nkind (Body_Decl) = N_Subprogram_Body
13628 and then Was_Attribute_Reference (Body_Decl)
13629 then
13630 return True;
13631 end if;
13633 return False;
13634 end Is_Safe_Call;
13636 ---------------------------
13637 -- Is_Safe_Instantiation --
13638 ---------------------------
13640 function Is_Safe_Instantiation
13641 (Inst : Node_Id;
13642 Gen_Id : Entity_Id;
13643 Gen_Rep : Target_Rep_Id) return Boolean
13645 Spec_Decl : constant Node_Id := Spec_Declaration (Gen_Rep);
13647 begin
13648 -- The generic is an intrinsic subprogram in which case it does not
13649 -- have a body at compile or bind time. Assume that the instantiation
13650 -- is ABE-safe.
13652 if Is_Bodiless_Subprogram (Gen_Id) then
13653 return True;
13655 -- The instantiation of an external nested generic cannot cause an ABE
13656 -- if the outer generic was already instantiated. Note that the instance
13657 -- of the outer generic may lead to an ABE.
13659 elsif In_External_Instance
13660 (N => Inst,
13661 Target_Decl => Spec_Decl)
13662 then
13663 return True;
13665 -- The generic is a package. The instantiation cannot cause an ABE when
13666 -- the package has no body.
13668 elsif Ekind (Gen_Id) = E_Generic_Package
13669 and then not Has_Body (Spec_Decl)
13670 then
13671 return True;
13672 end if;
13674 return False;
13675 end Is_Safe_Instantiation;
13677 ------------------
13678 -- Is_Same_Unit --
13679 ------------------
13681 function Is_Same_Unit
13682 (Unit_1 : Entity_Id;
13683 Unit_2 : Entity_Id) return Boolean
13685 begin
13686 return Unit_Entity (Unit_1) = Unit_Entity (Unit_2);
13687 end Is_Same_Unit;
13689 -------------------------------
13690 -- Kill_Elaboration_Scenario --
13691 -------------------------------
13693 procedure Kill_Elaboration_Scenario (N : Node_Id) is
13694 begin
13695 -- Nothing to do when switch -gnatH (legacy elaboration checking mode
13696 -- enabled) is in effect because the legacy ABE lechanism does not need
13697 -- to carry out this action.
13699 if Legacy_Elaboration_Checks then
13700 return;
13702 -- Nothing to do when the elaboration phase of the compiler is not
13703 -- active.
13705 elsif not Elaboration_Phase_Active then
13706 return;
13707 end if;
13709 -- Eliminate a recorded scenario when it appears within dead code
13710 -- because it will not be executed at elaboration time.
13712 if Is_Scenario (N) then
13713 Delete_Scenario (N);
13714 end if;
13715 end Kill_Elaboration_Scenario;
13717 ----------------------
13718 -- Main_Unit_Entity --
13719 ----------------------
13721 function Main_Unit_Entity return Entity_Id is
13722 begin
13723 -- Note that Cunit_Entity (Main_Unit) is not reliable in the presence of
13724 -- generic bodies and may return an outdated entity.
13726 return Defining_Entity (Unit (Cunit (Main_Unit)));
13727 end Main_Unit_Entity;
13729 ----------------------
13730 -- Non_Private_View --
13731 ----------------------
13733 function Non_Private_View (Typ : Entity_Id) return Entity_Id is
13734 begin
13735 if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
13736 return Full_View (Typ);
13737 else
13738 return Typ;
13739 end if;
13740 end Non_Private_View;
13742 ---------------------------------
13743 -- Record_Elaboration_Scenario --
13744 ---------------------------------
13746 procedure Record_Elaboration_Scenario (N : Node_Id) is
13747 procedure Check_Preelaborated_Call
13748 (Call : Node_Id;
13749 Call_Lvl : Enclosing_Level_Kind);
13750 pragma Inline (Check_Preelaborated_Call);
13751 -- Verify that entry, operator, or subprogram call Call with enclosing
13752 -- level Call_Lvl does not appear at the library level of preelaborated
13753 -- unit.
13755 function Find_Code_Unit (Nod : Node_Or_Entity_Id) return Entity_Id;
13756 pragma Inline (Find_Code_Unit);
13757 -- Return the code unit which contains arbitrary node or entity Nod.
13758 -- This is the unit of the file which physically contains the related
13759 -- construct denoted by Nod except when Nod is within an instantiation.
13760 -- In that case the unit is that of the top-level instantiation.
13762 function In_Preelaborated_Context (Nod : Node_Id) return Boolean;
13763 pragma Inline (In_Preelaborated_Context);
13764 -- Determine whether arbitrary node Nod appears within a preelaborated
13765 -- context.
13767 procedure Record_Access_Taken
13768 (Attr : Node_Id;
13769 Attr_Lvl : Enclosing_Level_Kind);
13770 pragma Inline (Record_Access_Taken);
13771 -- Record 'Access scenario Attr with enclosing level Attr_Lvl
13773 procedure Record_Call_Or_Task_Activation
13774 (Call : Node_Id;
13775 Call_Lvl : Enclosing_Level_Kind);
13776 pragma Inline (Record_Call_Or_Task_Activation);
13777 -- Record call scenario Call with enclosing level Call_Lvl
13779 procedure Record_Instantiation
13780 (Inst : Node_Id;
13781 Inst_Lvl : Enclosing_Level_Kind);
13782 pragma Inline (Record_Instantiation);
13783 -- Record instantiation scenario Inst with enclosing level Inst_Lvl
13785 procedure Record_Variable_Assignment
13786 (Asmt : Node_Id;
13787 Asmt_Lvl : Enclosing_Level_Kind);
13788 pragma Inline (Record_Variable_Assignment);
13789 -- Record variable assignment scenario Asmt with enclosing level
13790 -- Asmt_Lvl.
13792 procedure Record_Variable_Reference
13793 (Ref : Node_Id;
13794 Ref_Lvl : Enclosing_Level_Kind);
13795 pragma Inline (Record_Variable_Reference);
13796 -- Record variable reference scenario Ref with enclosing level Ref_Lvl
13798 ------------------------------
13799 -- Check_Preelaborated_Call --
13800 ------------------------------
13802 procedure Check_Preelaborated_Call
13803 (Call : Node_Id;
13804 Call_Lvl : Enclosing_Level_Kind)
13806 begin
13807 -- Nothing to do when the call is internally generated because it is
13808 -- assumed that it will never violate preelaboration.
13810 if not Is_Source_Call (Call) then
13811 return;
13813 -- Nothing to do when the call is preelaborable by definition
13815 elsif Is_Preelaborable_Call (Call) then
13816 return;
13818 -- Library-level calls are always considered because they are part of
13819 -- the associated unit's elaboration actions.
13821 elsif Call_Lvl in Library_Level then
13822 null;
13824 -- Calls at the library level of a generic package body have to be
13825 -- checked because they would render an instantiation illegal if the
13826 -- template is marked as preelaborated. Note that this does not apply
13827 -- to calls at the library level of a generic package spec.
13829 elsif Call_Lvl = Generic_Body_Level then
13830 null;
13832 -- Otherwise the call does not appear at the proper level and must
13833 -- not be considered for this check.
13835 else
13836 return;
13837 end if;
13839 -- If the call appears within a preelaborated unit, give an error
13841 if In_Preelaborated_Context (Call) then
13842 Error_Preelaborated_Call (Call);
13843 end if;
13844 end Check_Preelaborated_Call;
13846 --------------------
13847 -- Find_Code_Unit --
13848 --------------------
13850 function Find_Code_Unit (Nod : Node_Or_Entity_Id) return Entity_Id is
13851 begin
13852 return Find_Unit_Entity (Unit (Cunit (Get_Code_Unit (Nod))));
13853 end Find_Code_Unit;
13855 ------------------------------
13856 -- In_Preelaborated_Context --
13857 ------------------------------
13859 function In_Preelaborated_Context (Nod : Node_Id) return Boolean is
13860 Body_Id : constant Entity_Id := Find_Code_Unit (Nod);
13861 Spec_Id : constant Entity_Id := Unique_Entity (Body_Id);
13863 begin
13864 -- The node appears within a package body whose corresponding spec is
13865 -- subject to pragma Remote_Call_Interface or Remote_Types. This does
13866 -- not result in a preelaborated context because the package body may
13867 -- be on another machine.
13869 if Ekind (Body_Id) = E_Package_Body
13870 and then Is_Package_Or_Generic_Package (Spec_Id)
13871 and then (Is_Remote_Call_Interface (Spec_Id)
13872 or else Is_Remote_Types (Spec_Id))
13873 then
13874 return False;
13876 -- Otherwise the node appears within a preelaborated context when the
13877 -- associated unit is preelaborated.
13879 else
13880 return Is_Preelaborated_Unit (Spec_Id);
13881 end if;
13882 end In_Preelaborated_Context;
13884 -------------------------
13885 -- Record_Access_Taken --
13886 -------------------------
13888 procedure Record_Access_Taken
13889 (Attr : Node_Id;
13890 Attr_Lvl : Enclosing_Level_Kind)
13892 begin
13893 -- Signal any enclosing local exception handlers that the 'Access may
13894 -- raise Program_Error due to a failed ABE check when switch -gnatd.o
13895 -- (conservative elaboration order for indirect calls) is in effect.
13896 -- Marking the exception handlers ensures proper expansion by both
13897 -- the front and back end restriction when No_Exception_Propagation
13898 -- is in effect.
13900 if Debug_Flag_Dot_O then
13901 Possible_Local_Raise (Attr, Standard_Program_Error);
13902 end if;
13904 -- Add 'Access to the appropriate set
13906 if Attr_Lvl = Library_Body_Level then
13907 Add_Library_Body_Scenario (Attr);
13909 elsif Attr_Lvl = Library_Spec_Level
13910 or else Attr_Lvl = Instantiation_Level
13911 then
13912 Add_Library_Spec_Scenario (Attr);
13913 end if;
13915 -- 'Access requires a conditional ABE check when the dynamic model is
13916 -- in effect.
13918 Add_Dynamic_ABE_Check_Scenario (Attr);
13919 end Record_Access_Taken;
13921 ------------------------------------
13922 -- Record_Call_Or_Task_Activation --
13923 ------------------------------------
13925 procedure Record_Call_Or_Task_Activation
13926 (Call : Node_Id;
13927 Call_Lvl : Enclosing_Level_Kind)
13929 begin
13930 -- Signal any enclosing local exception handlers that the call may
13931 -- raise Program_Error due to failed ABE check. Marking the exception
13932 -- handlers ensures proper expansion by both the front and back end
13933 -- restriction when No_Exception_Propagation is in effect.
13935 Possible_Local_Raise (Call, Standard_Program_Error);
13937 -- Perform early detection of guaranteed ABEs in order to suppress
13938 -- the instantiation of generic bodies because gigi cannot handle
13939 -- certain types of premature instantiations.
13941 Process_Guaranteed_ABE
13942 (N => Call,
13943 In_State => Guaranteed_ABE_State);
13945 -- Add the call or task activation to the appropriate set
13947 if Call_Lvl = Declaration_Level then
13948 Add_Declaration_Scenario (Call);
13950 elsif Call_Lvl = Library_Body_Level then
13951 Add_Library_Body_Scenario (Call);
13953 elsif Call_Lvl = Library_Spec_Level
13954 or else Call_Lvl = Instantiation_Level
13955 then
13956 Add_Library_Spec_Scenario (Call);
13957 end if;
13959 -- A call or a task activation requires a conditional ABE check when
13960 -- the dynamic model is in effect.
13962 Add_Dynamic_ABE_Check_Scenario (Call);
13963 end Record_Call_Or_Task_Activation;
13965 --------------------------
13966 -- Record_Instantiation --
13967 --------------------------
13969 procedure Record_Instantiation
13970 (Inst : Node_Id;
13971 Inst_Lvl : Enclosing_Level_Kind)
13973 begin
13974 -- Signal enclosing local exception handlers that instantiation may
13975 -- raise Program_Error due to failed ABE check. Marking the exception
13976 -- handlers ensures proper expansion by both the front and back end
13977 -- restriction when No_Exception_Propagation is in effect.
13979 Possible_Local_Raise (Inst, Standard_Program_Error);
13981 -- Perform early detection of guaranteed ABEs in order to suppress
13982 -- the instantiation of generic bodies because gigi cannot handle
13983 -- certain types of premature instantiations.
13985 Process_Guaranteed_ABE
13986 (N => Inst,
13987 In_State => Guaranteed_ABE_State);
13989 -- Add the instantiation to the appropriate set
13991 if Inst_Lvl = Declaration_Level then
13992 Add_Declaration_Scenario (Inst);
13994 elsif Inst_Lvl = Library_Body_Level then
13995 Add_Library_Body_Scenario (Inst);
13997 elsif Inst_Lvl = Library_Spec_Level
13998 or else Inst_Lvl = Instantiation_Level
13999 then
14000 Add_Library_Spec_Scenario (Inst);
14001 end if;
14003 -- Instantiations of generics subject to SPARK_Mode On require
14004 -- elaboration-related checks even though the instantiations may
14005 -- not appear within elaboration code.
14007 if Is_Suitable_SPARK_Instantiation (Inst) then
14008 Add_SPARK_Scenario (Inst);
14009 end if;
14011 -- An instantiation requires a conditional ABE check when the dynamic
14012 -- model is in effect.
14014 Add_Dynamic_ABE_Check_Scenario (Inst);
14015 end Record_Instantiation;
14017 --------------------------------
14018 -- Record_Variable_Assignment --
14019 --------------------------------
14021 procedure Record_Variable_Assignment
14022 (Asmt : Node_Id;
14023 Asmt_Lvl : Enclosing_Level_Kind)
14025 begin
14026 -- Add the variable assignment to the appropriate set
14028 if Asmt_Lvl = Library_Body_Level then
14029 Add_Library_Body_Scenario (Asmt);
14031 elsif Asmt_Lvl = Library_Spec_Level
14032 or else Asmt_Lvl = Instantiation_Level
14033 then
14034 Add_Library_Spec_Scenario (Asmt);
14035 end if;
14036 end Record_Variable_Assignment;
14038 -------------------------------
14039 -- Record_Variable_Reference --
14040 -------------------------------
14042 procedure Record_Variable_Reference
14043 (Ref : Node_Id;
14044 Ref_Lvl : Enclosing_Level_Kind)
14046 begin
14047 -- Add the variable reference to the appropriate set
14049 if Ref_Lvl = Library_Body_Level then
14050 Add_Library_Body_Scenario (Ref);
14052 elsif Ref_Lvl = Library_Spec_Level
14053 or else Ref_Lvl = Instantiation_Level
14054 then
14055 Add_Library_Spec_Scenario (Ref);
14056 end if;
14057 end Record_Variable_Reference;
14059 -- Local variables
14061 Scen : constant Node_Id := Scenario (N);
14062 Scen_Lvl : Enclosing_Level_Kind;
14064 -- Start of processing for Record_Elaboration_Scenario
14066 begin
14067 -- Nothing to do when switch -gnatH (legacy elaboration checking mode
14068 -- enabled) is in effect because the legacy ABE mechanism does not need
14069 -- to carry out this action.
14071 if Legacy_Elaboration_Checks then
14072 return;
14074 -- Nothing to do when the scenario is being preanalyzed
14076 elsif Preanalysis_Active then
14077 return;
14079 -- Nothing to do when the elaboration phase of the compiler is not
14080 -- active.
14082 elsif not Elaboration_Phase_Active then
14083 return;
14084 end if;
14086 Scen_Lvl := Find_Enclosing_Level (Scen);
14088 -- Ensure that a library-level call does not appear in a preelaborated
14089 -- unit. The check must come before ignoring scenarios within external
14090 -- units or inside generics because calls in those context must also be
14091 -- verified.
14093 if Is_Suitable_Call (Scen) then
14094 Check_Preelaborated_Call (Scen, Scen_Lvl);
14095 end if;
14097 -- Nothing to do when the scenario does not appear within the main unit
14099 if not In_Main_Context (Scen) then
14100 return;
14102 -- Nothing to do when the scenario appears within a generic
14104 elsif Inside_A_Generic then
14105 return;
14107 -- 'Access
14109 elsif Is_Suitable_Access_Taken (Scen) then
14110 Record_Access_Taken
14111 (Attr => Scen,
14112 Attr_Lvl => Scen_Lvl);
14114 -- Call or task activation
14116 elsif Is_Suitable_Call (Scen) then
14117 Record_Call_Or_Task_Activation
14118 (Call => Scen,
14119 Call_Lvl => Scen_Lvl);
14121 -- Derived type declaration
14123 elsif Is_Suitable_SPARK_Derived_Type (Scen) then
14124 Add_SPARK_Scenario (Scen);
14126 -- Instantiation
14128 elsif Is_Suitable_Instantiation (Scen) then
14129 Record_Instantiation
14130 (Inst => Scen,
14131 Inst_Lvl => Scen_Lvl);
14133 -- Refined_State pragma
14135 elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
14136 Add_SPARK_Scenario (Scen);
14138 -- Variable assignment
14140 elsif Is_Suitable_Variable_Assignment (Scen) then
14141 Record_Variable_Assignment
14142 (Asmt => Scen,
14143 Asmt_Lvl => Scen_Lvl);
14145 -- Variable reference
14147 elsif Is_Suitable_Variable_Reference (Scen) then
14148 Record_Variable_Reference
14149 (Ref => Scen,
14150 Ref_Lvl => Scen_Lvl);
14151 end if;
14152 end Record_Elaboration_Scenario;
14154 --------------
14155 -- Scenario --
14156 --------------
14158 function Scenario (N : Node_Id) return Node_Id is
14159 Orig_N : constant Node_Id := Original_Node (N);
14161 begin
14162 -- An expanded instantiation is rewritten into a spec-body pair where
14163 -- N denotes the spec. In this case the original instantiation is the
14164 -- proper elaboration scenario.
14166 if Nkind (Orig_N) in N_Generic_Instantiation then
14167 return Orig_N;
14169 -- Otherwise the scenario is already in its proper form
14171 else
14172 return N;
14173 end if;
14174 end Scenario;
14176 ----------------------
14177 -- Scenario_Storage --
14178 ----------------------
14180 package body Scenario_Storage is
14182 ---------------------
14183 -- Data structures --
14184 ---------------------
14186 -- The following sets store all scenarios
14188 Declaration_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
14189 Dynamic_ABE_Check_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
14190 Library_Body_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
14191 Library_Spec_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
14192 SPARK_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
14194 -------------------------------
14195 -- Finalize_Scenario_Storage --
14196 -------------------------------
14198 procedure Finalize_Scenario_Storage is
14199 begin
14200 NE_Set.Destroy (Declaration_Scenarios);
14201 NE_Set.Destroy (Dynamic_ABE_Check_Scenarios);
14202 NE_Set.Destroy (Library_Body_Scenarios);
14203 NE_Set.Destroy (Library_Spec_Scenarios);
14204 NE_Set.Destroy (SPARK_Scenarios);
14205 end Finalize_Scenario_Storage;
14207 ---------------------------------
14208 -- Initialize_Scenario_Storage --
14209 ---------------------------------
14211 procedure Initialize_Scenario_Storage is
14212 begin
14213 Declaration_Scenarios := NE_Set.Create (1000);
14214 Dynamic_ABE_Check_Scenarios := NE_Set.Create (500);
14215 Library_Body_Scenarios := NE_Set.Create (1000);
14216 Library_Spec_Scenarios := NE_Set.Create (1000);
14217 SPARK_Scenarios := NE_Set.Create (100);
14218 end Initialize_Scenario_Storage;
14220 ------------------------------
14221 -- Add_Declaration_Scenario --
14222 ------------------------------
14224 procedure Add_Declaration_Scenario (N : Node_Id) is
14225 pragma Assert (Present (N));
14226 begin
14227 NE_Set.Insert (Declaration_Scenarios, N);
14228 end Add_Declaration_Scenario;
14230 ------------------------------------
14231 -- Add_Dynamic_ABE_Check_Scenario --
14232 ------------------------------------
14234 procedure Add_Dynamic_ABE_Check_Scenario (N : Node_Id) is
14235 pragma Assert (Present (N));
14237 begin
14238 if not Check_Or_Failure_Generation_OK then
14239 return;
14241 -- Nothing to do if the dynamic model is not in effect
14243 elsif not Dynamic_Elaboration_Checks then
14244 return;
14245 end if;
14247 NE_Set.Insert (Dynamic_ABE_Check_Scenarios, N);
14248 end Add_Dynamic_ABE_Check_Scenario;
14250 -------------------------------
14251 -- Add_Library_Body_Scenario --
14252 -------------------------------
14254 procedure Add_Library_Body_Scenario (N : Node_Id) is
14255 pragma Assert (Present (N));
14256 begin
14257 NE_Set.Insert (Library_Body_Scenarios, N);
14258 end Add_Library_Body_Scenario;
14260 -------------------------------
14261 -- Add_Library_Spec_Scenario --
14262 -------------------------------
14264 procedure Add_Library_Spec_Scenario (N : Node_Id) is
14265 pragma Assert (Present (N));
14266 begin
14267 NE_Set.Insert (Library_Spec_Scenarios, N);
14268 end Add_Library_Spec_Scenario;
14270 ------------------------
14271 -- Add_SPARK_Scenario --
14272 ------------------------
14274 procedure Add_SPARK_Scenario (N : Node_Id) is
14275 pragma Assert (Present (N));
14276 begin
14277 NE_Set.Insert (SPARK_Scenarios, N);
14278 end Add_SPARK_Scenario;
14280 ---------------------
14281 -- Delete_Scenario --
14282 ---------------------
14284 procedure Delete_Scenario (N : Node_Id) is
14285 pragma Assert (Present (N));
14287 begin
14288 -- Delete the scenario from whichever set it belongs to
14290 NE_Set.Delete (Declaration_Scenarios, N);
14291 NE_Set.Delete (Dynamic_ABE_Check_Scenarios, N);
14292 NE_Set.Delete (Library_Body_Scenarios, N);
14293 NE_Set.Delete (Library_Spec_Scenarios, N);
14294 NE_Set.Delete (SPARK_Scenarios, N);
14295 end Delete_Scenario;
14297 -----------------------------------
14298 -- Iterate_Declaration_Scenarios --
14299 -----------------------------------
14301 function Iterate_Declaration_Scenarios return NE_Set.Iterator is
14302 begin
14303 return NE_Set.Iterate (Declaration_Scenarios);
14304 end Iterate_Declaration_Scenarios;
14306 -----------------------------------------
14307 -- Iterate_Dynamic_ABE_Check_Scenarios --
14308 -----------------------------------------
14310 function Iterate_Dynamic_ABE_Check_Scenarios return NE_Set.Iterator is
14311 begin
14312 return NE_Set.Iterate (Dynamic_ABE_Check_Scenarios);
14313 end Iterate_Dynamic_ABE_Check_Scenarios;
14315 ------------------------------------
14316 -- Iterate_Library_Body_Scenarios --
14317 ------------------------------------
14319 function Iterate_Library_Body_Scenarios return NE_Set.Iterator is
14320 begin
14321 return NE_Set.Iterate (Library_Body_Scenarios);
14322 end Iterate_Library_Body_Scenarios;
14324 ------------------------------------
14325 -- Iterate_Library_Spec_Scenarios --
14326 ------------------------------------
14328 function Iterate_Library_Spec_Scenarios return NE_Set.Iterator is
14329 begin
14330 return NE_Set.Iterate (Library_Spec_Scenarios);
14331 end Iterate_Library_Spec_Scenarios;
14333 -----------------------------
14334 -- Iterate_SPARK_Scenarios --
14335 -----------------------------
14337 function Iterate_SPARK_Scenarios return NE_Set.Iterator is
14338 begin
14339 return NE_Set.Iterate (SPARK_Scenarios);
14340 end Iterate_SPARK_Scenarios;
14342 ----------------------
14343 -- Replace_Scenario --
14344 ----------------------
14346 procedure Replace_Scenario (Old_N : Node_Id; New_N : Node_Id) is
14347 procedure Replace_Scenario_In (Scenarios : NE_Set.Membership_Set);
14348 -- Determine whether scenario Old_N is present in set Scenarios, and
14349 -- if this is the case it, replace it with New_N.
14351 -------------------------
14352 -- Replace_Scenario_In --
14353 -------------------------
14355 procedure Replace_Scenario_In (Scenarios : NE_Set.Membership_Set) is
14356 begin
14357 -- The set is intentionally checked for existance because node
14358 -- rewriting may occur after Sem_Elab has verified all scenarios
14359 -- and data structures have been destroyed.
14361 if NE_Set.Present (Scenarios)
14362 and then NE_Set.Contains (Scenarios, Old_N)
14363 then
14364 NE_Set.Delete (Scenarios, Old_N);
14365 NE_Set.Insert (Scenarios, New_N);
14366 end if;
14367 end Replace_Scenario_In;
14369 -- Start of processing for Replace_Scenario
14371 begin
14372 Replace_Scenario_In (Declaration_Scenarios);
14373 Replace_Scenario_In (Dynamic_ABE_Check_Scenarios);
14374 Replace_Scenario_In (Library_Body_Scenarios);
14375 Replace_Scenario_In (Library_Spec_Scenarios);
14376 Replace_Scenario_In (SPARK_Scenarios);
14377 end Replace_Scenario;
14378 end Scenario_Storage;
14380 ---------------
14381 -- Semantics --
14382 ---------------
14384 package body Semantics is
14386 --------------------------------
14387 -- Is_Accept_Alternative_Proc --
14388 --------------------------------
14390 function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean is
14391 begin
14392 -- To qualify, the entity must denote a procedure with a receiving
14393 -- entry.
14395 return
14396 Ekind (Id) = E_Procedure and then Present (Receiving_Entry (Id));
14397 end Is_Accept_Alternative_Proc;
14399 ------------------------
14400 -- Is_Activation_Proc --
14401 ------------------------
14403 function Is_Activation_Proc (Id : Entity_Id) return Boolean is
14404 begin
14405 -- To qualify, the entity must denote one of the runtime procedures
14406 -- in charge of task activation.
14408 if Ekind (Id) = E_Procedure then
14409 if Restricted_Profile then
14410 return Is_RTE (Id, RE_Activate_Restricted_Tasks);
14411 else
14412 return Is_RTE (Id, RE_Activate_Tasks);
14413 end if;
14414 end if;
14416 return False;
14417 end Is_Activation_Proc;
14419 ----------------------------
14420 -- Is_Ada_Semantic_Target --
14421 ----------------------------
14423 function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean is
14424 begin
14425 return
14426 Is_Activation_Proc (Id)
14427 or else Is_Controlled_Proc (Id, Name_Adjust)
14428 or else Is_Controlled_Proc (Id, Name_Finalize)
14429 or else Is_Controlled_Proc (Id, Name_Initialize)
14430 or else Is_Init_Proc (Id)
14431 or else Is_Invariant_Proc (Id)
14432 or else Is_Protected_Entry (Id)
14433 or else Is_Protected_Subp (Id)
14434 or else Is_Protected_Body_Subp (Id)
14435 or else Is_Subprogram_Inst (Id)
14436 or else Is_Task_Entry (Id);
14437 end Is_Ada_Semantic_Target;
14439 --------------------------------
14440 -- Is_Assertion_Pragma_Target --
14441 --------------------------------
14443 function Is_Assertion_Pragma_Target (Id : Entity_Id) return Boolean is
14444 begin
14445 return
14446 Is_Default_Initial_Condition_Proc (Id)
14447 or else Is_Initial_Condition_Proc (Id)
14448 or else Is_Invariant_Proc (Id)
14449 or else Is_Partial_Invariant_Proc (Id);
14450 end Is_Assertion_Pragma_Target;
14452 ----------------------------
14453 -- Is_Bodiless_Subprogram --
14454 ----------------------------
14456 function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean is
14457 begin
14458 -- An abstract subprogram does not have a body
14460 if Ekind (Subp_Id) in E_Function | E_Operator | E_Procedure
14461 and then Is_Abstract_Subprogram (Subp_Id)
14462 then
14463 return True;
14465 -- A formal subprogram does not have a body
14467 elsif Is_Formal_Subprogram (Subp_Id) then
14468 return True;
14470 -- An imported subprogram may have a body, however it is not known at
14471 -- compile or bind time where the body resides and whether it will be
14472 -- elaborated on time.
14474 elsif Is_Imported (Subp_Id) then
14475 return True;
14476 end if;
14478 return False;
14479 end Is_Bodiless_Subprogram;
14481 ----------------------
14482 -- Is_Bridge_Target --
14483 ----------------------
14485 function Is_Bridge_Target (Id : Entity_Id) return Boolean is
14486 begin
14487 return
14488 Is_Accept_Alternative_Proc (Id)
14489 or else Is_Finalizer_Proc (Id)
14490 or else Is_Partial_Invariant_Proc (Id)
14491 or else Is_TSS (Id, TSS_Deep_Adjust)
14492 or else Is_TSS (Id, TSS_Deep_Finalize)
14493 or else Is_TSS (Id, TSS_Deep_Initialize);
14494 end Is_Bridge_Target;
14496 ------------------------
14497 -- Is_Controlled_Proc --
14498 ------------------------
14500 function Is_Controlled_Proc
14501 (Subp_Id : Entity_Id;
14502 Subp_Nam : Name_Id) return Boolean
14504 Formal_Id : Entity_Id;
14506 begin
14507 pragma Assert
14508 (Subp_Nam in Name_Adjust | Name_Finalize | Name_Initialize);
14510 -- To qualify, the subprogram must denote a source procedure with
14511 -- name Adjust, Finalize, or Initialize where the sole formal is
14512 -- controlled.
14514 if Comes_From_Source (Subp_Id)
14515 and then Ekind (Subp_Id) = E_Procedure
14516 and then Chars (Subp_Id) = Subp_Nam
14517 then
14518 Formal_Id := First_Formal (Subp_Id);
14520 return
14521 Present (Formal_Id)
14522 and then Is_Controlled (Etype (Formal_Id))
14523 and then No (Next_Formal (Formal_Id));
14524 end if;
14526 return False;
14527 end Is_Controlled_Proc;
14529 ---------------------------------------
14530 -- Is_Default_Initial_Condition_Proc --
14531 ---------------------------------------
14533 function Is_Default_Initial_Condition_Proc
14534 (Id : Entity_Id) return Boolean
14536 begin
14537 -- To qualify, the entity must denote a Default_Initial_Condition
14538 -- procedure.
14540 return Ekind (Id) = E_Procedure and then Is_DIC_Procedure (Id);
14541 end Is_Default_Initial_Condition_Proc;
14543 -----------------------
14544 -- Is_Finalizer_Proc --
14545 -----------------------
14547 function Is_Finalizer_Proc (Id : Entity_Id) return Boolean is
14548 begin
14549 -- To qualify, the entity must denote a _Finalizer procedure
14551 return Ekind (Id) = E_Procedure and then Chars (Id) = Name_uFinalizer;
14552 end Is_Finalizer_Proc;
14554 -------------------------------
14555 -- Is_Initial_Condition_Proc --
14556 -------------------------------
14558 function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean is
14559 begin
14560 -- To qualify, the entity must denote an Initial_Condition procedure
14562 return
14563 Ekind (Id) = E_Procedure
14564 and then Is_Initial_Condition_Procedure (Id);
14565 end Is_Initial_Condition_Proc;
14567 --------------------
14568 -- Is_Initialized --
14569 --------------------
14571 function Is_Initialized (Obj_Decl : Node_Id) return Boolean is
14572 begin
14573 -- To qualify, the object declaration must have an expression
14575 return
14576 Present (Expression (Obj_Decl))
14577 or else Has_Init_Expression (Obj_Decl);
14578 end Is_Initialized;
14580 -----------------------
14581 -- Is_Invariant_Proc --
14582 -----------------------
14584 function Is_Invariant_Proc (Id : Entity_Id) return Boolean is
14585 begin
14586 -- To qualify, the entity must denote the "full" invariant procedure
14588 return Ekind (Id) = E_Procedure and then Is_Invariant_Procedure (Id);
14589 end Is_Invariant_Proc;
14591 ---------------------------------------
14592 -- Is_Non_Library_Level_Encapsulator --
14593 ---------------------------------------
14595 function Is_Non_Library_Level_Encapsulator
14596 (N : Node_Id) return Boolean
14598 begin
14599 case Nkind (N) is
14600 when N_Abstract_Subprogram_Declaration
14601 | N_Aspect_Specification
14602 | N_Component_Declaration
14603 | N_Entry_Body
14604 | N_Entry_Declaration
14605 | N_Expression_Function
14606 | N_Formal_Abstract_Subprogram_Declaration
14607 | N_Formal_Concrete_Subprogram_Declaration
14608 | N_Formal_Object_Declaration
14609 | N_Formal_Package_Declaration
14610 | N_Formal_Type_Declaration
14611 | N_Generic_Association
14612 | N_Implicit_Label_Declaration
14613 | N_Incomplete_Type_Declaration
14614 | N_Private_Extension_Declaration
14615 | N_Private_Type_Declaration
14616 | N_Protected_Body
14617 | N_Protected_Type_Declaration
14618 | N_Single_Protected_Declaration
14619 | N_Single_Task_Declaration
14620 | N_Subprogram_Body
14621 | N_Subprogram_Declaration
14622 | N_Task_Body
14623 | N_Task_Type_Declaration
14625 return True;
14627 when others =>
14628 return Is_Generic_Declaration_Or_Body (N);
14629 end case;
14630 end Is_Non_Library_Level_Encapsulator;
14632 -------------------------------
14633 -- Is_Partial_Invariant_Proc --
14634 -------------------------------
14636 function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean is
14637 begin
14638 -- To qualify, the entity must denote the "partial" invariant
14639 -- procedure.
14641 return
14642 Ekind (Id) = E_Procedure
14643 and then Is_Partial_Invariant_Procedure (Id);
14644 end Is_Partial_Invariant_Proc;
14646 ---------------------------
14647 -- Is_Preelaborated_Unit --
14648 ---------------------------
14650 function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean is
14651 begin
14652 return
14653 Is_Preelaborated (Id)
14654 or else Is_Pure (Id)
14655 or else Is_Remote_Call_Interface (Id)
14656 or else Is_Remote_Types (Id)
14657 or else Is_Shared_Passive (Id);
14658 end Is_Preelaborated_Unit;
14660 ------------------------
14661 -- Is_Protected_Entry --
14662 ------------------------
14664 function Is_Protected_Entry (Id : Entity_Id) return Boolean is
14665 begin
14666 -- To qualify, the entity must denote an entry defined in a protected
14667 -- type.
14669 return
14670 Is_Entry (Id)
14671 and then Is_Protected_Type (Non_Private_View (Scope (Id)));
14672 end Is_Protected_Entry;
14674 -----------------------
14675 -- Is_Protected_Subp --
14676 -----------------------
14678 function Is_Protected_Subp (Id : Entity_Id) return Boolean is
14679 begin
14680 -- To qualify, the entity must denote a subprogram defined within a
14681 -- protected type.
14683 return
14684 Ekind (Id) in E_Function | E_Procedure
14685 and then Is_Protected_Type (Non_Private_View (Scope (Id)));
14686 end Is_Protected_Subp;
14688 ----------------------------
14689 -- Is_Protected_Body_Subp --
14690 ----------------------------
14692 function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean is
14693 begin
14694 -- To qualify, the entity must denote a subprogram with attribute
14695 -- Protected_Subprogram set.
14697 return
14698 Ekind (Id) in E_Function | E_Procedure
14699 and then Present (Protected_Subprogram (Id));
14700 end Is_Protected_Body_Subp;
14702 -----------------
14703 -- Is_Scenario --
14704 -----------------
14706 function Is_Scenario (N : Node_Id) return Boolean is
14707 begin
14708 case Nkind (N) is
14709 when N_Assignment_Statement
14710 | N_Attribute_Reference
14711 | N_Call_Marker
14712 | N_Entry_Call_Statement
14713 | N_Expanded_Name
14714 | N_Function_Call
14715 | N_Function_Instantiation
14716 | N_Identifier
14717 | N_Package_Instantiation
14718 | N_Procedure_Call_Statement
14719 | N_Procedure_Instantiation
14720 | N_Requeue_Statement
14722 return True;
14724 when others =>
14725 return False;
14726 end case;
14727 end Is_Scenario;
14729 ------------------------------
14730 -- Is_SPARK_Semantic_Target --
14731 ------------------------------
14733 function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean is
14734 begin
14735 return
14736 Is_Default_Initial_Condition_Proc (Id)
14737 or else Is_Initial_Condition_Proc (Id);
14738 end Is_SPARK_Semantic_Target;
14740 ------------------------
14741 -- Is_Subprogram_Inst --
14742 ------------------------
14744 function Is_Subprogram_Inst (Id : Entity_Id) return Boolean is
14745 begin
14746 -- To qualify, the entity must denote a function or a procedure which
14747 -- is hidden within an anonymous package, and is a generic instance.
14749 return
14750 Ekind (Id) in E_Function | E_Procedure
14751 and then Is_Hidden (Id)
14752 and then Is_Generic_Instance (Id);
14753 end Is_Subprogram_Inst;
14755 ------------------------------
14756 -- Is_Suitable_Access_Taken --
14757 ------------------------------
14759 function Is_Suitable_Access_Taken (N : Node_Id) return Boolean is
14760 Nam : Name_Id;
14761 Pref : Node_Id;
14762 Subp_Id : Entity_Id;
14764 begin
14765 -- Nothing to do when switch -gnatd.U (ignore 'Access) is in effect
14767 if Debug_Flag_Dot_UU then
14768 return False;
14770 -- Nothing to do when the scenario is not an attribute reference
14772 elsif Nkind (N) /= N_Attribute_Reference then
14773 return False;
14775 -- Nothing to do for internally-generated attributes because they are
14776 -- assumed to be ABE safe.
14778 elsif not Comes_From_Source (N) then
14779 return False;
14780 end if;
14782 Nam := Attribute_Name (N);
14783 Pref := Prefix (N);
14785 -- Sanitize the prefix of the attribute
14787 if not Is_Entity_Name (Pref) then
14788 return False;
14790 elsif No (Entity (Pref)) then
14791 return False;
14792 end if;
14794 Subp_Id := Entity (Pref);
14796 if not Is_Subprogram_Or_Entry (Subp_Id) then
14797 return False;
14798 end if;
14800 -- Traverse a possible chain of renamings to obtain the original
14801 -- entry or subprogram which the prefix may rename.
14803 Subp_Id := Get_Renamed_Entity (Subp_Id);
14805 -- To qualify, the attribute must meet the following prerequisites:
14807 return
14809 -- The prefix must denote a source entry, operator, or subprogram
14810 -- which is not imported.
14812 Comes_From_Source (Subp_Id)
14813 and then Is_Subprogram_Or_Entry (Subp_Id)
14814 and then not Is_Bodiless_Subprogram (Subp_Id)
14816 -- The attribute name must be one of the 'Access forms. Note that
14817 -- 'Unchecked_Access cannot apply to a subprogram.
14819 and then Nam in Name_Access | Name_Unrestricted_Access;
14820 end Is_Suitable_Access_Taken;
14822 ----------------------
14823 -- Is_Suitable_Call --
14824 ----------------------
14826 function Is_Suitable_Call (N : Node_Id) return Boolean is
14827 begin
14828 -- Entry and subprogram calls are intentionally ignored because they
14829 -- may undergo expansion depending on the compilation mode, previous
14830 -- errors, generic context, etc. Call markers play the role of calls
14831 -- and provide a uniform foundation for ABE processing.
14833 return Nkind (N) = N_Call_Marker;
14834 end Is_Suitable_Call;
14836 -------------------------------
14837 -- Is_Suitable_Instantiation --
14838 -------------------------------
14840 function Is_Suitable_Instantiation (N : Node_Id) return Boolean is
14841 Inst : constant Node_Id := Scenario (N);
14843 begin
14844 -- To qualify, the instantiation must come from source
14846 return
14847 Comes_From_Source (Inst)
14848 and then Nkind (Inst) in N_Generic_Instantiation;
14849 end Is_Suitable_Instantiation;
14851 ------------------------------------
14852 -- Is_Suitable_SPARK_Derived_Type --
14853 ------------------------------------
14855 function Is_Suitable_SPARK_Derived_Type (N : Node_Id) return Boolean is
14856 Prag : Node_Id;
14857 Typ : Entity_Id;
14859 begin
14860 -- To qualify, the type declaration must denote a derived tagged type
14861 -- with primitive operations, subject to pragma SPARK_Mode On.
14863 if Nkind (N) = N_Full_Type_Declaration
14864 and then Nkind (Type_Definition (N)) = N_Derived_Type_Definition
14865 then
14866 Typ := Defining_Entity (N);
14867 Prag := SPARK_Pragma (Typ);
14869 return
14870 Is_Tagged_Type (Typ)
14871 and then Has_Primitive_Operations (Typ)
14872 and then Present (Prag)
14873 and then Get_SPARK_Mode_From_Annotation (Prag) = On;
14874 end if;
14876 return False;
14877 end Is_Suitable_SPARK_Derived_Type;
14879 -------------------------------------
14880 -- Is_Suitable_SPARK_Instantiation --
14881 -------------------------------------
14883 function Is_Suitable_SPARK_Instantiation (N : Node_Id) return Boolean is
14884 Inst : constant Node_Id := Scenario (N);
14886 Gen_Id : Entity_Id;
14887 Prag : Node_Id;
14889 begin
14890 -- To qualify, both the instantiation and the generic must be subject
14891 -- to SPARK_Mode On.
14893 if Is_Suitable_Instantiation (N) then
14894 Gen_Id := Instantiated_Generic (Inst);
14895 Prag := SPARK_Pragma (Gen_Id);
14897 return
14898 Is_SPARK_Mode_On_Node (Inst)
14899 and then Present (Prag)
14900 and then Get_SPARK_Mode_From_Annotation (Prag) = On;
14901 end if;
14903 return False;
14904 end Is_Suitable_SPARK_Instantiation;
14906 --------------------------------------------
14907 -- Is_Suitable_SPARK_Refined_State_Pragma --
14908 --------------------------------------------
14910 function Is_Suitable_SPARK_Refined_State_Pragma
14911 (N : Node_Id) return Boolean
14913 begin
14914 -- To qualfy, the pragma must denote Refined_State
14916 return
14917 Nkind (N) = N_Pragma
14918 and then Pragma_Name (N) = Name_Refined_State;
14919 end Is_Suitable_SPARK_Refined_State_Pragma;
14921 -------------------------------------
14922 -- Is_Suitable_Variable_Assignment --
14923 -------------------------------------
14925 function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean is
14926 N_Unit : Node_Id;
14927 N_Unit_Id : Entity_Id;
14928 Nam : Node_Id;
14929 Var_Decl : Node_Id;
14930 Var_Id : Entity_Id;
14931 Var_Unit : Node_Id;
14932 Var_Unit_Id : Entity_Id;
14934 begin
14935 -- Nothing to do when the scenario is not an assignment
14937 if Nkind (N) /= N_Assignment_Statement then
14938 return False;
14940 -- Nothing to do for internally-generated assignments because they
14941 -- are assumed to be ABE safe.
14943 elsif not Comes_From_Source (N) then
14944 return False;
14946 -- Assignments are ignored in GNAT mode on the assumption that
14947 -- they are ABE-safe. This behavior parallels that of the old
14948 -- ABE mechanism.
14950 elsif GNAT_Mode then
14951 return False;
14952 end if;
14954 Nam := Assignment_Target (N);
14956 -- Sanitize the left hand side of the assignment
14958 if not Is_Entity_Name (Nam) then
14959 return False;
14961 elsif No (Entity (Nam)) then
14962 return False;
14963 end if;
14965 Var_Id := Entity (Nam);
14967 -- Sanitize the variable
14969 if Var_Id = Any_Id then
14970 return False;
14972 elsif Ekind (Var_Id) /= E_Variable then
14973 return False;
14974 end if;
14976 Var_Decl := Declaration_Node (Var_Id);
14978 if Nkind (Var_Decl) /= N_Object_Declaration then
14979 return False;
14980 end if;
14982 N_Unit_Id := Find_Top_Unit (N);
14983 N_Unit := Unit_Declaration_Node (N_Unit_Id);
14985 Var_Unit_Id := Find_Top_Unit (Var_Decl);
14986 Var_Unit := Unit_Declaration_Node (Var_Unit_Id);
14988 -- To qualify, the assignment must meet the following prerequisites:
14990 return
14991 Comes_From_Source (Var_Id)
14993 -- The variable must be declared in the spec of compilation unit
14994 -- U.
14996 and then Nkind (Var_Unit) = N_Package_Declaration
14997 and then Find_Enclosing_Level (Var_Decl) = Library_Spec_Level
14999 -- The assignment must occur in the body of compilation unit U
15001 and then Nkind (N_Unit) = N_Package_Body
15002 and then Present (Corresponding_Body (Var_Unit))
15003 and then Corresponding_Body (Var_Unit) = N_Unit_Id;
15004 end Is_Suitable_Variable_Assignment;
15006 ------------------------------------
15007 -- Is_Suitable_Variable_Reference --
15008 ------------------------------------
15010 function Is_Suitable_Variable_Reference (N : Node_Id) return Boolean is
15011 begin
15012 -- Expanded names and identifiers are intentionally ignored because
15013 -- they be folded, optimized away, etc. Variable references markers
15014 -- play the role of variable references and provide a uniform
15015 -- foundation for ABE processing.
15017 return Nkind (N) = N_Variable_Reference_Marker;
15018 end Is_Suitable_Variable_Reference;
15020 -------------------
15021 -- Is_Task_Entry --
15022 -------------------
15024 function Is_Task_Entry (Id : Entity_Id) return Boolean is
15025 begin
15026 -- To qualify, the entity must denote an entry defined in a task type
15028 return
15029 Is_Entry (Id) and then Is_Task_Type (Non_Private_View (Scope (Id)));
15030 end Is_Task_Entry;
15032 ------------------------
15033 -- Is_Up_Level_Target --
15034 ------------------------
15036 function Is_Up_Level_Target
15037 (Targ_Decl : Node_Id;
15038 In_State : Processing_In_State) return Boolean
15040 Root : constant Node_Id := Root_Scenario;
15041 Root_Rep : constant Scenario_Rep_Id :=
15042 Scenario_Representation_Of (Root, In_State);
15044 begin
15045 -- The root appears within the declaratons of a block statement,
15046 -- entry body, subprogram body, or task body ignoring enclosing
15047 -- packages. The root is always within the main unit.
15049 if not In_State.Suppress_Up_Level_Targets
15050 and then Level (Root_Rep) = Declaration_Level
15051 then
15052 -- The target is within the main unit. It acts as an up-level
15053 -- target when it appears within a context which encloses the
15054 -- root.
15056 -- package body Main_Unit is
15057 -- function Func ...; -- target
15059 -- procedure Proc is
15060 -- X : ... := Func; -- root scenario
15062 if In_Extended_Main_Code_Unit (Targ_Decl) then
15063 return not In_Same_Context (Root, Targ_Decl, Nested_OK => True);
15065 -- Otherwise the target is external to the main unit which makes
15066 -- it an up-level target.
15068 else
15069 return True;
15070 end if;
15071 end if;
15073 return False;
15074 end Is_Up_Level_Target;
15075 end Semantics;
15077 ---------------------------
15078 -- Set_Elaboration_Phase --
15079 ---------------------------
15081 procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status) is
15082 begin
15083 Elaboration_Phase := Status;
15084 end Set_Elaboration_Phase;
15086 ---------------------
15087 -- SPARK_Processor --
15088 ---------------------
15090 package body SPARK_Processor is
15092 -----------------------
15093 -- Local subprograms --
15094 -----------------------
15096 procedure Process_SPARK_Derived_Type
15097 (Typ_Decl : Node_Id;
15098 Typ_Rep : Scenario_Rep_Id;
15099 In_State : Processing_In_State);
15100 pragma Inline (Process_SPARK_Derived_Type);
15101 -- Verify that the freeze node of a derived type denoted by declaration
15102 -- Typ_Decl is within the early call region of each overriding primitive
15103 -- body that belongs to the derived type (SPARK RM 7.7(8)). Typ_Rep is
15104 -- the representation of the type. In_State denotes the current state of
15105 -- the Processing phase.
15107 procedure Process_SPARK_Instantiation
15108 (Inst : Node_Id;
15109 Inst_Rep : Scenario_Rep_Id;
15110 In_State : Processing_In_State);
15111 pragma Inline (Process_SPARK_Instantiation);
15112 -- Verify that instantiation Inst does not precede the generic body it
15113 -- instantiates (SPARK RM 7.7(6)). Inst_Rep is the representation of the
15114 -- instantiation. In_State is the current state of the Processing phase.
15116 procedure Process_SPARK_Refined_State_Pragma
15117 (Prag : Node_Id;
15118 Prag_Rep : Scenario_Rep_Id;
15119 In_State : Processing_In_State);
15120 pragma Inline (Process_SPARK_Refined_State_Pragma);
15121 -- Verify that each constituent of Refined_State pragma Prag which
15122 -- belongs to abstract state mentioned in pragma Initializes has prior
15123 -- elaboration with respect to the main unit (SPARK RM 7.7.1(7)).
15124 -- Prag_Rep is the representation of the pragma. In_State denotes the
15125 -- current state of the Processing phase.
15127 procedure Process_SPARK_Scenario
15128 (N : Node_Id;
15129 In_State : Processing_In_State);
15130 pragma Inline (Process_SPARK_Scenario);
15131 -- Top-level dispatcher for verifying SPARK scenarios which are not
15132 -- always executable during elaboration but still need elaboration-
15133 -- related checks. In_State is the current state of the Processing
15134 -- phase.
15136 ---------------------------------
15137 -- Check_SPARK_Model_In_Effect --
15138 ---------------------------------
15140 SPARK_Model_Warning_Posted : Boolean := False;
15141 -- This flag prevents the same SPARK model-related warning from being
15142 -- emitted multiple times.
15144 procedure Check_SPARK_Model_In_Effect is
15145 Spec_Id : constant Entity_Id := Unique_Entity (Main_Unit_Entity);
15147 begin
15148 -- Do not emit the warning multiple times as this creates useless
15149 -- noise.
15151 if SPARK_Model_Warning_Posted then
15152 null;
15154 -- SPARK rule verification requires the "strict" static model
15156 elsif Static_Elaboration_Checks
15157 and not Relaxed_Elaboration_Checks
15158 then
15159 null;
15161 -- Any other combination of models does not guarantee the absence of
15162 -- ABE problems for SPARK rule verification purposes. Note that there
15163 -- is no need to check for the presence of the legacy ABE mechanism
15164 -- because the legacy code has its own dedicated processing for SPARK
15165 -- rules.
15167 else
15168 SPARK_Model_Warning_Posted := True;
15170 Error_Msg_N
15171 ("??SPARK elaboration checks require static elaboration model",
15172 Spec_Id);
15174 if Dynamic_Elaboration_Checks then
15175 Error_Msg_N
15176 ("\dynamic elaboration model is in effect", Spec_Id);
15178 else
15179 pragma Assert (Relaxed_Elaboration_Checks);
15180 Error_Msg_N
15181 ("\relaxed elaboration model is in effect", Spec_Id);
15182 end if;
15183 end if;
15184 end Check_SPARK_Model_In_Effect;
15186 ---------------------------
15187 -- Check_SPARK_Scenarios --
15188 ---------------------------
15190 procedure Check_SPARK_Scenarios is
15191 Iter : NE_Set.Iterator;
15192 N : Node_Id;
15194 begin
15195 Iter := Iterate_SPARK_Scenarios;
15196 while NE_Set.Has_Next (Iter) loop
15197 NE_Set.Next (Iter, N);
15199 Process_SPARK_Scenario
15200 (N => N,
15201 In_State => SPARK_State);
15202 end loop;
15203 end Check_SPARK_Scenarios;
15205 --------------------------------
15206 -- Process_SPARK_Derived_Type --
15207 --------------------------------
15209 procedure Process_SPARK_Derived_Type
15210 (Typ_Decl : Node_Id;
15211 Typ_Rep : Scenario_Rep_Id;
15212 In_State : Processing_In_State)
15214 pragma Unreferenced (In_State);
15216 Typ : constant Entity_Id := Target (Typ_Rep);
15218 Stop_Check : exception;
15219 -- This exception is raised when the freeze node violates the
15220 -- placement rules.
15222 procedure Check_Overriding_Primitive
15223 (Prim : Entity_Id;
15224 FNode : Node_Id);
15225 pragma Inline (Check_Overriding_Primitive);
15226 -- Verify that freeze node FNode is within the early call region of
15227 -- overriding primitive Prim's body.
15229 function Freeze_Node_Location (FNode : Node_Id) return Source_Ptr;
15230 pragma Inline (Freeze_Node_Location);
15231 -- Return a more accurate source location associated with freeze node
15232 -- FNode.
15234 function Precedes_Source_Construct (N : Node_Id) return Boolean;
15235 pragma Inline (Precedes_Source_Construct);
15236 -- Determine whether arbitrary node N appears prior to some source
15237 -- construct.
15239 procedure Suggest_Elaborate_Body
15240 (N : Node_Id;
15241 Body_Decl : Node_Id;
15242 Error_Nod : Node_Id);
15243 pragma Inline (Suggest_Elaborate_Body);
15244 -- Suggest the use of pragma Elaborate_Body when the pragma will
15245 -- allow for node N to appear within the early call region of
15246 -- subprogram body Body_Decl. The suggestion is attached to
15247 -- Error_Nod as a continuation error.
15249 --------------------------------
15250 -- Check_Overriding_Primitive --
15251 --------------------------------
15253 procedure Check_Overriding_Primitive
15254 (Prim : Entity_Id;
15255 FNode : Node_Id)
15257 Prim_Decl : constant Node_Id := Unit_Declaration_Node (Prim);
15258 Body_Decl : Node_Id;
15259 Body_Id : Entity_Id;
15260 Region : Node_Id;
15262 begin
15263 -- Nothing to do for predefined primitives because they are
15264 -- artifacts of tagged type expansion and cannot override source
15265 -- primitives. Nothing to do as well for inherited primitives, as
15266 -- the check concerns overriding ones. Finally, nothing to do for
15267 -- abstract subprograms, because they have no body that could be
15268 -- examined.
15270 if Is_Predefined_Dispatching_Operation (Prim)
15271 or else not Is_Overriding_Subprogram (Prim)
15272 or else Is_Abstract_Subprogram (Prim)
15273 then
15274 return;
15275 end if;
15277 Body_Id := Corresponding_Body (Prim_Decl);
15279 -- Nothing to do when the primitive does not have a corresponding
15280 -- body. This can happen when the unit with the bodies is not the
15281 -- main unit subjected to ABE checks.
15283 if No (Body_Id) then
15284 return;
15286 -- The primitive overrides a parent or progenitor primitive
15288 elsif Present (Overridden_Operation (Prim)) then
15290 -- Nothing to do when overriding an interface primitive happens
15291 -- by inheriting a non-interface primitive as the check would
15292 -- be done on the parent primitive.
15294 if Present (Alias (Prim)) then
15295 return;
15296 end if;
15298 -- Nothing to do when the primitive is not overriding. The body of
15299 -- such a primitive cannot be targeted by a dispatching call which
15300 -- is executable during elaboration, and cannot cause an ABE.
15302 else
15303 return;
15304 end if;
15306 Body_Decl := Unit_Declaration_Node (Body_Id);
15307 Region := Find_Early_Call_Region (Body_Decl);
15309 -- The freeze node appears prior to the early call region of the
15310 -- primitive body.
15312 -- IMPORTANT: This check must always be performed even when
15313 -- -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
15314 -- specified because the static model cannot guarantee the absence
15315 -- of ABEs in the presence of dispatching calls.
15317 if Earlier_In_Extended_Unit (FNode, Region) then
15318 Error_Msg_Node_2 := Prim;
15319 Error_Msg_Code := GEC_Type_Early_Call_Region;
15320 Error_Msg_NE
15321 ("first freezing point of type & must appear within early "
15322 & "call region of primitive body '[[]']",
15323 Typ_Decl, Typ);
15325 Error_Msg_Sloc := Sloc (Region);
15326 Error_Msg_N ("\region starts #", Typ_Decl);
15328 Error_Msg_Sloc := Sloc (Body_Decl);
15329 Error_Msg_N ("\region ends #", Typ_Decl);
15331 Error_Msg_Sloc := Freeze_Node_Location (FNode);
15332 Error_Msg_N ("\first freezing point #", Typ_Decl);
15334 -- If applicable, suggest the use of pragma Elaborate_Body in
15335 -- the associated package spec.
15337 Suggest_Elaborate_Body
15338 (N => FNode,
15339 Body_Decl => Body_Decl,
15340 Error_Nod => Typ_Decl);
15342 raise Stop_Check;
15343 end if;
15344 end Check_Overriding_Primitive;
15346 --------------------------
15347 -- Freeze_Node_Location --
15348 --------------------------
15350 function Freeze_Node_Location (FNode : Node_Id) return Source_Ptr is
15351 Context : constant Node_Id := Parent (FNode);
15352 Loc : constant Source_Ptr := Sloc (FNode);
15354 Prv_Decls : List_Id;
15355 Vis_Decls : List_Id;
15357 begin
15358 -- In general, the source location of the freeze node is as close
15359 -- as possible to the real freeze point, except when the freeze
15360 -- node is at the "bottom" of a package spec.
15362 if Nkind (Context) = N_Package_Specification then
15363 Prv_Decls := Private_Declarations (Context);
15364 Vis_Decls := Visible_Declarations (Context);
15366 -- The freeze node appears in the private declarations of the
15367 -- package.
15369 if Present (Prv_Decls)
15370 and then List_Containing (FNode) = Prv_Decls
15371 then
15372 null;
15374 -- The freeze node appears in the visible declarations of the
15375 -- package and there are no private declarations.
15377 elsif Present (Vis_Decls)
15378 and then List_Containing (FNode) = Vis_Decls
15379 and then Is_Empty_List (Prv_Decls)
15380 then
15381 null;
15383 -- Otherwise the freeze node is not in the "last" declarative
15384 -- list of the package. Use the existing source location of the
15385 -- freeze node.
15387 else
15388 return Loc;
15389 end if;
15391 -- The freeze node appears at the "bottom" of the package when
15392 -- it is in the "last" declarative list and is either the last
15393 -- in the list or is followed by internal constructs only. In
15394 -- that case the more appropriate source location is that of
15395 -- the package end label.
15397 if not Precedes_Source_Construct (FNode) then
15398 return Sloc (End_Label (Context));
15399 end if;
15400 end if;
15402 return Loc;
15403 end Freeze_Node_Location;
15405 -------------------------------
15406 -- Precedes_Source_Construct --
15407 -------------------------------
15409 function Precedes_Source_Construct (N : Node_Id) return Boolean is
15410 Decl : Node_Id;
15412 begin
15413 Decl := Next (N);
15414 while Present (Decl) loop
15415 if Comes_From_Source (Decl) then
15416 return True;
15418 -- A generated body for a source expression function is treated
15419 -- as a source construct.
15421 elsif Nkind (Decl) = N_Subprogram_Body
15422 and then Was_Expression_Function (Decl)
15423 and then Comes_From_Source (Original_Node (Decl))
15424 then
15425 return True;
15426 end if;
15428 Next (Decl);
15429 end loop;
15431 return False;
15432 end Precedes_Source_Construct;
15434 ----------------------------
15435 -- Suggest_Elaborate_Body --
15436 ----------------------------
15438 procedure Suggest_Elaborate_Body
15439 (N : Node_Id;
15440 Body_Decl : Node_Id;
15441 Error_Nod : Node_Id)
15443 Unit_Id : constant Node_Id := Unit (Cunit (Main_Unit));
15444 Region : Node_Id;
15446 begin
15447 -- The suggestion applies only when the subprogram body resides in
15448 -- a compilation package body, and a pragma Elaborate_Body would
15449 -- allow for the node to appear in the early call region of the
15450 -- subprogram body. This implies that all code from the subprogram
15451 -- body up to the node is preelaborable.
15453 if Nkind (Unit_Id) = N_Package_Body then
15455 -- Find the start of the early call region again assuming that
15456 -- the package spec has pragma Elaborate_Body. Note that the
15457 -- internal data structures are intentionally not updated
15458 -- because this is a speculative search.
15460 Region :=
15461 Find_Early_Call_Region
15462 (Body_Decl => Body_Decl,
15463 Assume_Elab_Body => True,
15464 Skip_Memoization => True);
15466 -- If the node appears within the early call region, assuming
15467 -- that the package spec carries pragma Elaborate_Body, then it
15468 -- is safe to suggest the pragma.
15470 if Earlier_In_Extended_Unit (Region, N) then
15471 Error_Msg_Name_1 := Name_Elaborate_Body;
15472 Error_Msg_NE
15473 ("\consider adding pragma % in spec of unit &",
15474 Error_Nod, Defining_Entity (Unit_Id));
15475 end if;
15476 end if;
15477 end Suggest_Elaborate_Body;
15479 -- Local variables
15481 FNode : constant Node_Id := Freeze_Node (Typ);
15482 Prims : constant Elist_Id := Direct_Primitive_Operations (Typ);
15484 Prim_Elmt : Elmt_Id;
15486 -- Start of processing for Process_SPARK_Derived_Type
15488 begin
15489 -- A type should have its freeze node set by the time SPARK scenarios
15490 -- are being verified.
15492 pragma Assert (Present (FNode));
15494 -- Verify that the freeze node of the derived type is within the
15495 -- early call region of each overriding primitive body
15496 -- (SPARK RM 7.7(8)).
15498 if Present (Prims) then
15499 Prim_Elmt := First_Elmt (Prims);
15500 while Present (Prim_Elmt) loop
15501 Check_Overriding_Primitive
15502 (Prim => Node (Prim_Elmt),
15503 FNode => FNode);
15505 Next_Elmt (Prim_Elmt);
15506 end loop;
15507 end if;
15509 exception
15510 when Stop_Check =>
15511 null;
15512 end Process_SPARK_Derived_Type;
15514 ---------------------------------
15515 -- Process_SPARK_Instantiation --
15516 ---------------------------------
15518 procedure Process_SPARK_Instantiation
15519 (Inst : Node_Id;
15520 Inst_Rep : Scenario_Rep_Id;
15521 In_State : Processing_In_State)
15523 Gen_Id : constant Entity_Id := Target (Inst_Rep);
15524 Gen_Rep : constant Target_Rep_Id :=
15525 Target_Representation_Of (Gen_Id, In_State);
15526 Body_Decl : constant Node_Id := Body_Declaration (Gen_Rep);
15528 begin
15529 -- The instantiation and the generic body are both in the main unit
15531 if Present (Body_Decl)
15532 and then In_Extended_Main_Code_Unit (Body_Decl)
15534 -- If the instantiation appears prior to the generic body, then the
15535 -- instantiation is illegal (SPARK RM 7.7(6)).
15537 -- IMPORTANT: This check must always be performed even when
15538 -- -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
15539 -- specified because the rule prevents use-before-declaration of
15540 -- objects that may precede the generic body.
15542 and then Earlier_In_Extended_Unit (Inst, Body_Decl)
15543 then
15544 Error_Msg_NE
15545 ("cannot instantiate & before body seen", Inst, Gen_Id);
15546 end if;
15547 end Process_SPARK_Instantiation;
15549 ----------------------------
15550 -- Process_SPARK_Scenario --
15551 ----------------------------
15553 procedure Process_SPARK_Scenario
15554 (N : Node_Id;
15555 In_State : Processing_In_State)
15557 Scen : constant Node_Id := Scenario (N);
15559 begin
15560 -- Ensure that a suitable elaboration model is in effect for SPARK
15561 -- rule verification.
15563 Check_SPARK_Model_In_Effect;
15565 -- Add the current scenario to the stack of active scenarios
15567 Push_Active_Scenario (Scen);
15569 -- Derived type
15571 if Is_Suitable_SPARK_Derived_Type (Scen) then
15572 Process_SPARK_Derived_Type
15573 (Typ_Decl => Scen,
15574 Typ_Rep => Scenario_Representation_Of (Scen, In_State),
15575 In_State => In_State);
15577 -- Instantiation
15579 elsif Is_Suitable_SPARK_Instantiation (Scen) then
15580 Process_SPARK_Instantiation
15581 (Inst => Scen,
15582 Inst_Rep => Scenario_Representation_Of (Scen, In_State),
15583 In_State => In_State);
15585 -- Refined_State pragma
15587 elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
15588 Process_SPARK_Refined_State_Pragma
15589 (Prag => Scen,
15590 Prag_Rep => Scenario_Representation_Of (Scen, In_State),
15591 In_State => In_State);
15592 end if;
15594 -- Remove the current scenario from the stack of active scenarios
15595 -- once all ABE diagnostics and checks have been performed.
15597 Pop_Active_Scenario (Scen);
15598 end Process_SPARK_Scenario;
15600 ----------------------------------------
15601 -- Process_SPARK_Refined_State_Pragma --
15602 ----------------------------------------
15604 procedure Process_SPARK_Refined_State_Pragma
15605 (Prag : Node_Id;
15606 Prag_Rep : Scenario_Rep_Id;
15607 In_State : Processing_In_State)
15609 pragma Unreferenced (Prag_Rep);
15611 procedure Check_SPARK_Constituent (Constit_Id : Entity_Id);
15612 pragma Inline (Check_SPARK_Constituent);
15613 -- Ensure that a single constituent Constit_Id is elaborated prior to
15614 -- the main unit.
15616 procedure Check_SPARK_Constituents (Constits : Elist_Id);
15617 pragma Inline (Check_SPARK_Constituents);
15618 -- Ensure that all constituents found in list Constits are elaborated
15619 -- prior to the main unit.
15621 procedure Check_SPARK_Initialized_State (State : Node_Id);
15622 pragma Inline (Check_SPARK_Initialized_State);
15623 -- Ensure that the constituents of single abstract state State are
15624 -- elaborated prior to the main unit.
15626 procedure Check_SPARK_Initialized_States (Pack_Id : Entity_Id);
15627 pragma Inline (Check_SPARK_Initialized_States);
15628 -- Ensure that the constituents of all abstract states which appear
15629 -- in the Initializes pragma of package Pack_Id are elaborated prior
15630 -- to the main unit.
15632 -----------------------------
15633 -- Check_SPARK_Constituent --
15634 -----------------------------
15636 procedure Check_SPARK_Constituent (Constit_Id : Entity_Id) is
15637 SM_Prag : Node_Id;
15639 begin
15640 -- Nothing to do for "null" constituents
15642 if Nkind (Constit_Id) = N_Null then
15643 return;
15645 -- Nothing to do for illegal constituents
15647 elsif Error_Posted (Constit_Id) then
15648 return;
15649 end if;
15651 SM_Prag := SPARK_Pragma (Constit_Id);
15653 -- The check applies only when the constituent is subject to
15654 -- pragma SPARK_Mode On.
15656 if Present (SM_Prag)
15657 and then Get_SPARK_Mode_From_Annotation (SM_Prag) = On
15658 then
15659 -- An external constituent of an abstract state which appears
15660 -- in the Initializes pragma of a package spec imposes an
15661 -- Elaborate requirement on the context of the main unit.
15662 -- Determine whether the context has a pragma strong enough to
15663 -- meet the requirement.
15665 -- IMPORTANT: This check is performed only when -gnatd.v
15666 -- (enforce SPARK elaboration rules in SPARK code) is in effect
15667 -- because the static model can ensure the prior elaboration of
15668 -- the unit which contains a constituent by installing implicit
15669 -- Elaborate pragma.
15671 if Debug_Flag_Dot_V then
15672 Meet_Elaboration_Requirement
15673 (N => Prag,
15674 Targ_Id => Constit_Id,
15675 Req_Nam => Name_Elaborate,
15676 In_State => In_State);
15678 -- Otherwise ensure that the unit with the external constituent
15679 -- is elaborated prior to the main unit.
15681 else
15682 Ensure_Prior_Elaboration
15683 (N => Prag,
15684 Unit_Id => Find_Top_Unit (Constit_Id),
15685 Prag_Nam => Name_Elaborate,
15686 In_State => In_State);
15687 end if;
15688 end if;
15689 end Check_SPARK_Constituent;
15691 ------------------------------
15692 -- Check_SPARK_Constituents --
15693 ------------------------------
15695 procedure Check_SPARK_Constituents (Constits : Elist_Id) is
15696 Constit_Elmt : Elmt_Id;
15698 begin
15699 if Present (Constits) then
15700 Constit_Elmt := First_Elmt (Constits);
15701 while Present (Constit_Elmt) loop
15702 Check_SPARK_Constituent (Node (Constit_Elmt));
15703 Next_Elmt (Constit_Elmt);
15704 end loop;
15705 end if;
15706 end Check_SPARK_Constituents;
15708 -----------------------------------
15709 -- Check_SPARK_Initialized_State --
15710 -----------------------------------
15712 procedure Check_SPARK_Initialized_State (State : Node_Id) is
15713 SM_Prag : Node_Id;
15714 State_Id : Entity_Id;
15716 begin
15717 -- Nothing to do for "null" initialization items
15719 if Nkind (State) = N_Null then
15720 return;
15722 -- Nothing to do for illegal states
15724 elsif Error_Posted (State) then
15725 return;
15726 end if;
15728 State_Id := Entity_Of (State);
15730 -- Sanitize the state
15732 if No (State_Id) then
15733 return;
15735 elsif Error_Posted (State_Id) then
15736 return;
15738 elsif Ekind (State_Id) /= E_Abstract_State then
15739 return;
15740 end if;
15742 -- The check is performed only when the abstract state is subject
15743 -- to SPARK_Mode On.
15745 SM_Prag := SPARK_Pragma (State_Id);
15747 if Present (SM_Prag)
15748 and then Get_SPARK_Mode_From_Annotation (SM_Prag) = On
15749 then
15750 Check_SPARK_Constituents (Refinement_Constituents (State_Id));
15751 end if;
15752 end Check_SPARK_Initialized_State;
15754 ------------------------------------
15755 -- Check_SPARK_Initialized_States --
15756 ------------------------------------
15758 procedure Check_SPARK_Initialized_States (Pack_Id : Entity_Id) is
15759 Init_Prag : constant Node_Id :=
15760 Get_Pragma (Pack_Id, Pragma_Initializes);
15762 Init : Node_Id;
15763 Inits : Node_Id;
15765 begin
15766 if Present (Init_Prag) then
15767 Inits := Expression (Get_Argument (Init_Prag, Pack_Id));
15769 -- Avoid processing a "null" initialization list. The only
15770 -- other alternative is an aggregate.
15772 if Nkind (Inits) = N_Aggregate then
15774 -- The initialization items appear in list form:
15776 -- (state1, state2)
15778 if Present (Expressions (Inits)) then
15779 Init := First (Expressions (Inits));
15780 while Present (Init) loop
15781 Check_SPARK_Initialized_State (Init);
15782 Next (Init);
15783 end loop;
15784 end if;
15786 -- The initialization items appear in associated form:
15788 -- (state1 => item1,
15789 -- state2 => (item2, item3))
15791 if Present (Component_Associations (Inits)) then
15792 Init := First (Component_Associations (Inits));
15793 while Present (Init) loop
15794 Check_SPARK_Initialized_State (Init);
15795 Next (Init);
15796 end loop;
15797 end if;
15798 end if;
15799 end if;
15800 end Check_SPARK_Initialized_States;
15802 -- Local variables
15804 Pack_Body : constant Node_Id := Find_Related_Package_Or_Body (Prag);
15806 -- Start of processing for Process_SPARK_Refined_State_Pragma
15808 begin
15809 -- Pragma Refined_State must be associated with a package body
15811 pragma Assert
15812 (Present (Pack_Body) and then Nkind (Pack_Body) = N_Package_Body);
15814 -- Verify that each external contitunent of an abstract state
15815 -- mentioned in pragma Initializes is properly elaborated.
15817 Check_SPARK_Initialized_States (Unique_Defining_Entity (Pack_Body));
15818 end Process_SPARK_Refined_State_Pragma;
15819 end SPARK_Processor;
15821 -------------------------------
15822 -- Spec_And_Body_From_Entity --
15823 -------------------------------
15825 procedure Spec_And_Body_From_Entity
15826 (Id : Entity_Id;
15827 Spec_Decl : out Node_Id;
15828 Body_Decl : out Node_Id)
15830 begin
15831 Spec_And_Body_From_Node
15832 (N => Unit_Declaration_Node (Id),
15833 Spec_Decl => Spec_Decl,
15834 Body_Decl => Body_Decl);
15835 end Spec_And_Body_From_Entity;
15837 -----------------------------
15838 -- Spec_And_Body_From_Node --
15839 -----------------------------
15841 procedure Spec_And_Body_From_Node
15842 (N : Node_Id;
15843 Spec_Decl : out Node_Id;
15844 Body_Decl : out Node_Id)
15846 Body_Id : Entity_Id;
15847 Spec_Id : Entity_Id;
15849 begin
15850 -- Assume that the construct lacks spec and body
15852 Body_Decl := Empty;
15853 Spec_Decl := Empty;
15855 -- Bodies
15857 if Nkind (N) in N_Package_Body
15858 | N_Protected_Body
15859 | N_Subprogram_Body
15860 | N_Task_Body
15861 then
15862 Spec_Id := Corresponding_Spec (N);
15864 -- The body completes a previous declaration
15866 if Present (Spec_Id) then
15867 Spec_Decl := Unit_Declaration_Node (Spec_Id);
15869 -- Otherwise the body acts as the initial declaration, and is both a
15870 -- spec and body. There is no need to look for an optional body.
15872 else
15873 Body_Decl := N;
15874 Spec_Decl := N;
15875 return;
15876 end if;
15878 -- Declarations
15880 elsif Nkind (N) in N_Entry_Declaration
15881 | N_Generic_Package_Declaration
15882 | N_Generic_Subprogram_Declaration
15883 | N_Package_Declaration
15884 | N_Protected_Type_Declaration
15885 | N_Subprogram_Declaration
15886 | N_Task_Type_Declaration
15887 then
15888 Spec_Decl := N;
15890 -- Expression function
15892 elsif Nkind (N) = N_Expression_Function then
15893 Spec_Id := Corresponding_Spec (N);
15894 pragma Assert (Present (Spec_Id));
15896 Spec_Decl := Unit_Declaration_Node (Spec_Id);
15898 -- Instantiations
15900 elsif Nkind (N) in N_Generic_Instantiation then
15901 Spec_Decl := Instance_Spec (N);
15902 pragma Assert (Present (Spec_Decl));
15904 -- Stubs
15906 elsif Nkind (N) in N_Body_Stub then
15907 Spec_Id := Corresponding_Spec_Of_Stub (N);
15909 -- The stub completes a previous declaration
15911 if Present (Spec_Id) then
15912 Spec_Decl := Unit_Declaration_Node (Spec_Id);
15914 -- Otherwise the stub acts as a spec
15916 else
15917 Spec_Decl := N;
15918 end if;
15919 end if;
15921 -- Obtain an optional or mandatory body
15923 if Present (Spec_Decl) then
15924 Body_Id := Corresponding_Body (Spec_Decl);
15926 if Present (Body_Id) then
15927 Body_Decl := Unit_Declaration_Node (Body_Id);
15928 end if;
15929 end if;
15930 end Spec_And_Body_From_Node;
15932 -------------------------------
15933 -- Static_Elaboration_Checks --
15934 -------------------------------
15936 function Static_Elaboration_Checks return Boolean is
15937 begin
15938 return not Dynamic_Elaboration_Checks;
15939 end Static_Elaboration_Checks;
15941 -----------------
15942 -- Unit_Entity --
15943 -----------------
15945 function Unit_Entity (Unit_Id : Entity_Id) return Entity_Id is
15946 function Is_Subunit (Id : Entity_Id) return Boolean;
15947 pragma Inline (Is_Subunit);
15948 -- Determine whether the entity of an initial declaration denotes a
15949 -- subunit.
15951 ----------------
15952 -- Is_Subunit --
15953 ----------------
15955 function Is_Subunit (Id : Entity_Id) return Boolean is
15956 Decl : constant Node_Id := Unit_Declaration_Node (Id);
15958 begin
15959 return
15960 Nkind (Decl) in N_Generic_Package_Declaration
15961 | N_Generic_Subprogram_Declaration
15962 | N_Package_Declaration
15963 | N_Protected_Type_Declaration
15964 | N_Subprogram_Declaration
15965 | N_Task_Type_Declaration
15966 and then Present (Corresponding_Body (Decl))
15967 and then Nkind (Parent (Unit_Declaration_Node
15968 (Corresponding_Body (Decl)))) = N_Subunit;
15969 end Is_Subunit;
15971 -- Local variables
15973 Id : Entity_Id;
15975 -- Start of processing for Unit_Entity
15977 begin
15978 Id := Unique_Entity (Unit_Id);
15980 -- Skip all subunits found in the scope chain which ends at the input
15981 -- unit.
15983 while Is_Subunit (Id) loop
15984 Id := Scope (Id);
15985 end loop;
15987 return Id;
15988 end Unit_Entity;
15990 ---------------------------------
15991 -- Update_Elaboration_Scenario --
15992 ---------------------------------
15994 procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id) is
15995 begin
15996 -- Nothing to do when the elaboration phase of the compiler is not
15997 -- active.
15999 if not Elaboration_Phase_Active then
16000 return;
16002 -- Nothing to do when the old and new scenarios are one and the same
16004 elsif Old_N = New_N then
16005 return;
16006 end if;
16008 -- A scenario is being transformed by Atree.Rewrite. Update all relevant
16009 -- internal data structures to reflect this change. This ensures that a
16010 -- potential run-time conditional ABE check or a guaranteed ABE failure
16011 -- is inserted at the proper place in the tree.
16013 if Is_Scenario (Old_N) then
16014 Replace_Scenario (Old_N, New_N);
16015 end if;
16016 end Update_Elaboration_Scenario;
16018 ---------------------------------------------------------------------------
16019 -- --
16020 -- 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 --
16021 -- --
16022 -- M E C H A N I S M --
16023 -- --
16024 ---------------------------------------------------------------------------
16026 -- This section contains the implementation of the pre-18.x legacy ABE
16027 -- mechanism. The mechanism can be activated using switch -gnatH (legacy
16028 -- elaboration checking mode enabled).
16030 -----------------------------
16031 -- Description of Approach --
16032 -----------------------------
16034 -- Every non-static call that is encountered by Sem_Res results in a call
16035 -- to Check_Elab_Call, with N being the call node, and Outer set to its
16036 -- default value of True. In addition X'Access is treated like a call
16037 -- for the access-to-procedure case, and in SPARK mode only we also
16038 -- check variable references.
16040 -- The goal of Check_Elab_Call is to determine whether or not the reference
16041 -- in question can generate an access before elaboration error (raising
16042 -- Program_Error) either by directly calling a subprogram whose body
16043 -- has not yet been elaborated, or indirectly, by calling a subprogram
16044 -- whose body has been elaborated, but which contains a call to such a
16045 -- subprogram.
16047 -- In addition, in SPARK mode, we are checking for a variable reference in
16048 -- another package, which requires an explicit Elaborate_All pragma.
16050 -- The only references that we need to look at the outer level are
16051 -- references that occur in elaboration code. There are two cases. The
16052 -- reference can be at the outer level of elaboration code, or it can
16053 -- be within another unit, e.g. the elaboration code of a subprogram.
16055 -- In the case of an elaboration call at the outer level, we must trace
16056 -- all calls to outer level routines either within the current unit or to
16057 -- other units that are with'ed. For calls within the current unit, we can
16058 -- determine if the body has been elaborated or not, and if it has not,
16059 -- then a warning is generated.
16061 -- Note that there are two subcases. If the original call directly calls a
16062 -- subprogram whose body has not been elaborated, then we know that an ABE
16063 -- will take place, and we replace the call by a raise of Program_Error.
16064 -- If the call is indirect, then we don't know that the PE will be raised,
16065 -- since the call might be guarded by a conditional. In this case we set
16066 -- Do_Elab_Check on the call so that a dynamic check is generated, and
16067 -- output a warning.
16069 -- For calls to a subprogram in a with'ed unit or a 'Access or variable
16070 -- reference (SPARK mode case), we require that a pragma Elaborate_All
16071 -- or pragma Elaborate be present, or that the referenced unit have a
16072 -- pragma Preelaborate, pragma Pure, or pragma Elaborate_Body. If none
16073 -- of these conditions is met, then a warning is generated that a pragma
16074 -- Elaborate_All may be needed (error in the SPARK case), or an implicit
16075 -- pragma is generated.
16077 -- For the case of an elaboration call at some inner level, we are
16078 -- interested in tracing only calls to subprograms at the same level, i.e.
16079 -- those that can be called during elaboration. Any calls to outer level
16080 -- routines cannot cause ABE's as a result of the original call (there
16081 -- might be an outer level call to the subprogram from outside that causes
16082 -- the ABE, but that gets analyzed separately).
16084 -- Note that we never trace calls to inner level subprograms, since these
16085 -- cannot result in ABE's unless there is an elaboration problem at a lower
16086 -- level, which will be separately detected.
16088 -- Note on pragma Elaborate. The checking here assumes that a pragma
16089 -- Elaborate on a with'ed unit guarantees that subprograms within the unit
16090 -- can be called without causing an ABE. This is not in fact the case since
16091 -- pragma Elaborate does not guarantee the transitive coverage guaranteed
16092 -- by Elaborate_All. However, we decide to trust the user in this case.
16094 --------------------------------------
16095 -- Instantiation Elaboration Errors --
16096 --------------------------------------
16098 -- A special case arises when an instantiation appears in a context that is
16099 -- known to be before the body is elaborated, e.g.
16101 -- generic package x is ...
16102 -- ...
16103 -- package xx is new x;
16104 -- ...
16105 -- package body x is ...
16107 -- In this situation it is certain that an elaboration error will occur,
16108 -- and an unconditional raise Program_Error statement is inserted before
16109 -- the instantiation, and a warning generated.
16111 -- The problem is that in this case we have no place to put the body of
16112 -- the instantiation. We can't put it in the normal place, because it is
16113 -- too early, and will cause errors to occur as a result of referencing
16114 -- entities before they are declared.
16116 -- Our approach in this case is simply to avoid creating the body of the
16117 -- instantiation in such a case. The instantiation spec is modified to
16118 -- include dummy bodies for all subprograms, so that the resulting code
16119 -- does not contain subprogram specs with no corresponding bodies.
16121 -- The following table records the recursive call chain for output in the
16122 -- Output routine. Each entry records the call node and the entity of the
16123 -- called routine. The number of entries in the table (i.e. the value of
16124 -- Elab_Call.Last) indicates the current depth of recursion and is used to
16125 -- identify the outer level.
16127 type Elab_Call_Element is record
16128 Cloc : Source_Ptr;
16129 Ent : Entity_Id;
16130 end record;
16132 package Elab_Call is new Table.Table
16133 (Table_Component_Type => Elab_Call_Element,
16134 Table_Index_Type => Int,
16135 Table_Low_Bound => 1,
16136 Table_Initial => 50,
16137 Table_Increment => 100,
16138 Table_Name => "Elab_Call");
16140 -- The following table records all calls that have been processed starting
16141 -- from an outer level call. The table prevents both infinite recursion and
16142 -- useless reanalysis of calls within the same context. The use of context
16143 -- is important because it allows for proper checks in more complex code:
16145 -- if ... then
16146 -- Call; -- requires a check
16147 -- Call; -- does not need a check thanks to the table
16148 -- elsif ... then
16149 -- Call; -- requires a check, different context
16150 -- end if;
16152 -- Call; -- requires a check, different context
16154 type Visited_Element is record
16155 Subp_Id : Entity_Id;
16156 -- The entity of the subprogram being called
16158 Context : Node_Id;
16159 -- The context where the call to the subprogram occurs
16160 end record;
16162 package Elab_Visited is new Table.Table
16163 (Table_Component_Type => Visited_Element,
16164 Table_Index_Type => Int,
16165 Table_Low_Bound => 1,
16166 Table_Initial => 200,
16167 Table_Increment => 100,
16168 Table_Name => "Elab_Visited");
16170 -- The following table records delayed calls which must be examined after
16171 -- all generic bodies have been instantiated.
16173 type Delay_Element is record
16174 N : Node_Id;
16175 -- The parameter N from the call to Check_Internal_Call. Note that this
16176 -- node may get rewritten over the delay period by expansion in the call
16177 -- case (but not in the instantiation case).
16179 E : Entity_Id;
16180 -- The parameter E from the call to Check_Internal_Call
16182 Orig_Ent : Entity_Id;
16183 -- The parameter Orig_Ent from the call to Check_Internal_Call
16185 Curscop : Entity_Id;
16186 -- The current scope of the call. This is restored when we complete the
16187 -- delayed call, so that we do this in the right scope.
16189 Outer_Scope : Entity_Id;
16190 -- Save scope of outer level call
16192 From_Elab_Code : Boolean;
16193 -- Save indication of whether this call is from elaboration code
16195 In_Task_Activation : Boolean;
16196 -- Save indication of whether this call is from a task body. Tasks are
16197 -- activated at the "begin", which is after all local procedure bodies,
16198 -- so calls to those procedures can't fail, even if they occur after the
16199 -- task body.
16201 From_SPARK_Code : Boolean;
16202 -- Save indication of whether this call is under SPARK_Mode => On
16203 end record;
16205 package Delay_Check is new Table.Table
16206 (Table_Component_Type => Delay_Element,
16207 Table_Index_Type => Int,
16208 Table_Low_Bound => 1,
16209 Table_Initial => 1000,
16210 Table_Increment => 100,
16211 Table_Name => "Delay_Check");
16213 C_Scope : Entity_Id;
16214 -- Top-level scope of current scope. Compute this only once at the outer
16215 -- level, i.e. for a call to Check_Elab_Call from outside this unit.
16217 Outer_Level_Sloc : Source_Ptr;
16218 -- Save Sloc value for outer level call node for comparisons of source
16219 -- locations. A body is too late if it appears after the *outer* level
16220 -- call, not the particular call that is being analyzed.
16222 From_Elab_Code : Boolean;
16223 -- This flag shows whether the outer level call currently being examined
16224 -- is or is not in elaboration code. We are only interested in calls to
16225 -- routines in other units if this flag is True.
16227 In_Task_Activation : Boolean := False;
16228 -- This flag indicates whether we are performing elaboration checks on task
16229 -- bodies, at the point of activation. If true, we do not raise
16230 -- Program_Error for calls to local procedures, because all local bodies
16231 -- are known to be elaborated. However, we still need to trace such calls,
16232 -- because a local procedure could call a procedure in another package,
16233 -- so we might need an implicit Elaborate_All.
16235 Delaying_Elab_Checks : Boolean := True;
16236 -- This is set True till the compilation is complete, including the
16237 -- insertion of all instance bodies. Then when Check_Elab_Calls is called,
16238 -- the delay table is used to make the delayed calls and this flag is reset
16239 -- to False, so that the calls are processed.
16241 -----------------------
16242 -- Local Subprograms --
16243 -----------------------
16245 -- Note: Outer_Scope in all following specs represents the scope of
16246 -- interest of the outer level call. If it is set to Standard_Standard,
16247 -- then it means the outer level call was at elaboration level, and that
16248 -- thus all calls are of interest. If it was set to some other scope,
16249 -- then the original call was an inner call, and we are not interested
16250 -- in calls that go outside this scope.
16252 procedure Activate_Elaborate_All_Desirable (N : Node_Id; U : Entity_Id);
16253 -- Analysis of construct N shows that we should set Elaborate_All_Desirable
16254 -- for the WITH clause for unit U (which will always be present). A special
16255 -- case is when N is a function or procedure instantiation, in which case
16256 -- it is sufficient to set Elaborate_Desirable, since in this case there is
16257 -- no possibility of transitive elaboration issues.
16259 procedure Check_A_Call
16260 (N : Node_Id;
16261 E : Entity_Id;
16262 Outer_Scope : Entity_Id;
16263 Inter_Unit_Only : Boolean;
16264 Generate_Warnings : Boolean := True;
16265 In_Init_Proc : Boolean := False);
16266 -- This is the internal recursive routine that is called to check for
16267 -- possible elaboration error. The argument N is a subprogram call or
16268 -- generic instantiation, or 'Access attribute reference to be checked, and
16269 -- E is the entity of the called subprogram, or instantiated generic unit,
16270 -- or subprogram referenced by 'Access.
16272 -- In SPARK mode, N can also be a variable reference, since in SPARK this
16273 -- also triggers a requirement for Elaborate_All, and in this case E is the
16274 -- entity being referenced.
16276 -- Outer_Scope is the outer level scope for the original reference.
16277 -- Inter_Unit_Only is set if the call is only to be checked in the
16278 -- case where it is to another unit (and skipped if within a unit).
16279 -- Generate_Warnings is set to False to suppress warning messages about
16280 -- missing pragma Elaborate_All's. These messages are not wanted for
16281 -- inner calls in the dynamic model. Note that an instance of the Access
16282 -- attribute applied to a subprogram also generates a call to this
16283 -- procedure (since the referenced subprogram may be called later
16284 -- indirectly). Flag In_Init_Proc should be set whenever the current
16285 -- context is a type init proc.
16287 -- Note: this might better be called Check_A_Reference to recognize the
16288 -- variable case for SPARK, but we prefer to retain the historical name
16289 -- since in practice this is mostly about checking calls for the possible
16290 -- occurrence of an access-before-elaboration exception.
16292 procedure Check_Bad_Instantiation (N : Node_Id);
16293 -- N is a node for an instantiation (if called with any other node kind,
16294 -- Check_Bad_Instantiation ignores the call). This subprogram checks for
16295 -- the special case of a generic instantiation of a generic spec in the
16296 -- same declarative part as the instantiation where a body is present and
16297 -- has not yet been seen. This is an obvious error, but needs to be checked
16298 -- specially at the time of the instantiation, since it is a case where we
16299 -- cannot insert the body anywhere. If this case is detected, warnings are
16300 -- generated, and a raise of Program_Error is inserted. In addition any
16301 -- subprograms in the generic spec are stubbed, and the Bad_Instantiation
16302 -- flag is set on the instantiation node. The caller in Sem_Ch12 uses this
16303 -- flag as an indication that no attempt should be made to insert an
16304 -- instance body.
16306 procedure Check_Internal_Call
16307 (N : Node_Id;
16308 E : Entity_Id;
16309 Outer_Scope : Entity_Id;
16310 Orig_Ent : Entity_Id);
16311 -- N is a function call or procedure statement call node and E is the
16312 -- entity of the called function, which is within the current compilation
16313 -- unit (where subunits count as part of the parent). This call checks if
16314 -- this call, or any call within any accessed body could cause an ABE, and
16315 -- if so, outputs a warning. Orig_Ent differs from E only in the case of
16316 -- renamings, and points to the original name of the entity. This is used
16317 -- for error messages. Outer_Scope is the outer level scope for the
16318 -- original call.
16320 procedure Check_Internal_Call_Continue
16321 (N : Node_Id;
16322 E : Entity_Id;
16323 Outer_Scope : Entity_Id;
16324 Orig_Ent : Entity_Id);
16325 -- The processing for Check_Internal_Call is divided up into two phases,
16326 -- and this represents the second phase. The second phase is delayed if
16327 -- Delaying_Elab_Checks is set to True. In this delayed case, the first
16328 -- phase makes an entry in the Delay_Check table, which is processed when
16329 -- Check_Elab_Calls is called. N, E and Orig_Ent are as for the call to
16330 -- Check_Internal_Call. Outer_Scope is the outer level scope for the
16331 -- original call.
16333 function Get_Referenced_Ent (N : Node_Id) return Entity_Id;
16334 -- N is either a function or procedure call or an access attribute that
16335 -- references a subprogram. This call retrieves the relevant entity. If
16336 -- this is a call to a protected subprogram, the entity is a selected
16337 -- component. The callable entity may be absent, in which case Empty is
16338 -- returned. This happens with non-analyzed calls in nested generics.
16340 -- If SPARK_Mode is On, then N can also be a reference to an E_Variable
16341 -- entity, in which case, the value returned is simply this entity.
16343 function Has_Generic_Body (N : Node_Id) return Boolean;
16344 -- N is a generic package instantiation node, and this routine determines
16345 -- if this package spec does in fact have a generic body. If so, then
16346 -- True is returned, otherwise False. Note that this is not at all the
16347 -- same as checking if the unit requires a body, since it deals with
16348 -- the case of optional bodies accurately (i.e. if a body is optional,
16349 -- then it looks to see if a body is actually present). Note: this
16350 -- function can only do a fully correct job if in generating code mode
16351 -- where all bodies have to be present. If we are operating in semantics
16352 -- check only mode, then in some cases of optional bodies, a result of
16353 -- False may incorrectly be given. In practice this simply means that
16354 -- some cases of warnings for incorrect order of elaboration will only
16355 -- be given when generating code, which is not a big problem (and is
16356 -- inevitable, given the optional body semantics of Ada).
16358 procedure Insert_Elab_Check (N : Node_Id; C : Node_Id := Empty);
16359 -- Given code for an elaboration check (or unconditional raise if the check
16360 -- is not needed), inserts the code in the appropriate place. N is the call
16361 -- or instantiation node for which the check code is required. C is the
16362 -- test whose failure triggers the raise.
16364 function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean;
16365 -- Returns True if node N is a call to a generic formal subprogram
16367 function Is_Finalization_Procedure (Id : Entity_Id) return Boolean;
16368 -- Determine whether entity Id denotes a [Deep_]Finalize procedure
16370 procedure Output_Calls
16371 (N : Node_Id;
16372 Check_Elab_Flag : Boolean);
16373 -- Outputs chain of calls stored in the Elab_Call table. The caller has
16374 -- already generated the main warning message, so the warnings generated
16375 -- are all continuation messages. The argument is the call node at which
16376 -- the messages are to be placed. When Check_Elab_Flag is set, calls are
16377 -- enumerated only when flag Elab_Warning is set for the dynamic case or
16378 -- when flag Elab_Info_Messages is set for the static case.
16380 function Same_Elaboration_Scope (Scop1, Scop2 : Entity_Id) return Boolean;
16381 -- Given two scopes, determine whether they are the same scope from an
16382 -- elaboration point of view, i.e. packages and blocks are ignored.
16384 procedure Set_C_Scope;
16385 -- On entry C_Scope is set to some scope. On return, C_Scope is reset
16386 -- to be the enclosing compilation unit of this scope.
16388 procedure Set_Elaboration_Constraint
16389 (Call : Node_Id;
16390 Subp : Entity_Id;
16391 Scop : Entity_Id);
16392 -- The current unit U may depend semantically on some unit P that is not
16393 -- in the current context. If there is an elaboration call that reaches P,
16394 -- we need to indicate that P requires an Elaborate_All, but this is not
16395 -- effective in U's ali file, if there is no with_clause for P. In this
16396 -- case we add the Elaborate_All on the unit Q that directly or indirectly
16397 -- makes P available. This can happen in two cases:
16399 -- a) Q declares a subtype of a type declared in P, and the call is an
16400 -- initialization call for an object of that subtype.
16402 -- b) Q declares an object of some tagged type whose root type is
16403 -- declared in P, and the initialization call uses object notation on
16404 -- that object to reach a primitive operation or a classwide operation
16405 -- declared in P.
16407 -- If P appears in the context of U, the current processing is correct.
16408 -- Otherwise we must identify these two cases to retrieve Q and place the
16409 -- Elaborate_All_Desirable on it.
16411 function Spec_Entity (E : Entity_Id) return Entity_Id;
16412 -- Given a compilation unit entity, if it is a spec entity, it is returned
16413 -- unchanged. If it is a body entity, then the spec for the corresponding
16414 -- spec is returned
16416 function Within (E1, E2 : Entity_Id) return Boolean;
16417 -- Given two scopes E1 and E2, returns True if E1 is equal to E2, or is one
16418 -- of its contained scopes, False otherwise.
16420 function Within_Elaborate_All
16421 (Unit : Unit_Number_Type;
16422 E : Entity_Id) return Boolean;
16423 -- Return True if we are within the scope of an Elaborate_All for E, or if
16424 -- we are within the scope of an Elaborate_All for some other unit U, and U
16425 -- with's E. This prevents spurious warnings when the called entity is
16426 -- renamed within U, or in case of generic instances.
16428 --------------------------------------
16429 -- Activate_Elaborate_All_Desirable --
16430 --------------------------------------
16432 procedure Activate_Elaborate_All_Desirable (N : Node_Id; U : Entity_Id) is
16433 UN : constant Unit_Number_Type := Get_Code_Unit (N);
16434 CU : constant Node_Id := Cunit (UN);
16435 UE : constant Entity_Id := Cunit_Entity (UN);
16436 Unm : constant Unit_Name_Type := Unit_Name (UN);
16437 CI : constant List_Id := Context_Items (CU);
16438 Itm : Node_Id;
16439 Ent : Entity_Id;
16441 procedure Add_To_Context_And_Mark (Itm : Node_Id);
16442 -- This procedure is called when the elaborate indication must be
16443 -- applied to a unit not in the context of the referencing unit. The
16444 -- unit gets added to the context as an implicit with.
16446 function In_Withs_Of (UEs : Entity_Id) return Boolean;
16447 -- UEs is the spec entity of a unit. If the unit to be marked is
16448 -- in the context item list of this unit spec, then the call returns
16449 -- True and Itm is left set to point to the relevant N_With_Clause node.
16451 procedure Set_Elab_Flag (Itm : Node_Id);
16452 -- Sets Elaborate_[All_]Desirable as appropriate on Itm
16454 -----------------------------
16455 -- Add_To_Context_And_Mark --
16456 -----------------------------
16458 procedure Add_To_Context_And_Mark (Itm : Node_Id) is
16459 CW : constant Node_Id :=
16460 Make_With_Clause (Sloc (Itm),
16461 Name => Name (Itm));
16463 begin
16464 Set_Library_Unit (CW, Library_Unit (Itm));
16465 Set_Implicit_With (CW);
16467 -- Set elaborate all desirable on copy and then append the copy to
16468 -- the list of body with's and we are done.
16470 Set_Elab_Flag (CW);
16471 Append_To (CI, CW);
16472 end Add_To_Context_And_Mark;
16474 -----------------
16475 -- In_Withs_Of --
16476 -----------------
16478 function In_Withs_Of (UEs : Entity_Id) return Boolean is
16479 UNs : constant Unit_Number_Type := Get_Source_Unit (UEs);
16480 CUs : constant Node_Id := Cunit (UNs);
16481 CIs : constant List_Id := Context_Items (CUs);
16483 begin
16484 Itm := First (CIs);
16485 while Present (Itm) loop
16486 if Nkind (Itm) = N_With_Clause then
16487 Ent :=
16488 Cunit_Entity (Get_Cunit_Unit_Number (Library_Unit (Itm)));
16490 if U = Ent then
16491 return True;
16492 end if;
16493 end if;
16495 Next (Itm);
16496 end loop;
16498 return False;
16499 end In_Withs_Of;
16501 -------------------
16502 -- Set_Elab_Flag --
16503 -------------------
16505 procedure Set_Elab_Flag (Itm : Node_Id) is
16506 begin
16507 if Nkind (N) in N_Subprogram_Instantiation then
16508 Set_Elaborate_Desirable (Itm);
16509 else
16510 Set_Elaborate_All_Desirable (Itm);
16511 end if;
16512 end Set_Elab_Flag;
16514 -- Start of processing for Activate_Elaborate_All_Desirable
16516 begin
16517 -- Do not set binder indication if expansion is disabled, as when
16518 -- compiling a generic unit.
16520 if not Expander_Active then
16521 return;
16522 end if;
16524 -- If an instance of a generic package contains a controlled object (so
16525 -- we're calling Initialize at elaboration time), and the instance is in
16526 -- a package body P that says "with P;", then we need to return without
16527 -- adding "pragma Elaborate_All (P);" to P.
16529 if U = Main_Unit_Entity then
16530 return;
16531 end if;
16533 Itm := First (CI);
16534 while Present (Itm) loop
16535 if Nkind (Itm) = N_With_Clause then
16536 Ent := Cunit_Entity (Get_Cunit_Unit_Number (Library_Unit (Itm)));
16538 -- If we find it, then mark elaborate all desirable and return
16540 if U = Ent then
16541 Set_Elab_Flag (Itm);
16542 return;
16543 end if;
16544 end if;
16546 Next (Itm);
16547 end loop;
16549 -- If we fall through then the with clause is not present in the
16550 -- current unit. One legitimate possibility is that the with clause
16551 -- is present in the spec when we are a body.
16553 if Is_Body_Name (Unm)
16554 and then In_Withs_Of (Spec_Entity (UE))
16555 then
16556 Add_To_Context_And_Mark (Itm);
16557 return;
16558 end if;
16560 -- Similarly, we may be in the spec or body of a child unit, where
16561 -- the unit in question is with'ed by some ancestor of the child unit.
16563 if Is_Child_Name (Unm) then
16564 declare
16565 Pkg : Entity_Id;
16567 begin
16568 Pkg := UE;
16569 loop
16570 Pkg := Scope (Pkg);
16571 exit when Pkg = Standard_Standard;
16573 if In_Withs_Of (Pkg) then
16574 Add_To_Context_And_Mark (Itm);
16575 return;
16576 end if;
16577 end loop;
16578 end;
16579 end if;
16581 -- Here if we do not find with clause on spec or body. We just ignore
16582 -- this case; it means that the elaboration involves some other unit
16583 -- than the unit being compiled, and will be caught elsewhere.
16584 end Activate_Elaborate_All_Desirable;
16586 ------------------
16587 -- Check_A_Call --
16588 ------------------
16590 procedure Check_A_Call
16591 (N : Node_Id;
16592 E : Entity_Id;
16593 Outer_Scope : Entity_Id;
16594 Inter_Unit_Only : Boolean;
16595 Generate_Warnings : Boolean := True;
16596 In_Init_Proc : Boolean := False)
16598 Access_Case : constant Boolean := Nkind (N) = N_Attribute_Reference;
16599 -- Indicates if we have Access attribute case
16601 function Call_To_Instance_From_Outside (Id : Entity_Id) return Boolean;
16602 -- True if we're calling an instance of a generic subprogram, or a
16603 -- subprogram in an instance of a generic package, and the call is
16604 -- outside that instance.
16606 procedure Elab_Warning
16607 (Msg_D : String;
16608 Msg_S : String;
16609 Ent : Node_Or_Entity_Id);
16610 -- Generate a call to Error_Msg_NE with parameters Msg_D or Msg_S (for
16611 -- dynamic or static elaboration model), N and Ent. Msg_D is a real
16612 -- warning (output if Msg_D is non-null and Elab_Warnings is set),
16613 -- Msg_S is an info message (output if Elab_Info_Messages is set).
16615 function Find_W_Scope return Entity_Id;
16616 -- Find top-level scope for called entity (not following renamings
16617 -- or derivations). This is where the Elaborate_All will go if it is
16618 -- needed. We start with the called entity, except in the case of an
16619 -- initialization procedure outside the current package, where the init
16620 -- proc is in the root package, and we start from the entity of the name
16621 -- in the call.
16623 -----------------------------------
16624 -- Call_To_Instance_From_Outside --
16625 -----------------------------------
16627 function Call_To_Instance_From_Outside (Id : Entity_Id) return Boolean is
16628 Scop : Entity_Id := Id;
16630 begin
16631 loop
16632 if Scop = Standard_Standard then
16633 return False;
16634 end if;
16636 if Is_Generic_Instance (Scop) then
16637 return not In_Open_Scopes (Scop);
16638 end if;
16640 Scop := Scope (Scop);
16641 end loop;
16642 end Call_To_Instance_From_Outside;
16644 ------------------
16645 -- Elab_Warning --
16646 ------------------
16648 procedure Elab_Warning
16649 (Msg_D : String;
16650 Msg_S : String;
16651 Ent : Node_Or_Entity_Id)
16653 begin
16654 -- Dynamic elaboration checks, real warning
16656 if Dynamic_Elaboration_Checks then
16657 if not Access_Case then
16658 if Msg_D /= "" and then Elab_Warnings then
16659 Error_Msg_NE (Msg_D, N, Ent);
16660 end if;
16662 -- In the access case emit first warning message as well,
16663 -- otherwise list of calls will appear as errors.
16665 elsif Elab_Warnings then
16666 Error_Msg_NE (Msg_S, N, Ent);
16667 end if;
16669 -- Static elaboration checks, info message
16671 else
16672 if Elab_Info_Messages then
16673 Error_Msg_NE (Msg_S, N, Ent);
16674 end if;
16675 end if;
16676 end Elab_Warning;
16678 ------------------
16679 -- Find_W_Scope --
16680 ------------------
16682 function Find_W_Scope return Entity_Id is
16683 Refed_Ent : constant Entity_Id := Get_Referenced_Ent (N);
16684 W_Scope : Entity_Id;
16686 begin
16687 if Is_Init_Proc (Refed_Ent)
16688 and then not In_Same_Extended_Unit (N, Refed_Ent)
16689 then
16690 W_Scope := Scope (Refed_Ent);
16691 else
16692 W_Scope := E;
16693 end if;
16695 -- Now loop through scopes to get to the enclosing compilation unit
16697 while not Is_Compilation_Unit (W_Scope) loop
16698 W_Scope := Scope (W_Scope);
16699 end loop;
16701 return W_Scope;
16702 end Find_W_Scope;
16704 -- Local variables
16706 Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;
16707 -- Indicates if we have instantiation case
16709 Loc : constant Source_Ptr := Sloc (N);
16711 Variable_Case : constant Boolean :=
16712 Nkind (N) in N_Has_Entity
16713 and then Present (Entity (N))
16714 and then Ekind (Entity (N)) = E_Variable;
16715 -- Indicates if we have variable reference case
16717 W_Scope : constant Entity_Id := Find_W_Scope;
16718 -- Top-level scope of directly called entity for subprogram. This
16719 -- differs from E_Scope in the case where renamings or derivations
16720 -- are involved, since it does not follow these links. W_Scope is
16721 -- generally in a visible unit, and it is this scope that may require
16722 -- an Elaborate_All. However, there are some cases (initialization
16723 -- calls and calls involving object notation) where W_Scope might not
16724 -- be in the context of the current unit, and there is an intermediate
16725 -- package that is, in which case the Elaborate_All has to be placed
16726 -- on this intermediate package. These special cases are handled in
16727 -- Set_Elaboration_Constraint.
16729 Ent : Entity_Id;
16730 Callee_Unit_Internal : Boolean;
16731 Caller_Unit_Internal : Boolean;
16732 Decl : Node_Id;
16733 Inst_Callee : Source_Ptr;
16734 Inst_Caller : Source_Ptr;
16735 Unit_Callee : Unit_Number_Type;
16736 Unit_Caller : Unit_Number_Type;
16738 Body_Acts_As_Spec : Boolean;
16739 -- Set to true if call is to body acting as spec (no separate spec)
16741 Cunit_SC : Boolean := False;
16742 -- Set to suppress dynamic elaboration checks where one of the
16743 -- enclosing scopes has Elaboration_Checks_Suppressed set, or else
16744 -- if a pragma Elaborate[_All] applies to that scope, in which case
16745 -- warnings on the scope are also suppressed. For the internal case,
16746 -- we ignore this flag.
16748 E_Scope : Entity_Id;
16749 -- Top-level scope of entity for called subprogram. This value includes
16750 -- following renamings and derivations, so this scope can be in a
16751 -- non-visible unit. This is the scope that is to be investigated to
16752 -- see whether an elaboration check is required.
16754 Is_DIC : Boolean;
16755 -- Flag set when the subprogram being invoked is the procedure generated
16756 -- for pragma Default_Initial_Condition.
16758 SPARK_Elab_Errors : Boolean;
16759 -- Flag set when an entity is called or a variable is read during SPARK
16760 -- dynamic elaboration.
16762 -- Start of processing for Check_A_Call
16764 begin
16765 -- If the call is known to be within a local Suppress Elaboration
16766 -- pragma, nothing to check. This can happen in task bodies. But
16767 -- we ignore this for a call to a generic formal.
16769 if Nkind (N) in N_Subprogram_Call
16770 and then No_Elaboration_Check (N)
16771 and then not Is_Call_Of_Generic_Formal (N)
16772 then
16773 return;
16775 -- If this is a rewrite of a Valid_Scalars attribute, then nothing to
16776 -- check, we don't mind in this case if the call occurs before the body
16777 -- since this is all generated code.
16779 elsif Nkind (Original_Node (N)) = N_Attribute_Reference
16780 and then Attribute_Name (Original_Node (N)) = Name_Valid_Scalars
16781 then
16782 return;
16784 -- Intrinsics such as instances of Unchecked_Deallocation do not have
16785 -- any body, so elaboration checking is not needed, and would be wrong.
16787 elsif Is_Intrinsic_Subprogram (E) then
16788 return;
16790 -- Do not consider references to internal variables for SPARK semantics
16792 elsif Variable_Case and then not Comes_From_Source (E) then
16793 return;
16794 end if;
16796 -- Proceed with check
16798 Ent := E;
16800 -- For a variable reference, just set Body_Acts_As_Spec to False
16802 if Variable_Case then
16803 Body_Acts_As_Spec := False;
16805 -- Additional checks for all other cases
16807 else
16808 -- Go to parent for derived subprogram, or to original subprogram in
16809 -- the case of a renaming (Alias covers both these cases).
16811 loop
16812 if (Suppress_Elaboration_Warnings (Ent)
16813 or else Elaboration_Checks_Suppressed (Ent))
16814 and then (Inst_Case or else No (Alias (Ent)))
16815 then
16816 return;
16817 end if;
16819 -- Nothing to do for imported entities
16821 if Is_Imported (Ent) then
16822 return;
16823 end if;
16825 exit when Inst_Case or else No (Alias (Ent));
16826 Ent := Alias (Ent);
16827 end loop;
16829 Decl := Unit_Declaration_Node (Ent);
16831 if Nkind (Decl) = N_Subprogram_Body then
16832 Body_Acts_As_Spec := True;
16834 elsif Nkind (Decl) in
16835 N_Subprogram_Declaration | N_Subprogram_Body_Stub
16836 or else Inst_Case
16837 then
16838 Body_Acts_As_Spec := False;
16840 -- If we have none of an instantiation, subprogram body or subprogram
16841 -- declaration, or in the SPARK case, a variable reference, then
16842 -- it is not a case that we want to check. (One case is a call to a
16843 -- generic formal subprogram, where we do not want the check in the
16844 -- template).
16846 else
16847 return;
16848 end if;
16849 end if;
16851 E_Scope := Ent;
16852 loop
16853 if Elaboration_Checks_Suppressed (E_Scope)
16854 or else Suppress_Elaboration_Warnings (E_Scope)
16855 then
16856 Cunit_SC := True;
16857 end if;
16859 -- Exit when we get to compilation unit, not counting subunits
16861 exit when Is_Compilation_Unit (E_Scope)
16862 and then (Is_Child_Unit (E_Scope)
16863 or else Scope (E_Scope) = Standard_Standard);
16865 pragma Assert (E_Scope /= Standard_Standard);
16867 -- Move up a scope looking for compilation unit
16869 E_Scope := Scope (E_Scope);
16870 end loop;
16872 -- No checks needed for pure or preelaborated compilation units
16874 if Is_Pure (E_Scope) or else Is_Preelaborated (E_Scope) then
16875 return;
16876 end if;
16878 -- If the generic entity is within a deeper instance than we are, then
16879 -- either the instantiation to which we refer itself caused an ABE, in
16880 -- which case that will be handled separately, or else we know that the
16881 -- body we need appears as needed at the point of the instantiation.
16882 -- However, this assumption is only valid if we are in static mode.
16884 if not Dynamic_Elaboration_Checks
16885 and then
16886 Instantiation_Depth (Sloc (Ent)) > Instantiation_Depth (Sloc (N))
16887 then
16888 return;
16889 end if;
16891 -- Do not give a warning for a package with no body
16893 if Ekind (Ent) = E_Generic_Package and then not Has_Generic_Body (N) then
16894 return;
16895 end if;
16897 -- Case of entity is in same unit as call or instantiation. In the
16898 -- instantiation case, W_Scope may be different from E_Scope; we want
16899 -- the unit in which the instantiation occurs, since we're analyzing
16900 -- based on the expansion.
16902 if W_Scope = C_Scope then
16903 if not Inter_Unit_Only then
16904 Check_Internal_Call (N, Ent, Outer_Scope, E);
16905 end if;
16907 return;
16908 end if;
16910 -- Case of entity is not in current unit (i.e. with'ed unit case)
16912 -- We are only interested in such calls if the outer call was from
16913 -- elaboration code, or if we are in Dynamic_Elaboration_Checks mode.
16915 if not From_Elab_Code and then not Dynamic_Elaboration_Checks then
16916 return;
16917 end if;
16919 -- Nothing to do if some scope said that no checks were required
16921 if Cunit_SC then
16922 return;
16923 end if;
16925 -- Nothing to do for a generic instance, because a call to an instance
16926 -- cannot fail the elaboration check, because the body of the instance
16927 -- is always elaborated immediately after the spec.
16929 if Call_To_Instance_From_Outside (Ent) then
16930 return;
16931 end if;
16933 -- Nothing to do if subprogram with no separate spec. However, a call
16934 -- to Deep_Initialize may result in a call to a user-defined Initialize
16935 -- procedure, which imposes a body dependency. This happens only if the
16936 -- type is controlled and the Initialize procedure is not inherited.
16938 if Body_Acts_As_Spec then
16939 if Is_TSS (Ent, TSS_Deep_Initialize) then
16940 declare
16941 Typ : constant Entity_Id := Etype (First_Formal (Ent));
16942 Init : Entity_Id;
16944 begin
16945 if not Is_Controlled (Typ) then
16946 return;
16947 else
16948 Init := Find_Prim_Op (Typ, Name_Initialize);
16950 if Comes_From_Source (Init) then
16951 Ent := Init;
16952 else
16953 return;
16954 end if;
16955 end if;
16956 end;
16958 else
16959 return;
16960 end if;
16961 end if;
16963 -- Check cases of internal units
16965 Callee_Unit_Internal := In_Internal_Unit (E_Scope);
16967 -- Do not give a warning if the with'ed unit is internal and this is
16968 -- the generic instantiation case (this saves a lot of hassle dealing
16969 -- with the Text_IO special child units)
16971 if Callee_Unit_Internal and Inst_Case then
16972 return;
16973 end if;
16975 if C_Scope = Standard_Standard then
16976 Caller_Unit_Internal := False;
16977 else
16978 Caller_Unit_Internal := In_Internal_Unit (C_Scope);
16979 end if;
16981 -- Do not give a warning if the with'ed unit is internal and the caller
16982 -- is not internal (since the binder always elaborates internal units
16983 -- first).
16985 if Callee_Unit_Internal and not Caller_Unit_Internal then
16986 return;
16987 end if;
16989 -- For now, if debug flag -gnatdE is not set, do no checking for one
16990 -- internal unit withing another. This fixes the problem with the sgi
16991 -- build and storage errors. To be resolved later ???
16993 if (Callee_Unit_Internal and Caller_Unit_Internal)
16994 and not Debug_Flag_EE
16995 then
16996 return;
16997 end if;
16999 if Is_TSS (E, TSS_Deep_Initialize) then
17000 Ent := E;
17001 end if;
17003 -- If the call is in an instance, and the called entity is not
17004 -- defined in the same instance, then the elaboration issue focuses
17005 -- around the unit containing the template, it is this unit that
17006 -- requires an Elaborate_All.
17008 -- However, if we are doing dynamic elaboration, we need to chase the
17009 -- call in the usual manner.
17011 -- We also need to chase the call in the usual manner if it is a call
17012 -- to a generic formal parameter, since that case was not handled as
17013 -- part of the processing of the template.
17015 Inst_Caller := Instantiation (Get_Source_File_Index (Sloc (N)));
17016 Inst_Callee := Instantiation (Get_Source_File_Index (Sloc (Ent)));
17018 if Inst_Caller = No_Location then
17019 Unit_Caller := No_Unit;
17020 else
17021 Unit_Caller := Get_Source_Unit (N);
17022 end if;
17024 if Inst_Callee = No_Location then
17025 Unit_Callee := No_Unit;
17026 else
17027 Unit_Callee := Get_Source_Unit (Ent);
17028 end if;
17030 if Unit_Caller /= No_Unit
17031 and then Unit_Callee /= Unit_Caller
17032 and then not Dynamic_Elaboration_Checks
17033 and then not Is_Call_Of_Generic_Formal (N)
17034 then
17035 E_Scope := Spec_Entity (Cunit_Entity (Unit_Caller));
17037 -- If we don't get a spec entity, just ignore call. Not quite
17038 -- clear why this check is necessary. ???
17040 if No (E_Scope) then
17041 return;
17042 end if;
17044 -- Otherwise step to enclosing compilation unit
17046 while not Is_Compilation_Unit (E_Scope) loop
17047 E_Scope := Scope (E_Scope);
17048 end loop;
17050 -- For the case where N is not an instance, and is not a call within
17051 -- instance to other than a generic formal, we recompute E_Scope
17052 -- for the error message, since we do NOT want to go to the unit
17053 -- that has the ultimate declaration in the case of renaming and
17054 -- derivation and we also want to go to the generic unit in the
17055 -- case of an instance, and no further.
17057 else
17058 -- Loop to carefully follow renamings and derivations one step
17059 -- outside the current unit, but not further.
17061 if not (Inst_Case or Variable_Case)
17062 and then Present (Alias (Ent))
17063 then
17064 E_Scope := Alias (Ent);
17065 else
17066 E_Scope := Ent;
17067 end if;
17069 loop
17070 while not Is_Compilation_Unit (E_Scope) loop
17071 E_Scope := Scope (E_Scope);
17072 end loop;
17074 -- If E_Scope is the same as C_Scope, it means that there
17075 -- definitely was a local renaming or derivation, and we
17076 -- are not yet out of the current unit.
17078 exit when E_Scope /= C_Scope;
17079 Ent := Alias (Ent);
17080 E_Scope := Ent;
17082 -- If no alias, there could be a previous error, but not if we've
17083 -- already reached the outermost level (Standard).
17085 if No (Ent) then
17086 return;
17087 end if;
17088 end loop;
17089 end if;
17091 if Within_Elaborate_All (Current_Sem_Unit, E_Scope) then
17092 return;
17093 end if;
17095 -- Determine whether the Default_Initial_Condition procedure of some
17096 -- type is being invoked.
17098 Is_DIC := Ekind (Ent) = E_Procedure and then Is_DIC_Procedure (Ent);
17100 -- Checks related to Default_Initial_Condition fall under the SPARK
17101 -- umbrella because this is a SPARK-specific annotation.
17103 SPARK_Elab_Errors :=
17104 SPARK_Mode = On and (Is_DIC or Dynamic_Elaboration_Checks);
17106 -- Now check if an Elaborate_All (or dynamic check) is needed
17108 if (Elab_Info_Messages or Elab_Warnings or SPARK_Elab_Errors)
17109 and then Generate_Warnings
17110 and then not Suppress_Elaboration_Warnings (Ent)
17111 and then not Elaboration_Checks_Suppressed (Ent)
17112 and then not Suppress_Elaboration_Warnings (E_Scope)
17113 and then not Elaboration_Checks_Suppressed (E_Scope)
17114 then
17115 -- Instantiation case
17117 if Inst_Case then
17118 if Comes_From_Source (Ent) and then SPARK_Elab_Errors then
17119 Error_Msg_NE
17120 ("instantiation of & during elaboration in SPARK", N, Ent);
17121 else
17122 Elab_Warning
17123 ("instantiation of & may raise Program_Error?l?",
17124 "info: instantiation of & during elaboration?$?", Ent);
17125 end if;
17127 -- Indirect call case, info message only in static elaboration
17128 -- case, because the attribute reference itself cannot raise an
17129 -- exception. Note that SPARK does not permit indirect calls.
17131 elsif Access_Case then
17132 Elab_Warning ("", "info: access to & during elaboration?$?", Ent);
17134 -- Variable reference in SPARK mode
17136 elsif Variable_Case then
17137 if Comes_From_Source (Ent) and then SPARK_Elab_Errors then
17138 Error_Msg_NE
17139 ("reference to & during elaboration in SPARK", N, Ent);
17140 end if;
17142 -- Subprogram call case
17144 else
17145 if Nkind (Name (N)) in N_Has_Entity
17146 and then Is_Init_Proc (Entity (Name (N)))
17147 and then Comes_From_Source (Ent)
17148 then
17149 Elab_Warning
17150 ("implicit call to & may raise Program_Error?l?",
17151 "info: implicit call to & during elaboration?$?",
17152 Ent);
17154 elsif SPARK_Elab_Errors then
17156 -- Emit a specialized error message when the elaboration of an
17157 -- object of a private type evaluates the expression of pragma
17158 -- Default_Initial_Condition. This prevents the internal name
17159 -- of the procedure from appearing in the error message.
17161 if Is_DIC then
17162 Error_Msg_N
17163 ("call to Default_Initial_Condition during elaboration in "
17164 & "SPARK", N);
17165 else
17166 Error_Msg_NE
17167 ("call to & during elaboration in SPARK", N, Ent);
17168 end if;
17170 else
17171 Elab_Warning
17172 ("call to & may raise Program_Error?l?",
17173 "info: call to & during elaboration?$?",
17174 Ent);
17175 end if;
17176 end if;
17178 Error_Msg_Qual_Level := Nat'Last;
17180 -- Case of Elaborate_All not present and required, for SPARK this
17181 -- is an error, so give an error message.
17183 if SPARK_Elab_Errors then
17184 Error_Msg_NE -- CODEFIX
17185 ("\Elaborate_All pragma required for&", N, W_Scope);
17187 -- Otherwise we generate an implicit pragma. For a subprogram
17188 -- instantiation, Elaborate is good enough, since no transitive
17189 -- call is possible at elaboration time in this case.
17191 elsif Nkind (N) in N_Subprogram_Instantiation then
17192 Elab_Warning
17193 ("\missing pragma Elaborate for&?l?",
17194 "\implicit pragma Elaborate for& generated?$?",
17195 W_Scope);
17197 -- For all other cases, we need an implicit Elaborate_All
17199 else
17200 Elab_Warning
17201 ("\missing pragma Elaborate_All for&?l?",
17202 "\implicit pragma Elaborate_All for & generated?$?",
17203 W_Scope);
17204 end if;
17206 Error_Msg_Qual_Level := 0;
17208 -- Take into account the flags related to elaboration warning
17209 -- messages when enumerating the various calls involved. This
17210 -- ensures the proper pairing of the main warning and the
17211 -- clarification messages generated by Output_Calls.
17213 Output_Calls (N, Check_Elab_Flag => True);
17215 -- Set flag to prevent further warnings for same unit unless in
17216 -- All_Errors_Mode.
17218 if not All_Errors_Mode and not Dynamic_Elaboration_Checks then
17219 Set_Suppress_Elaboration_Warnings (W_Scope);
17220 end if;
17221 end if;
17223 -- Check for runtime elaboration check required
17225 if Dynamic_Elaboration_Checks then
17226 if not Elaboration_Checks_Suppressed (Ent)
17227 and then not Elaboration_Checks_Suppressed (W_Scope)
17228 and then not Elaboration_Checks_Suppressed (E_Scope)
17229 and then not Cunit_SC
17230 then
17231 -- Runtime elaboration check required. Generate check of the
17232 -- elaboration Boolean for the unit containing the entity.
17234 -- Note that for this case, we do check the real unit (the one
17235 -- from following renamings, since that is the issue).
17237 -- Could this possibly miss a useless but required PE???
17239 Insert_Elab_Check (N,
17240 Make_Attribute_Reference (Loc,
17241 Attribute_Name => Name_Elaborated,
17242 Prefix =>
17243 New_Occurrence_Of (Spec_Entity (E_Scope), Loc)));
17245 -- Prevent duplicate elaboration checks on the same call, which
17246 -- can happen if the body enclosing the call appears itself in a
17247 -- call whose elaboration check is delayed.
17249 if Nkind (N) in N_Subprogram_Call then
17250 Set_No_Elaboration_Check (N);
17251 end if;
17252 end if;
17254 -- Case of static elaboration model
17256 else
17257 -- Do not do anything if elaboration checks suppressed. Note that
17258 -- we check Ent here, not E, since we want the real entity for the
17259 -- body to see if checks are suppressed for it, not the dummy
17260 -- entry for renamings or derivations.
17262 if Elaboration_Checks_Suppressed (Ent)
17263 or else Elaboration_Checks_Suppressed (E_Scope)
17264 or else Elaboration_Checks_Suppressed (W_Scope)
17265 then
17266 null;
17268 -- Do not generate an Elaborate_All for finalization routines
17269 -- that perform partial clean up as part of initialization.
17271 elsif In_Init_Proc and then Is_Finalization_Procedure (Ent) then
17272 null;
17274 -- Here we need to generate an implicit elaborate all
17276 else
17277 -- Generate Elaborate_All warning unless suppressed
17279 if (Elab_Info_Messages and Generate_Warnings and not Inst_Case)
17280 and then not Suppress_Elaboration_Warnings (Ent)
17281 and then not Suppress_Elaboration_Warnings (E_Scope)
17282 and then not Suppress_Elaboration_Warnings (W_Scope)
17283 then
17284 Error_Msg_Node_2 := W_Scope;
17285 Error_Msg_NE
17286 ("info: call to& in elaboration code requires pragma "
17287 & "Elaborate_All on&?$?", N, E);
17288 end if;
17290 -- Set indication for binder to generate Elaborate_All
17292 Set_Elaboration_Constraint (N, E, W_Scope);
17293 end if;
17294 end if;
17295 end Check_A_Call;
17297 -----------------------------
17298 -- Check_Bad_Instantiation --
17299 -----------------------------
17301 procedure Check_Bad_Instantiation (N : Node_Id) is
17302 Ent : Entity_Id;
17304 begin
17305 -- Nothing to do if we do not have an instantiation (happens in some
17306 -- error cases, and also in the formal package declaration case)
17308 if Nkind (N) not in N_Generic_Instantiation then
17309 return;
17311 -- Nothing to do if serious errors detected (avoid cascaded errors)
17313 elsif Serious_Errors_Detected /= 0 then
17314 return;
17316 -- Nothing to do if not in full analysis mode
17318 elsif not Full_Analysis then
17319 return;
17321 -- Nothing to do if inside a generic template
17323 elsif Inside_A_Generic then
17324 return;
17326 -- Nothing to do if a library level instantiation
17328 elsif Nkind (Parent (N)) = N_Compilation_Unit then
17329 return;
17331 -- Nothing to do if we are compiling a proper body for semantic
17332 -- purposes only. The generic body may be in another proper body.
17334 elsif
17335 Nkind (Parent (Unit_Declaration_Node (Main_Unit_Entity))) = N_Subunit
17336 then
17337 return;
17338 end if;
17340 Ent := Get_Generic_Entity (N);
17342 -- The case we are interested in is when the generic spec is in the
17343 -- current declarative part
17345 if not Same_Elaboration_Scope (Current_Scope, Scope (Ent))
17346 or else not In_Same_Extended_Unit (N, Ent)
17347 then
17348 return;
17349 end if;
17351 -- If the generic entity is within a deeper instance than we are, then
17352 -- either the instantiation to which we refer itself caused an ABE, in
17353 -- which case that will be handled separately. Otherwise, we know that
17354 -- the body we need appears as needed at the point of the instantiation.
17355 -- If they are both at the same level but not within the same instance
17356 -- then the body of the generic will be in the earlier instance.
17358 declare
17359 D1 : constant Nat := Instantiation_Depth (Sloc (Ent));
17360 D2 : constant Nat := Instantiation_Depth (Sloc (N));
17362 begin
17363 if D1 > D2 then
17364 return;
17366 elsif D1 = D2
17367 and then Is_Generic_Instance (Scope (Ent))
17368 and then not In_Open_Scopes (Scope (Ent))
17369 then
17370 return;
17371 end if;
17372 end;
17374 -- Now we can proceed, if the entity being called has a completion,
17375 -- then we are definitely OK, since we have already seen the body.
17377 if Has_Completion (Ent) then
17378 return;
17379 end if;
17381 -- If there is no body, then nothing to do
17383 if not Has_Generic_Body (N) then
17384 return;
17385 end if;
17387 -- Here we definitely have a bad instantiation
17389 Error_Msg_Warn := SPARK_Mode /= On;
17390 Error_Msg_NE ("cannot instantiate& before body seen<<", N, Ent);
17391 Error_Msg_N ("\Program_Error [<<", N);
17393 Insert_Elab_Check (N);
17394 Set_Is_Known_Guaranteed_ABE (N);
17395 end Check_Bad_Instantiation;
17397 ---------------------
17398 -- Check_Elab_Call --
17399 ---------------------
17401 procedure Check_Elab_Call
17402 (N : Node_Id;
17403 Outer_Scope : Entity_Id := Empty;
17404 In_Init_Proc : Boolean := False)
17406 Ent : Entity_Id;
17407 P : Node_Id;
17409 begin
17410 pragma Assert (Legacy_Elaboration_Checks);
17412 -- If the reference is not in the main unit, there is nothing to check.
17413 -- Elaboration call from units in the context of the main unit will lead
17414 -- to semantic dependencies when those units are compiled.
17416 if not In_Extended_Main_Code_Unit (N) then
17417 return;
17418 end if;
17420 -- For an entry call, check relevant restriction
17422 if Nkind (N) = N_Entry_Call_Statement
17423 and then not In_Subprogram_Or_Concurrent_Unit
17424 then
17425 Check_Restriction (No_Entry_Calls_In_Elaboration_Code, N);
17427 -- Nothing to do if this is not an expected type of reference (happens
17428 -- in some error conditions, and in some cases where rewriting occurs).
17430 elsif Nkind (N) not in N_Subprogram_Call
17431 and then Nkind (N) /= N_Attribute_Reference
17432 and then (SPARK_Mode /= On
17433 or else Nkind (N) not in N_Has_Entity
17434 or else No (Entity (N))
17435 or else Ekind (Entity (N)) /= E_Variable)
17436 then
17437 return;
17439 -- Nothing to do if this is a call already rewritten for elab checking.
17440 -- Such calls appear as the targets of If_Expressions.
17442 -- This check MUST be wrong, it catches far too much
17444 elsif Nkind (Parent (N)) = N_If_Expression then
17445 return;
17447 -- Nothing to do if inside a generic template
17449 elsif Inside_A_Generic
17450 and then No (Enclosing_Generic_Body (N))
17451 then
17452 return;
17454 -- Nothing to do if call is being preanalyzed, as when within a
17455 -- pre/postcondition, a predicate, or an invariant.
17457 elsif In_Spec_Expression then
17458 return;
17459 end if;
17461 -- Nothing to do if this is a call to a postcondition, which is always
17462 -- within a subprogram body, even though the current scope may be the
17463 -- enclosing scope of the subprogram.
17465 if Nkind (N) = N_Procedure_Call_Statement
17466 and then Is_Entity_Name (Name (N))
17467 and then Chars (Entity (Name (N))) = Name_uWrapped_Statements
17468 then
17469 return;
17470 end if;
17472 -- Here we have a reference at elaboration time that must be checked
17474 if Debug_Flag_Underscore_LL then
17475 Write_Str (" Check_Elab_Ref: ");
17477 if Nkind (N) = N_Attribute_Reference then
17478 if not Is_Entity_Name (Prefix (N)) then
17479 Write_Str ("<<not entity name>>");
17480 else
17481 Write_Name (Chars (Entity (Prefix (N))));
17482 end if;
17484 Write_Str ("'Access");
17486 elsif No (Name (N)) or else not Is_Entity_Name (Name (N)) then
17487 Write_Str ("<<not entity name>> ");
17489 else
17490 Write_Name (Chars (Entity (Name (N))));
17491 end if;
17493 Write_Str (" reference at ");
17494 Write_Location (Sloc (N));
17495 Write_Eol;
17496 end if;
17498 -- Climb up the tree to make sure we are not inside default expression
17499 -- of a parameter specification or a record component, since in both
17500 -- these cases, we will be doing the actual reference later, not now,
17501 -- and it is at the time of the actual reference (statically speaking)
17502 -- that we must do our static check, not at the time of its initial
17503 -- analysis).
17505 -- However, we have to check references within component definitions
17506 -- (e.g. a function call that determines an array component bound),
17507 -- so we terminate the loop in that case.
17509 P := Parent (N);
17510 while Present (P) loop
17511 if Nkind (P) in N_Parameter_Specification | N_Component_Declaration
17512 then
17513 return;
17515 -- The reference occurs within the constraint of a component,
17516 -- so it must be checked.
17518 elsif Nkind (P) = N_Component_Definition then
17519 exit;
17521 else
17522 P := Parent (P);
17523 end if;
17524 end loop;
17526 -- Stuff that happens only at the outer level
17528 if No (Outer_Scope) then
17529 Elab_Visited.Set_Last (0);
17531 -- Nothing to do if current scope is Standard (this is a bit odd, but
17532 -- it happens in the case of generic instantiations).
17534 C_Scope := Current_Scope;
17536 if C_Scope = Standard_Standard then
17537 return;
17538 end if;
17540 -- First case, we are in elaboration code
17542 From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit;
17544 if From_Elab_Code then
17546 -- Complain if ref that comes from source in preelaborated unit
17547 -- and we are not inside a subprogram (i.e. we are in elab code).
17549 -- Ada 2022 (AI12-0175): Calls to certain functions that are
17550 -- essentially unchecked conversions are preelaborable.
17552 if Comes_From_Source (N)
17553 and then In_Preelaborated_Unit
17554 and then not In_Inlined_Body
17555 and then Nkind (N) /= N_Attribute_Reference
17556 and then not (Ada_Version >= Ada_2022
17557 and then Is_Preelaborable_Construct (N))
17558 then
17559 Error_Preelaborated_Call (N);
17560 return;
17561 end if;
17563 -- Second case, we are inside a subprogram or concurrent unit, which
17564 -- means we are not in elaboration code.
17566 else
17567 -- In this case, the issue is whether we are inside the
17568 -- declarative part of the unit in which we live, or inside its
17569 -- statements. In the latter case, there is no issue of ABE calls
17570 -- at this level (a call from outside to the unit in which we live
17571 -- might cause an ABE, but that will be detected when we analyze
17572 -- that outer level call, as it recurses into the called unit).
17574 -- Climb up the tree, doing this test, and also testing for being
17575 -- inside a default expression, which, as discussed above, is not
17576 -- checked at this stage.
17578 declare
17579 P : Node_Id;
17580 L : List_Id;
17582 begin
17583 P := N;
17584 loop
17585 -- If we find a parentless subtree, it seems safe to assume
17586 -- that we are not in a declarative part and that no
17587 -- checking is required.
17589 if No (P) then
17590 return;
17591 end if;
17593 if Is_List_Member (P) then
17594 L := List_Containing (P);
17595 P := Parent (L);
17596 else
17597 L := No_List;
17598 P := Parent (P);
17599 end if;
17601 exit when Nkind (P) = N_Subunit;
17603 -- Filter out case of default expressions, where we do not
17604 -- do the check at this stage.
17606 if Nkind (P) in
17607 N_Parameter_Specification | N_Component_Declaration
17608 then
17609 return;
17610 end if;
17612 -- A protected body has no elaboration code and contains
17613 -- only other bodies.
17615 if Nkind (P) = N_Protected_Body then
17616 return;
17618 elsif Nkind (P) in N_Subprogram_Body
17619 | N_Task_Body
17620 | N_Block_Statement
17621 | N_Entry_Body
17622 then
17623 if L = Declarations (P) then
17624 exit;
17626 -- We are not in elaboration code, but we are doing
17627 -- dynamic elaboration checks, in this case, we still
17628 -- need to do the reference, since the subprogram we are
17629 -- in could be called from another unit, also in dynamic
17630 -- elaboration check mode, at elaboration time.
17632 elsif Dynamic_Elaboration_Checks then
17634 -- We provide a debug flag to disable this check. That
17635 -- way we have an easy work around for regressions
17636 -- that are caused by this new check. This debug flag
17637 -- can be removed later.
17639 if Debug_Flag_DD then
17640 return;
17641 end if;
17643 -- Do the check in this case
17645 exit;
17647 elsif Nkind (P) = N_Task_Body then
17649 -- The check is deferred until Check_Task_Activation
17650 -- but we need to capture local suppress pragmas
17651 -- that may inhibit checks on this call.
17653 Ent := Get_Referenced_Ent (N);
17655 if No (Ent) then
17656 return;
17658 elsif Elaboration_Checks_Suppressed (Current_Scope)
17659 or else Elaboration_Checks_Suppressed (Ent)
17660 or else Elaboration_Checks_Suppressed (Scope (Ent))
17661 then
17662 if Nkind (N) in N_Subprogram_Call then
17663 Set_No_Elaboration_Check (N);
17664 end if;
17665 end if;
17667 return;
17669 -- Static model, call is not in elaboration code, we
17670 -- never need to worry, because in the static model the
17671 -- top-level caller always takes care of things.
17673 else
17674 return;
17675 end if;
17676 end if;
17677 end loop;
17678 end;
17679 end if;
17680 end if;
17682 Ent := Get_Referenced_Ent (N);
17684 if No (Ent) then
17685 return;
17686 end if;
17688 -- Determine whether a prior call to the same subprogram was already
17689 -- examined within the same context. If this is the case, then there is
17690 -- no need to proceed with the various warnings and checks because the
17691 -- work was already done for the previous call.
17693 declare
17694 Self : constant Visited_Element :=
17695 (Subp_Id => Ent, Context => Parent (N));
17697 begin
17698 for Index in 1 .. Elab_Visited.Last loop
17699 if Self = Elab_Visited.Table (Index) then
17700 return;
17701 end if;
17702 end loop;
17703 end;
17705 -- See if we need to analyze this reference. We analyze it if either of
17706 -- the following conditions is met:
17708 -- It is an inner level call (since in this case it was triggered
17709 -- by an outer level call from elaboration code), but only if the
17710 -- call is within the scope of the original outer level call.
17712 -- It is an outer level reference from elaboration code, or a call to
17713 -- an entity is in the same elaboration scope.
17715 -- And in these cases, we will check both inter-unit calls and
17716 -- intra-unit (within a single unit) calls.
17718 C_Scope := Current_Scope;
17720 -- If not outer level reference, then we follow it if it is within the
17721 -- original scope of the outer reference.
17723 if Present (Outer_Scope)
17724 and then Within (Scope (Ent), Outer_Scope)
17725 then
17726 Set_C_Scope;
17727 Check_A_Call
17728 (N => N,
17729 E => Ent,
17730 Outer_Scope => Outer_Scope,
17731 Inter_Unit_Only => False,
17732 In_Init_Proc => In_Init_Proc);
17734 -- Nothing to do if elaboration checks suppressed for this scope.
17735 -- However, an interesting exception, the fact that elaboration checks
17736 -- are suppressed within an instance (because we can trace the body when
17737 -- we process the template) does not extend to calls to generic formal
17738 -- subprograms.
17740 elsif Elaboration_Checks_Suppressed (Current_Scope)
17741 and then not Is_Call_Of_Generic_Formal (N)
17742 then
17743 null;
17745 elsif From_Elab_Code then
17746 Set_C_Scope;
17747 Check_A_Call (N, Ent, Standard_Standard, Inter_Unit_Only => False);
17749 elsif Same_Elaboration_Scope (C_Scope, Scope (Ent)) then
17750 Set_C_Scope;
17751 Check_A_Call (N, Ent, Scope (Ent), Inter_Unit_Only => False);
17753 -- If none of those cases holds, but Dynamic_Elaboration_Checks mode
17754 -- is set, then we will do the check, but only in the inter-unit case
17755 -- (this is to accommodate unguarded elaboration calls from other units
17756 -- in which this same mode is set). We don't want warnings in this case,
17757 -- it would generate warnings having nothing to do with elaboration.
17759 elsif Dynamic_Elaboration_Checks then
17760 Set_C_Scope;
17761 Check_A_Call
17763 Ent,
17764 Standard_Standard,
17765 Inter_Unit_Only => True,
17766 Generate_Warnings => False);
17768 -- Otherwise nothing to do
17770 else
17771 return;
17772 end if;
17774 -- A call to an Init_Proc in elaboration code may bring additional
17775 -- dependencies, if some of the record components thereof have
17776 -- initializations that are function calls that come from source. We
17777 -- treat the current node as a call to each of these functions, to check
17778 -- their elaboration impact.
17780 if Is_Init_Proc (Ent) and then From_Elab_Code then
17781 Process_Init_Proc : declare
17782 Unit_Decl : constant Node_Id := Unit_Declaration_Node (Ent);
17784 function Check_Init_Call (Nod : Node_Id) return Traverse_Result;
17785 -- Find subprogram calls within body of Init_Proc for Traverse
17786 -- instantiation below.
17788 procedure Traverse_Body is new Traverse_Proc (Check_Init_Call);
17789 -- Traversal procedure to find all calls with body of Init_Proc
17791 ---------------------
17792 -- Check_Init_Call --
17793 ---------------------
17795 function Check_Init_Call (Nod : Node_Id) return Traverse_Result is
17796 Func : Entity_Id;
17798 begin
17799 if Nkind (Nod) in N_Subprogram_Call
17800 and then Is_Entity_Name (Name (Nod))
17801 then
17802 Func := Entity (Name (Nod));
17804 if Comes_From_Source (Func) then
17805 Check_A_Call
17806 (N, Func, Standard_Standard, Inter_Unit_Only => True);
17807 end if;
17809 return OK;
17811 else
17812 return OK;
17813 end if;
17814 end Check_Init_Call;
17816 -- Start of processing for Process_Init_Proc
17818 begin
17819 if Nkind (Unit_Decl) = N_Subprogram_Body then
17820 Traverse_Body (Handled_Statement_Sequence (Unit_Decl));
17821 end if;
17822 end Process_Init_Proc;
17823 end if;
17824 end Check_Elab_Call;
17826 -----------------------
17827 -- Check_Elab_Assign --
17828 -----------------------
17830 procedure Check_Elab_Assign (N : Node_Id) is
17831 Ent : Entity_Id;
17832 Scop : Entity_Id;
17834 Pkg_Spec : Entity_Id;
17835 Pkg_Body : Entity_Id;
17837 begin
17838 pragma Assert (Legacy_Elaboration_Checks);
17840 -- For record or array component, check prefix. If it is an access type,
17841 -- then there is nothing to do (we do not know what is being assigned),
17842 -- but otherwise this is an assignment to the prefix.
17844 if Nkind (N) in N_Indexed_Component | N_Selected_Component | N_Slice then
17845 if not Is_Access_Type (Etype (Prefix (N))) then
17846 Check_Elab_Assign (Prefix (N));
17847 end if;
17849 return;
17850 end if;
17852 -- For type conversion, check expression
17854 if Nkind (N) = N_Type_Conversion then
17855 Check_Elab_Assign (Expression (N));
17856 return;
17857 end if;
17859 -- Nothing to do if this is not an entity reference otherwise get entity
17861 if Is_Entity_Name (N) then
17862 Ent := Entity (N);
17863 else
17864 return;
17865 end if;
17867 -- What we are looking for is a reference in the body of a package that
17868 -- modifies a variable declared in the visible part of the package spec.
17870 if Present (Ent)
17871 and then Comes_From_Source (N)
17872 and then not Suppress_Elaboration_Warnings (Ent)
17873 and then Ekind (Ent) = E_Variable
17874 and then not In_Private_Part (Ent)
17875 and then Is_Library_Level_Entity (Ent)
17876 then
17877 Scop := Current_Scope;
17878 loop
17879 if No (Scop) or else Scop = Standard_Standard then
17880 return;
17881 elsif Ekind (Scop) = E_Package
17882 and then Is_Compilation_Unit (Scop)
17883 then
17884 exit;
17885 else
17886 Scop := Scope (Scop);
17887 end if;
17888 end loop;
17890 -- Here Scop points to the containing library package
17892 Pkg_Spec := Scop;
17893 Pkg_Body := Body_Entity (Pkg_Spec);
17895 -- All OK if the package has an Elaborate_Body pragma
17897 if Has_Pragma_Elaborate_Body (Scop) then
17898 return;
17899 end if;
17901 -- OK if entity being modified is not in containing package spec
17903 if not In_Same_Source_Unit (Scop, Ent) then
17904 return;
17905 end if;
17907 -- All OK if entity appears in generic package or generic instance.
17908 -- We just get too messed up trying to give proper warnings in the
17909 -- presence of generics. Better no message than a junk one.
17911 Scop := Scope (Ent);
17912 while Present (Scop) and then Scop /= Pkg_Spec loop
17913 if Ekind (Scop) = E_Generic_Package then
17914 return;
17915 elsif Ekind (Scop) = E_Package
17916 and then Is_Generic_Instance (Scop)
17917 then
17918 return;
17919 end if;
17921 Scop := Scope (Scop);
17922 end loop;
17924 -- All OK if in task, don't issue warnings there
17926 if In_Task_Activation then
17927 return;
17928 end if;
17930 -- OK if no package body
17932 if No (Pkg_Body) then
17933 return;
17934 end if;
17936 -- OK if reference is not in package body
17938 if not In_Same_Source_Unit (Pkg_Body, N) then
17939 return;
17940 end if;
17942 -- OK if package body has no handled statement sequence
17944 declare
17945 HSS : constant Node_Id :=
17946 Handled_Statement_Sequence (Declaration_Node (Pkg_Body));
17947 begin
17948 if No (HSS) or else not Comes_From_Source (HSS) then
17949 return;
17950 end if;
17951 end;
17953 -- We definitely have a case of a modification of an entity in
17954 -- the package spec from the elaboration code of the package body.
17955 -- We may not give the warning (because there are some additional
17956 -- checks to avoid too many false positives), but it would be a good
17957 -- idea for the binder to try to keep the body elaboration close to
17958 -- the spec elaboration.
17960 Set_Elaborate_Body_Desirable (Pkg_Spec);
17962 -- All OK in gnat mode (we know what we are doing)
17964 if GNAT_Mode then
17965 return;
17966 end if;
17968 -- All OK if all warnings suppressed
17970 if Warning_Mode = Suppress then
17971 return;
17972 end if;
17974 -- All OK if elaboration checks suppressed for entity
17976 if Checks_May_Be_Suppressed (Ent)
17977 and then Is_Check_Suppressed (Ent, Elaboration_Check)
17978 then
17979 return;
17980 end if;
17982 -- OK if the entity is initialized. Note that the No_Initialization
17983 -- flag usually means that the initialization has been rewritten into
17984 -- assignments, but that still counts for us.
17986 declare
17987 Decl : constant Node_Id := Declaration_Node (Ent);
17988 begin
17989 if Nkind (Decl) = N_Object_Declaration
17990 and then (Present (Expression (Decl))
17991 or else No_Initialization (Decl))
17992 then
17993 return;
17994 end if;
17995 end;
17997 -- Here is where we give the warning
17999 -- All OK if warnings suppressed on the entity
18001 if not Has_Warnings_Off (Ent) then
18002 Error_Msg_Sloc := Sloc (Ent);
18004 Error_Msg_NE
18005 ("??& can be accessed by clients before this initialization",
18006 N, Ent);
18007 Error_Msg_NE
18008 ("\??add Elaborate_Body to spec to ensure & is initialized",
18009 N, Ent);
18010 end if;
18012 if not All_Errors_Mode then
18013 Set_Suppress_Elaboration_Warnings (Ent);
18014 end if;
18015 end if;
18016 end Check_Elab_Assign;
18018 ----------------------
18019 -- Check_Elab_Calls --
18020 ----------------------
18022 -- WARNING: This routine manages SPARK regions
18024 procedure Check_Elab_Calls is
18025 Saved_SM : SPARK_Mode_Type;
18026 Saved_SMP : Node_Id;
18028 begin
18029 pragma Assert (Legacy_Elaboration_Checks);
18031 -- If expansion is disabled, do not generate any checks, unless we
18032 -- are in GNATprove mode, so that errors are issued in GNATprove for
18033 -- violations of static elaboration rules in SPARK code. Also skip
18034 -- checks if any subunits are missing because in either case we lack the
18035 -- full information that we need, and no object file will be created in
18036 -- any case.
18038 if (not Expander_Active and not GNATprove_Mode)
18039 or else Is_Generic_Unit (Cunit_Entity (Main_Unit))
18040 or else Subunits_Missing
18041 then
18042 return;
18043 end if;
18045 -- Skip delayed calls if we had any errors
18047 if Serious_Errors_Detected = 0 then
18048 Delaying_Elab_Checks := False;
18049 Expander_Mode_Save_And_Set (True);
18051 for J in Delay_Check.First .. Delay_Check.Last loop
18052 Push_Scope (Delay_Check.Table (J).Curscop);
18053 From_Elab_Code := Delay_Check.Table (J).From_Elab_Code;
18054 In_Task_Activation := Delay_Check.Table (J).In_Task_Activation;
18056 Saved_SM := SPARK_Mode;
18057 Saved_SMP := SPARK_Mode_Pragma;
18059 -- Set appropriate value of SPARK_Mode
18061 if Delay_Check.Table (J).From_SPARK_Code then
18062 SPARK_Mode := On;
18063 end if;
18065 Check_Internal_Call_Continue
18066 (N => Delay_Check.Table (J).N,
18067 E => Delay_Check.Table (J).E,
18068 Outer_Scope => Delay_Check.Table (J).Outer_Scope,
18069 Orig_Ent => Delay_Check.Table (J).Orig_Ent);
18071 Restore_SPARK_Mode (Saved_SM, Saved_SMP);
18072 Pop_Scope;
18073 end loop;
18075 -- Set Delaying_Elab_Checks back on for next main compilation
18077 Expander_Mode_Restore;
18078 Delaying_Elab_Checks := True;
18079 end if;
18080 end Check_Elab_Calls;
18082 ------------------------------
18083 -- Check_Elab_Instantiation --
18084 ------------------------------
18086 procedure Check_Elab_Instantiation
18087 (N : Node_Id;
18088 Outer_Scope : Entity_Id := Empty)
18090 Ent : Entity_Id;
18092 begin
18093 pragma Assert (Legacy_Elaboration_Checks);
18095 -- Check for and deal with bad instantiation case. There is some
18096 -- duplicated code here, but we will worry about this later ???
18098 Check_Bad_Instantiation (N);
18100 if Is_Known_Guaranteed_ABE (N) then
18101 return;
18102 end if;
18104 -- Nothing to do if we do not have an instantiation (happens in some
18105 -- error cases, and also in the formal package declaration case)
18107 if Nkind (N) not in N_Generic_Instantiation then
18108 return;
18109 end if;
18111 -- Nothing to do if inside a generic template
18113 if Inside_A_Generic then
18114 return;
18115 end if;
18117 -- Nothing to do if the instantiation is not in the main unit
18119 if not In_Extended_Main_Code_Unit (N) then
18120 return;
18121 end if;
18123 Ent := Get_Generic_Entity (N);
18124 From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit;
18126 -- See if we need to analyze this instantiation. We analyze it if
18127 -- either of the following conditions is met:
18129 -- It is an inner level instantiation (since in this case it was
18130 -- triggered by an outer level call from elaboration code), but
18131 -- only if the instantiation is within the scope of the original
18132 -- outer level call.
18134 -- It is an outer level instantiation from elaboration code, or the
18135 -- instantiated entity is in the same elaboration scope.
18137 -- And in these cases, we will check both the inter-unit case and
18138 -- the intra-unit (within a single unit) case.
18140 C_Scope := Current_Scope;
18142 if Present (Outer_Scope) and then Within (Scope (Ent), Outer_Scope) then
18143 Set_C_Scope;
18144 Check_A_Call (N, Ent, Outer_Scope, Inter_Unit_Only => False);
18146 elsif From_Elab_Code then
18147 Set_C_Scope;
18148 Check_A_Call (N, Ent, Standard_Standard, Inter_Unit_Only => False);
18150 elsif Same_Elaboration_Scope (C_Scope, Scope (Ent)) then
18151 Set_C_Scope;
18152 Check_A_Call (N, Ent, Scope (Ent), Inter_Unit_Only => False);
18154 -- If none of those cases holds, but Dynamic_Elaboration_Checks mode is
18155 -- set, then we will do the check, but only in the inter-unit case (this
18156 -- is to accommodate unguarded elaboration calls from other units in
18157 -- which this same mode is set). We inhibit warnings in this case, since
18158 -- this instantiation is not occurring in elaboration code.
18160 elsif Dynamic_Elaboration_Checks then
18161 Set_C_Scope;
18162 Check_A_Call
18164 Ent,
18165 Standard_Standard,
18166 Inter_Unit_Only => True,
18167 Generate_Warnings => False);
18169 else
18170 return;
18171 end if;
18172 end Check_Elab_Instantiation;
18174 -------------------------
18175 -- Check_Internal_Call --
18176 -------------------------
18178 procedure Check_Internal_Call
18179 (N : Node_Id;
18180 E : Entity_Id;
18181 Outer_Scope : Entity_Id;
18182 Orig_Ent : Entity_Id)
18184 function Within_Initial_Condition (Call : Node_Id) return Boolean;
18185 -- Determine whether call Call occurs within pragma Initial_Condition or
18186 -- pragma Check with check_kind set to Initial_Condition.
18188 ------------------------------
18189 -- Within_Initial_Condition --
18190 ------------------------------
18192 function Within_Initial_Condition (Call : Node_Id) return Boolean is
18193 Args : List_Id;
18194 Nam : Name_Id;
18195 Par : Node_Id;
18197 begin
18198 -- Traverse the parent chain looking for an enclosing pragma
18200 Par := Call;
18201 while Present (Par) loop
18202 if Nkind (Par) = N_Pragma then
18203 Nam := Pragma_Name (Par);
18205 -- Pragma Initial_Condition appears in its alternative from as
18206 -- Check (Initial_Condition, ...).
18208 if Nam = Name_Check then
18209 Args := Pragma_Argument_Associations (Par);
18211 -- Pragma Check should have at least two arguments
18213 pragma Assert (Present (Args));
18215 return
18216 Chars (Expression (First (Args))) = Name_Initial_Condition;
18218 -- Direct match
18220 elsif Nam = Name_Initial_Condition then
18221 return True;
18223 -- Since pragmas are never nested within other pragmas, stop
18224 -- the traversal.
18226 else
18227 return False;
18228 end if;
18230 -- Prevent the search from going too far
18232 elsif Is_Body_Or_Package_Declaration (Par) then
18233 exit;
18234 end if;
18236 Par := Parent (Par);
18238 -- If assertions are not enabled, the check pragma is rewritten
18239 -- as an if_statement in sem_prag, to generate various warnings
18240 -- on boolean expressions. Retrieve the original pragma.
18242 if Nkind (Original_Node (Par)) = N_Pragma then
18243 Par := Original_Node (Par);
18244 end if;
18245 end loop;
18247 return False;
18248 end Within_Initial_Condition;
18250 -- Local variables
18252 Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;
18254 -- Start of processing for Check_Internal_Call
18256 begin
18257 -- For P'Access, we want to warn if the -gnatw.f switch is set, and the
18258 -- node comes from source.
18260 if Nkind (N) = N_Attribute_Reference
18261 and then ((not Warn_On_Elab_Access and then not Debug_Flag_Dot_O)
18262 or else not Comes_From_Source (N))
18263 then
18264 return;
18266 -- If not function or procedure call, instantiation, or 'Access, then
18267 -- ignore call (this happens in some error cases and rewriting cases).
18269 elsif Nkind (N) not in N_Attribute_Reference
18270 | N_Function_Call
18271 | N_Procedure_Call_Statement
18272 and then not Inst_Case
18273 then
18274 return;
18276 -- Nothing to do if this is a call or instantiation that has already
18277 -- been found to be a sure ABE.
18279 elsif Nkind (N) /= N_Attribute_Reference
18280 and then Is_Known_Guaranteed_ABE (N)
18281 then
18282 return;
18284 -- Nothing to do if errors already detected (avoid cascaded errors)
18286 elsif Serious_Errors_Detected /= 0 then
18287 return;
18289 -- Nothing to do if not in full analysis mode
18291 elsif not Full_Analysis then
18292 return;
18294 -- Nothing to do if analyzing in special spec-expression mode, since the
18295 -- call is not actually being made at this time.
18297 elsif In_Spec_Expression then
18298 return;
18300 -- Nothing to do for call to intrinsic subprogram
18302 elsif Is_Intrinsic_Subprogram (E) then
18303 return;
18305 -- Nothing to do if call is within a generic unit
18307 elsif Inside_A_Generic then
18308 return;
18310 -- Nothing to do when the call appears within pragma Initial_Condition.
18311 -- The pragma is part of the elaboration statements of a package body
18312 -- and may only call external subprograms or subprograms whose body is
18313 -- already available.
18315 elsif Within_Initial_Condition (N) then
18316 return;
18317 end if;
18319 -- Delay this call if we are still delaying calls
18321 if Delaying_Elab_Checks then
18322 Delay_Check.Append
18323 ((N => N,
18324 E => E,
18325 Orig_Ent => Orig_Ent,
18326 Curscop => Current_Scope,
18327 Outer_Scope => Outer_Scope,
18328 From_Elab_Code => From_Elab_Code,
18329 In_Task_Activation => In_Task_Activation,
18330 From_SPARK_Code => SPARK_Mode = On));
18331 return;
18333 -- Otherwise, call phase 2 continuation right now
18335 else
18336 Check_Internal_Call_Continue (N, E, Outer_Scope, Orig_Ent);
18337 end if;
18338 end Check_Internal_Call;
18340 ----------------------------------
18341 -- Check_Internal_Call_Continue --
18342 ----------------------------------
18344 procedure Check_Internal_Call_Continue
18345 (N : Node_Id;
18346 E : Entity_Id;
18347 Outer_Scope : Entity_Id;
18348 Orig_Ent : Entity_Id)
18350 function Find_Elab_Reference (N : Node_Id) return Traverse_Result;
18351 -- Function applied to each node as we traverse the body. Checks for
18352 -- call or entity reference that needs checking, and if so checks it.
18353 -- Always returns OK, so entire tree is traversed, except that as
18354 -- described below subprogram bodies are skipped for now.
18356 procedure Traverse is new Atree.Traverse_Proc (Find_Elab_Reference);
18357 -- Traverse procedure using above Find_Elab_Reference function
18359 -------------------------
18360 -- Find_Elab_Reference --
18361 -------------------------
18363 function Find_Elab_Reference (N : Node_Id) return Traverse_Result is
18364 Actual : Node_Id;
18366 begin
18367 -- If user has specified that there are no entry calls in elaboration
18368 -- code, do not trace past an accept statement, because the rendez-
18369 -- vous will happen after elaboration.
18371 if Nkind (Original_Node (N)) in
18372 N_Accept_Statement | N_Selective_Accept
18373 and then Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
18374 then
18375 return Abandon;
18377 -- If we have a function call, check it
18379 elsif Nkind (N) = N_Function_Call then
18380 Check_Elab_Call (N, Outer_Scope);
18381 return OK;
18383 -- If we have a procedure call, check the call, and also check
18384 -- arguments that are assignments (OUT or IN OUT mode formals).
18386 elsif Nkind (N) = N_Procedure_Call_Statement then
18387 Check_Elab_Call (N, Outer_Scope, In_Init_Proc => Is_Init_Proc (E));
18389 Actual := First_Actual (N);
18390 while Present (Actual) loop
18391 if Known_To_Be_Assigned (Actual) then
18392 Check_Elab_Assign (Actual);
18393 end if;
18395 Next_Actual (Actual);
18396 end loop;
18398 return OK;
18400 -- If we have an access attribute for a subprogram, check it.
18401 -- Suppress this behavior under debug flag.
18403 elsif not Debug_Flag_Dot_UU
18404 and then Nkind (N) = N_Attribute_Reference
18405 and then
18406 Attribute_Name (N) in Name_Access | Name_Unrestricted_Access
18407 and then Is_Entity_Name (Prefix (N))
18408 and then Is_Subprogram (Entity (Prefix (N)))
18409 then
18410 Check_Elab_Call (N, Outer_Scope);
18411 return OK;
18413 -- In SPARK mode, if we have an entity reference to a variable, then
18414 -- check it. For now we consider any reference.
18416 elsif SPARK_Mode = On
18417 and then Nkind (N) in N_Has_Entity
18418 and then Present (Entity (N))
18419 and then Ekind (Entity (N)) = E_Variable
18420 then
18421 Check_Elab_Call (N, Outer_Scope);
18422 return OK;
18424 -- If we have a generic instantiation, check it
18426 elsif Nkind (N) in N_Generic_Instantiation then
18427 Check_Elab_Instantiation (N, Outer_Scope);
18428 return OK;
18430 -- Skip subprogram bodies that come from source (wait for call to
18431 -- analyze these). The reason for the come from source test is to
18432 -- avoid catching task bodies.
18434 -- For task bodies, we should really avoid these too, waiting for the
18435 -- task activation, but that's too much trouble to catch for now, so
18436 -- we go in unconditionally. This is not so terrible, it means the
18437 -- error backtrace is not quite complete, and we are too eager to
18438 -- scan bodies of tasks that are unused, but this is hardly very
18439 -- significant.
18441 elsif Nkind (N) = N_Subprogram_Body
18442 and then Comes_From_Source (N)
18443 then
18444 return Skip;
18446 elsif Nkind (N) = N_Assignment_Statement
18447 and then Comes_From_Source (N)
18448 then
18449 Check_Elab_Assign (Name (N));
18450 return OK;
18452 else
18453 return OK;
18454 end if;
18455 end Find_Elab_Reference;
18457 Inst_Case : constant Boolean := Is_Generic_Unit (E);
18458 Loc : constant Source_Ptr := Sloc (N);
18460 Ebody : Entity_Id;
18461 Sbody : Node_Id;
18463 -- Start of processing for Check_Internal_Call_Continue
18465 begin
18466 -- Save outer level call if at outer level
18468 if Elab_Call.Last = 0 then
18469 Outer_Level_Sloc := Loc;
18470 end if;
18472 -- If the call is to a function that renames a literal, no check needed
18474 if Ekind (E) = E_Enumeration_Literal then
18475 return;
18476 end if;
18478 -- Register the subprogram as examined within this particular context.
18479 -- This ensures that calls to the same subprogram but in different
18480 -- contexts receive warnings and checks of their own since the calls
18481 -- may be reached through different flow paths.
18483 Elab_Visited.Append ((Subp_Id => E, Context => Parent (N)));
18485 Sbody := Unit_Declaration_Node (E);
18487 if Nkind (Sbody) not in N_Subprogram_Body | N_Package_Body then
18488 Ebody := Corresponding_Body (Sbody);
18490 if No (Ebody) then
18491 return;
18492 else
18493 Sbody := Unit_Declaration_Node (Ebody);
18494 end if;
18495 end if;
18497 -- If the body appears after the outer level call or instantiation then
18498 -- we have an error case handled below.
18500 if Earlier_In_Extended_Unit (Outer_Level_Sloc, Sloc (Sbody))
18501 and then not In_Task_Activation
18502 then
18503 null;
18505 -- If we have the instantiation case we are done, since we now know that
18506 -- the body of the generic appeared earlier.
18508 elsif Inst_Case then
18509 return;
18511 -- Otherwise we have a call, so we trace through the called body to see
18512 -- if it has any problems.
18514 else
18515 pragma Assert (Nkind (Sbody) = N_Subprogram_Body);
18517 Elab_Call.Append ((Cloc => Loc, Ent => E));
18519 if Debug_Flag_Underscore_LL then
18520 Write_Str ("Elab_Call.Last = ");
18521 Write_Int (Int (Elab_Call.Last));
18522 Write_Str (" Ent = ");
18523 Write_Name (Chars (E));
18524 Write_Str (" at ");
18525 Write_Location (Sloc (N));
18526 Write_Eol;
18527 end if;
18529 -- Now traverse declarations and statements of subprogram body. Note
18530 -- that we cannot simply Traverse (Sbody), since traverse does not
18531 -- normally visit subprogram bodies.
18533 declare
18534 Decl : Node_Id;
18535 begin
18536 Decl := First (Declarations (Sbody));
18537 while Present (Decl) loop
18538 Traverse (Decl);
18539 Next (Decl);
18540 end loop;
18541 end;
18543 Traverse (Handled_Statement_Sequence (Sbody));
18545 Elab_Call.Decrement_Last;
18546 return;
18547 end if;
18549 -- Here is the case of calling a subprogram where the body has not yet
18550 -- been encountered. A warning message is needed, except if this is the
18551 -- case of appearing within an aspect specification that results in
18552 -- a check call, we do not really have such a situation, so no warning
18553 -- is needed (e.g. the case of a precondition, where the call appears
18554 -- textually before the body, but in actual fact is moved to the
18555 -- appropriate subprogram body and so does not need a check).
18557 declare
18558 P : Node_Id;
18559 O : Node_Id;
18561 begin
18562 P := Parent (N);
18563 loop
18564 -- Keep looking at parents if we are still in the subexpression
18566 if Nkind (P) in N_Subexpr then
18567 P := Parent (P);
18569 -- Here P is the parent of the expression, check for special case
18571 else
18572 O := Original_Node (P);
18574 -- Definitely not the special case if orig node is not a pragma
18576 exit when Nkind (O) /= N_Pragma;
18578 -- Check we have an If statement or a null statement (happens
18579 -- when the If has been expanded to be True).
18581 exit when Nkind (P) not in N_If_Statement | N_Null_Statement;
18583 -- Our special case will be indicated either by the pragma
18584 -- coming from an aspect ...
18586 if Present (Corresponding_Aspect (O)) then
18587 return;
18589 -- Or, in the case of an initial condition, specifically by a
18590 -- Check pragma specifying an Initial_Condition check.
18592 elsif Pragma_Name (O) = Name_Check
18593 and then
18594 Chars
18595 (Expression (First (Pragma_Argument_Associations (O)))) =
18596 Name_Initial_Condition
18597 then
18598 return;
18600 -- For anything else, we have an error
18602 else
18603 exit;
18604 end if;
18605 end if;
18606 end loop;
18607 end;
18609 -- Not that special case, warning and dynamic check is required
18611 -- If we have nothing in the call stack, then this is at the outer
18612 -- level, and the ABE is bound to occur, unless it's a 'Access, or
18613 -- it's a renaming.
18615 if Elab_Call.Last = 0 then
18616 Error_Msg_Warn := SPARK_Mode /= On;
18618 declare
18619 Insert_Check : Boolean := True;
18620 -- This flag is set to True if an elaboration check should be
18621 -- inserted.
18623 begin
18624 if In_Task_Activation then
18625 Insert_Check := False;
18627 elsif Inst_Case then
18628 Error_Msg_NE
18629 ("cannot instantiate& before body seen<<", N, Orig_Ent);
18631 elsif Nkind (N) = N_Attribute_Reference then
18632 Error_Msg_NE
18633 ("Access attribute of & before body seen<<", N, Orig_Ent);
18634 Error_Msg_N
18635 ("\possible Program_Error on later references<<", N);
18636 Insert_Check := False;
18638 elsif Nkind (Unit_Declaration_Node (Orig_Ent)) /=
18639 N_Subprogram_Renaming_Declaration
18640 or else Is_Generic_Actual_Subprogram (Orig_Ent)
18641 then
18642 Error_Msg_NE
18643 ("cannot call& before body seen<<", N, Orig_Ent);
18644 else
18645 Insert_Check := False;
18646 end if;
18648 if Insert_Check then
18649 Error_Msg_N ("\Program_Error [<<", N);
18650 Insert_Elab_Check (N);
18651 end if;
18652 end;
18654 -- Call is not at outer level
18656 else
18657 -- Do not generate elaboration checks in GNATprove mode because the
18658 -- elaboration counter and the check are both forms of expansion.
18660 if GNATprove_Mode then
18661 null;
18663 -- Generate an elaboration check
18665 elsif not Elaboration_Checks_Suppressed (E) then
18666 Set_Elaboration_Entity_Required (E);
18668 -- Create a declaration of the elaboration entity, and insert it
18669 -- prior to the subprogram or the generic unit, within the same
18670 -- scope. Since the subprogram may be overloaded, create a unique
18671 -- entity.
18673 if No (Elaboration_Entity (E)) then
18674 declare
18675 Loce : constant Source_Ptr := Sloc (E);
18676 Ent : constant Entity_Id :=
18677 Make_Defining_Identifier (Loc,
18678 New_External_Name (Chars (E), 'E', -1));
18680 begin
18681 Set_Elaboration_Entity (E, Ent);
18682 Push_Scope (Scope (E));
18684 Insert_Action (Declaration_Node (E),
18685 Make_Object_Declaration (Loce,
18686 Defining_Identifier => Ent,
18687 Object_Definition =>
18688 New_Occurrence_Of (Standard_Short_Integer, Loce),
18689 Expression =>
18690 Make_Integer_Literal (Loc, Uint_0)));
18692 -- Set elaboration flag at the point of the body
18694 Set_Elaboration_Flag (Sbody, E);
18696 -- Kill current value indication. This is necessary because
18697 -- the tests of this flag are inserted out of sequence and
18698 -- must not pick up bogus indications of the wrong constant
18699 -- value. Also, this is never a true constant, since one way
18700 -- or another, it gets reset.
18702 Set_Current_Value (Ent, Empty);
18703 Set_Last_Assignment (Ent, Empty);
18704 Set_Is_True_Constant (Ent, False);
18705 Pop_Scope;
18706 end;
18707 end if;
18709 -- Generate:
18710 -- if Enn = 0 then
18711 -- raise Program_Error with "access before elaboration";
18712 -- end if;
18714 Insert_Elab_Check (N,
18715 Make_Attribute_Reference (Loc,
18716 Attribute_Name => Name_Elaborated,
18717 Prefix => New_Occurrence_Of (E, Loc)));
18718 end if;
18720 -- Generate the warning
18722 if not Suppress_Elaboration_Warnings (E)
18723 and then not Elaboration_Checks_Suppressed (E)
18725 -- Suppress this warning if we have a function call that occurred
18726 -- within an assertion expression, since we can get false warnings
18727 -- in this case, due to the out of order handling in this case.
18729 and then
18730 (Nkind (Original_Node (N)) /= N_Function_Call
18731 or else not In_Assertion_Expression_Pragma (Original_Node (N)))
18732 then
18733 Error_Msg_Warn := SPARK_Mode /= On;
18735 if Inst_Case then
18736 Error_Msg_NE
18737 ("instantiation of& may occur before body is seen<l<",
18738 N, Orig_Ent);
18739 else
18740 -- A rather specific check. For Finalize/Adjust/Initialize, if
18741 -- the type has Warnings_Off set, suppress the warning.
18743 if Chars (E) in Name_Adjust
18744 | Name_Finalize
18745 | Name_Initialize
18746 and then Present (First_Formal (E))
18747 then
18748 declare
18749 T : constant Entity_Id := Etype (First_Formal (E));
18750 begin
18751 if Is_Controlled (T) then
18752 if Has_Warnings_Off (T)
18753 or else (Ekind (T) = E_Private_Type
18754 and then Has_Warnings_Off (Full_View (T)))
18755 then
18756 goto Output;
18757 end if;
18758 end if;
18759 end;
18760 end if;
18762 -- Go ahead and give warning if not this special case
18764 Error_Msg_NE
18765 ("call to& may occur before body is seen<l<", N, Orig_Ent);
18766 end if;
18768 Error_Msg_N ("\Program_Error ]<l<", N);
18770 -- There is no need to query the elaboration warning message flags
18771 -- because the main message is an error, not a warning, therefore
18772 -- all the clarification messages produces by Output_Calls must be
18773 -- emitted unconditionally.
18775 <<Output>>
18777 Output_Calls (N, Check_Elab_Flag => False);
18778 end if;
18779 end if;
18780 end Check_Internal_Call_Continue;
18782 ---------------------------
18783 -- Check_Task_Activation --
18784 ---------------------------
18786 procedure Check_Task_Activation (N : Node_Id) is
18787 Loc : constant Source_Ptr := Sloc (N);
18788 Inter_Procs : constant Elist_Id := New_Elmt_List;
18789 Intra_Procs : constant Elist_Id := New_Elmt_List;
18790 Ent : Entity_Id;
18791 P : Entity_Id;
18792 Task_Scope : Entity_Id;
18793 Cunit_SC : Boolean := False;
18794 Decl : Node_Id;
18795 Elmt : Elmt_Id;
18796 Enclosing : Entity_Id;
18798 procedure Add_Task_Proc (Typ : Entity_Id);
18799 -- Add to Task_Procs the task body procedure(s) of task types in Typ.
18800 -- For record types, this procedure recurses over component types.
18802 procedure Collect_Tasks (Decls : List_Id);
18803 -- Collect the types of the tasks that are to be activated in the given
18804 -- list of declarations, in order to perform elaboration checks on the
18805 -- corresponding task procedures that are called implicitly here.
18807 function Outer_Unit (E : Entity_Id) return Entity_Id;
18808 -- find enclosing compilation unit of Entity, ignoring subunits, or
18809 -- else enclosing subprogram. If E is not a package, there is no need
18810 -- for inter-unit elaboration checks.
18812 -------------------
18813 -- Add_Task_Proc --
18814 -------------------
18816 procedure Add_Task_Proc (Typ : Entity_Id) is
18817 Comp : Entity_Id;
18818 Proc : Entity_Id := Empty;
18820 begin
18821 if Is_Task_Type (Typ) then
18822 Proc := Get_Task_Body_Procedure (Typ);
18824 elsif Is_Array_Type (Typ)
18825 and then Has_Task (Base_Type (Typ))
18826 then
18827 Add_Task_Proc (Component_Type (Typ));
18829 elsif Is_Record_Type (Typ)
18830 and then Has_Task (Base_Type (Typ))
18831 then
18832 Comp := First_Component (Typ);
18833 while Present (Comp) loop
18834 Add_Task_Proc (Etype (Comp));
18835 Next_Component (Comp);
18836 end loop;
18837 end if;
18839 -- If the task type is another unit, we will perform the usual
18840 -- elaboration check on its enclosing unit. If the type is in the
18841 -- same unit, we can trace the task body as for an internal call,
18842 -- but we only need to examine other external calls, because at
18843 -- the point the task is activated, internal subprogram bodies
18844 -- will have been elaborated already. We keep separate lists for
18845 -- each kind of task.
18847 -- Skip this test if errors have occurred, since in this case
18848 -- we can get false indications.
18850 if Serious_Errors_Detected /= 0 then
18851 return;
18852 end if;
18854 if Present (Proc) then
18855 if Outer_Unit (Scope (Proc)) = Enclosing then
18857 if No (Corresponding_Body (Unit_Declaration_Node (Proc)))
18858 and then
18859 (not Is_Generic_Instance (Scope (Proc))
18860 or else Scope (Proc) = Scope (Defining_Identifier (Decl)))
18861 then
18862 Error_Msg_Warn := SPARK_Mode /= On;
18863 Error_Msg_N
18864 ("task will be activated before elaboration of its body<<",
18865 Decl);
18866 Error_Msg_N ("\Program_Error [<<", Decl);
18868 elsif Present
18869 (Corresponding_Body (Unit_Declaration_Node (Proc)))
18870 then
18871 Append_Elmt (Proc, Intra_Procs);
18872 end if;
18874 else
18875 -- No need for multiple entries of the same type
18877 Elmt := First_Elmt (Inter_Procs);
18878 while Present (Elmt) loop
18879 if Node (Elmt) = Proc then
18880 return;
18881 end if;
18883 Next_Elmt (Elmt);
18884 end loop;
18886 Append_Elmt (Proc, Inter_Procs);
18887 end if;
18888 end if;
18889 end Add_Task_Proc;
18891 -------------------
18892 -- Collect_Tasks --
18893 -------------------
18895 procedure Collect_Tasks (Decls : List_Id) is
18896 begin
18897 Decl := First (Decls);
18898 while Present (Decl) loop
18899 if Nkind (Decl) = N_Object_Declaration
18900 and then Has_Task (Etype (Defining_Identifier (Decl)))
18901 then
18902 Add_Task_Proc (Etype (Defining_Identifier (Decl)));
18903 end if;
18905 Next (Decl);
18906 end loop;
18907 end Collect_Tasks;
18909 ----------------
18910 -- Outer_Unit --
18911 ----------------
18913 function Outer_Unit (E : Entity_Id) return Entity_Id is
18914 Outer : Entity_Id;
18916 begin
18917 Outer := E;
18918 while Present (Outer) loop
18919 if Elaboration_Checks_Suppressed (Outer) then
18920 Cunit_SC := True;
18921 end if;
18923 exit when Is_Child_Unit (Outer)
18924 or else Scope (Outer) = Standard_Standard
18925 or else Ekind (Outer) /= E_Package;
18926 Outer := Scope (Outer);
18927 end loop;
18929 return Outer;
18930 end Outer_Unit;
18932 -- Start of processing for Check_Task_Activation
18934 begin
18935 pragma Assert (Legacy_Elaboration_Checks);
18937 Enclosing := Outer_Unit (Current_Scope);
18939 -- Find all tasks declared in the current unit
18941 if Nkind (N) = N_Package_Body then
18942 P := Unit_Declaration_Node (Corresponding_Spec (N));
18944 Collect_Tasks (Declarations (N));
18945 Collect_Tasks (Visible_Declarations (Specification (P)));
18946 Collect_Tasks (Private_Declarations (Specification (P)));
18948 elsif Nkind (N) = N_Package_Declaration then
18949 Collect_Tasks (Visible_Declarations (Specification (N)));
18950 Collect_Tasks (Private_Declarations (Specification (N)));
18952 else
18953 Collect_Tasks (Declarations (N));
18954 end if;
18956 -- We only perform detailed checks in all tasks that are library level
18957 -- entities. If the master is a subprogram or task, activation will
18958 -- depend on the activation of the master itself.
18960 -- Should dynamic checks be added in the more general case???
18962 if Ekind (Enclosing) /= E_Package then
18963 return;
18964 end if;
18966 -- For task types defined in other units, we want the unit containing
18967 -- the task body to be elaborated before the current one.
18969 Elmt := First_Elmt (Inter_Procs);
18970 while Present (Elmt) loop
18971 Ent := Node (Elmt);
18972 Task_Scope := Outer_Unit (Scope (Ent));
18974 if not Is_Compilation_Unit (Task_Scope) then
18975 null;
18977 elsif Suppress_Elaboration_Warnings (Task_Scope)
18978 or else Elaboration_Checks_Suppressed (Task_Scope)
18979 then
18980 null;
18982 elsif Dynamic_Elaboration_Checks then
18983 if not Elaboration_Checks_Suppressed (Ent)
18984 and then not Cunit_SC
18985 and then not Restriction_Active
18986 (No_Entry_Calls_In_Elaboration_Code)
18987 then
18988 -- Runtime elaboration check required. Generate check of the
18989 -- elaboration counter for the unit containing the entity.
18991 Insert_Elab_Check (N,
18992 Make_Attribute_Reference (Loc,
18993 Prefix =>
18994 New_Occurrence_Of (Spec_Entity (Task_Scope), Loc),
18995 Attribute_Name => Name_Elaborated));
18996 end if;
18998 else
18999 -- Force the binder to elaborate other unit first
19001 if Elab_Info_Messages
19002 and then not Suppress_Elaboration_Warnings (Ent)
19003 and then not Elaboration_Checks_Suppressed (Ent)
19004 and then not Suppress_Elaboration_Warnings (Task_Scope)
19005 and then not Elaboration_Checks_Suppressed (Task_Scope)
19006 then
19007 Error_Msg_Node_2 := Task_Scope;
19008 Error_Msg_NE
19009 ("info: activation of an instance of task type & requires "
19010 & "pragma Elaborate_All on &?$?", N, Ent);
19011 end if;
19013 Activate_Elaborate_All_Desirable (N, Task_Scope);
19014 Set_Suppress_Elaboration_Warnings (Task_Scope);
19015 end if;
19017 Next_Elmt (Elmt);
19018 end loop;
19020 -- For tasks declared in the current unit, trace other calls within the
19021 -- task procedure bodies, which are available.
19023 if not Debug_Flag_Dot_Y then
19024 In_Task_Activation := True;
19026 Elmt := First_Elmt (Intra_Procs);
19027 while Present (Elmt) loop
19028 Ent := Node (Elmt);
19029 Check_Internal_Call_Continue (N, Ent, Enclosing, Ent);
19030 Next_Elmt (Elmt);
19031 end loop;
19033 In_Task_Activation := False;
19034 end if;
19035 end Check_Task_Activation;
19037 ------------------------
19038 -- Get_Referenced_Ent --
19039 ------------------------
19041 function Get_Referenced_Ent (N : Node_Id) return Entity_Id is
19042 Nam : Node_Id;
19044 begin
19045 if Nkind (N) in N_Has_Entity
19046 and then Present (Entity (N))
19047 and then Ekind (Entity (N)) = E_Variable
19048 then
19049 return Entity (N);
19050 end if;
19052 if Nkind (N) = N_Attribute_Reference then
19053 Nam := Prefix (N);
19054 else
19055 Nam := Name (N);
19056 end if;
19058 if No (Nam) then
19059 return Empty;
19060 elsif Nkind (Nam) = N_Selected_Component then
19061 return Entity (Selector_Name (Nam));
19062 elsif not Is_Entity_Name (Nam) then
19063 return Empty;
19064 else
19065 return Entity (Nam);
19066 end if;
19067 end Get_Referenced_Ent;
19069 ----------------------
19070 -- Has_Generic_Body --
19071 ----------------------
19073 function Has_Generic_Body (N : Node_Id) return Boolean is
19074 Ent : constant Entity_Id := Get_Generic_Entity (N);
19075 Decl : constant Node_Id := Unit_Declaration_Node (Ent);
19076 Scop : Entity_Id;
19078 function Find_Body_In (E : Entity_Id; N : Node_Id) return Node_Id;
19079 -- Determine if the list of nodes headed by N and linked by Next
19080 -- contains a package body for the package spec entity E, and if so
19081 -- return the package body. If not, then returns Empty.
19083 function Load_Package_Body (Nam : Unit_Name_Type) return Node_Id;
19084 -- This procedure is called load the unit whose name is given by Nam.
19085 -- This unit is being loaded to see whether it contains an optional
19086 -- generic body. The returned value is the loaded unit, which is always
19087 -- a package body (only package bodies can contain other entities in the
19088 -- sense in which Has_Generic_Body is interested). We only attempt to
19089 -- load bodies if we are generating code. If we are in semantics check
19090 -- only mode, then it would be wrong to load bodies that are not
19091 -- required from a semantic point of view, so in this case we return
19092 -- Empty. The result is that the caller may incorrectly decide that a
19093 -- generic spec does not have a body when in fact it does, but the only
19094 -- harm in this is that some warnings on elaboration problems may be
19095 -- lost in semantic checks only mode, which is not big loss. We also
19096 -- return Empty if we go for a body and it is not there.
19098 function Locate_Corresponding_Body (PE : Entity_Id) return Node_Id;
19099 -- PE is the entity for a package spec. This function locates the
19100 -- corresponding package body, returning Empty if none is found. The
19101 -- package body returned is fully parsed but may not yet be analyzed,
19102 -- so only syntactic fields should be referenced.
19104 ------------------
19105 -- Find_Body_In --
19106 ------------------
19108 function Find_Body_In (E : Entity_Id; N : Node_Id) return Node_Id is
19109 Nod : Node_Id;
19111 begin
19112 Nod := N;
19113 while Present (Nod) loop
19115 -- If we found the package body we are looking for, return it
19117 if Nkind (Nod) = N_Package_Body
19118 and then Chars (Defining_Unit_Name (Nod)) = Chars (E)
19119 then
19120 return Nod;
19122 -- If we found the stub for the body, go after the subunit,
19123 -- loading it if necessary.
19125 elsif Nkind (Nod) = N_Package_Body_Stub
19126 and then Chars (Defining_Identifier (Nod)) = Chars (E)
19127 then
19128 if Present (Library_Unit (Nod)) then
19129 return Unit (Library_Unit (Nod));
19131 else
19132 return Load_Package_Body (Get_Unit_Name (Nod));
19133 end if;
19135 -- If neither package body nor stub, keep looking on chain
19137 else
19138 Next (Nod);
19139 end if;
19140 end loop;
19142 return Empty;
19143 end Find_Body_In;
19145 -----------------------
19146 -- Load_Package_Body --
19147 -----------------------
19149 function Load_Package_Body (Nam : Unit_Name_Type) return Node_Id is
19150 U : Unit_Number_Type;
19152 begin
19153 if Operating_Mode /= Generate_Code then
19154 return Empty;
19155 else
19156 U :=
19157 Load_Unit
19158 (Load_Name => Nam,
19159 Required => False,
19160 Subunit => False,
19161 Error_Node => N);
19163 if U = No_Unit then
19164 return Empty;
19165 else
19166 return Unit (Cunit (U));
19167 end if;
19168 end if;
19169 end Load_Package_Body;
19171 -------------------------------
19172 -- Locate_Corresponding_Body --
19173 -------------------------------
19175 function Locate_Corresponding_Body (PE : Entity_Id) return Node_Id is
19176 Spec : constant Node_Id := Declaration_Node (PE);
19177 Decl : constant Node_Id := Parent (Spec);
19178 Scop : constant Entity_Id := Scope (PE);
19179 PBody : Node_Id;
19181 begin
19182 if Is_Library_Level_Entity (PE) then
19184 -- If package is a library unit that requires a body, we have no
19185 -- choice but to go after that body because it might contain an
19186 -- optional body for the original generic package.
19188 if Unit_Requires_Body (PE) then
19190 -- Load the body. Note that we are a little careful here to use
19191 -- Spec to get the unit number, rather than PE or Decl, since
19192 -- in the case where the package is itself a library level
19193 -- instantiation, Spec will properly reference the generic
19194 -- template, which is what we really want.
19196 return
19197 Load_Package_Body
19198 (Get_Body_Name (Unit_Name (Get_Source_Unit (Spec))));
19200 -- But if the package is a library unit that does NOT require
19201 -- a body, then no body is permitted, so we are sure that there
19202 -- is no body for the original generic package.
19204 else
19205 return Empty;
19206 end if;
19208 -- Otherwise look and see if we are embedded in a further package
19210 elsif Is_Package_Or_Generic_Package (Scop) then
19212 -- If so, get the body of the enclosing package, and look in
19213 -- its package body for the package body we are looking for.
19215 PBody := Locate_Corresponding_Body (Scop);
19217 if No (PBody) then
19218 return Empty;
19219 else
19220 return Find_Body_In (PE, First (Declarations (PBody)));
19221 end if;
19223 -- If we are not embedded in a further package, then the body
19224 -- must be in the same declarative part as we are.
19226 else
19227 return Find_Body_In (PE, Next (Decl));
19228 end if;
19229 end Locate_Corresponding_Body;
19231 -- Start of processing for Has_Generic_Body
19233 begin
19234 if Present (Corresponding_Body (Decl)) then
19235 return True;
19237 elsif Unit_Requires_Body (Ent) then
19238 return True;
19240 -- Compilation units cannot have optional bodies
19242 elsif Is_Compilation_Unit (Ent) then
19243 return False;
19245 -- Otherwise look at what scope we are in
19247 else
19248 Scop := Scope (Ent);
19250 -- Case of entity is in other than a package spec, in this case
19251 -- the body, if present, must be in the same declarative part.
19253 if not Is_Package_Or_Generic_Package (Scop) then
19254 declare
19255 P : Node_Id;
19257 begin
19258 -- Declaration node may get us a spec, so if so, go to
19259 -- the parent declaration.
19261 P := Declaration_Node (Ent);
19262 while not Is_List_Member (P) loop
19263 P := Parent (P);
19264 end loop;
19266 return Present (Find_Body_In (Ent, Next (P)));
19267 end;
19269 -- If the entity is in a package spec, then we have to locate
19270 -- the corresponding package body, and look there.
19272 else
19273 declare
19274 PBody : constant Node_Id := Locate_Corresponding_Body (Scop);
19276 begin
19277 if No (PBody) then
19278 return False;
19279 else
19280 return
19281 Present
19282 (Find_Body_In (Ent, (First (Declarations (PBody)))));
19283 end if;
19284 end;
19285 end if;
19286 end if;
19287 end Has_Generic_Body;
19289 -----------------------
19290 -- Insert_Elab_Check --
19291 -----------------------
19293 procedure Insert_Elab_Check (N : Node_Id; C : Node_Id := Empty) is
19294 Nod : Node_Id;
19295 Loc : constant Source_Ptr := Sloc (N);
19297 Chk : Node_Id;
19298 -- The check (N_Raise_Program_Error) node to be inserted
19300 begin
19301 -- If expansion is disabled, do not generate any checks. Also
19302 -- skip checks if any subunits are missing because in either
19303 -- case we lack the full information that we need, and no object
19304 -- file will be created in any case.
19306 if not Expander_Active or else Subunits_Missing then
19307 return;
19308 end if;
19310 -- If we have a generic instantiation, where Instance_Spec is set,
19311 -- then this field points to a generic instance spec that has
19312 -- been inserted before the instantiation node itself, so that
19313 -- is where we want to insert a check.
19315 if Nkind (N) in N_Generic_Instantiation
19316 and then Present (Instance_Spec (N))
19317 then
19318 Nod := Instance_Spec (N);
19319 else
19320 Nod := N;
19321 end if;
19323 -- Build check node, possibly with condition
19325 Chk :=
19326 Make_Raise_Program_Error (Loc, Reason => PE_Access_Before_Elaboration);
19328 if Present (C) then
19329 Set_Condition (Chk, Make_Op_Not (Loc, Right_Opnd => C));
19330 end if;
19332 -- If we are inserting at the top level, insert in Aux_Decls
19334 if Nkind (Parent (Nod)) = N_Compilation_Unit then
19335 declare
19336 ADN : constant Node_Id := Aux_Decls_Node (Parent (Nod));
19338 begin
19339 if No (Declarations (ADN)) then
19340 Set_Declarations (ADN, New_List (Chk));
19341 else
19342 Append_To (Declarations (ADN), Chk);
19343 end if;
19345 Analyze (Chk);
19346 end;
19348 -- Otherwise just insert as an action on the node in question
19350 else
19351 Insert_Action (Nod, Chk);
19352 end if;
19353 end Insert_Elab_Check;
19355 -------------------------------
19356 -- Is_Call_Of_Generic_Formal --
19357 -------------------------------
19359 function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean is
19360 begin
19361 return Nkind (N) in N_Subprogram_Call
19363 -- Always return False if debug flag -gnatd.G is set
19365 and then not Debug_Flag_Dot_GG
19367 -- For now, we detect this by looking for the strange identifier
19368 -- node, whose Chars reflect the name of the generic formal, but
19369 -- the Chars of the Entity references the generic actual.
19371 and then Nkind (Name (N)) = N_Identifier
19372 and then Chars (Name (N)) /= Chars (Entity (Name (N)));
19373 end Is_Call_Of_Generic_Formal;
19375 -------------------------------
19376 -- Is_Finalization_Procedure --
19377 -------------------------------
19379 function Is_Finalization_Procedure (Id : Entity_Id) return Boolean is
19380 begin
19381 -- Check whether Id is a procedure with at least one parameter
19383 if Ekind (Id) = E_Procedure and then Present (First_Formal (Id)) then
19384 declare
19385 Typ : constant Entity_Id := Etype (First_Formal (Id));
19386 Deep_Fin : Entity_Id := Empty;
19387 Fin : Entity_Id := Empty;
19389 begin
19390 -- If the type of the first formal does not require finalization
19391 -- actions, then this is definitely not [Deep_]Finalize.
19393 if not Needs_Finalization (Typ) then
19394 return False;
19395 end if;
19397 -- At this point we have the following scenario:
19399 -- procedure Name (Param1 : [in] [out] Ctrl[; Param2 : ...]);
19401 -- Recover the two possible versions of [Deep_]Finalize using the
19402 -- type of the first parameter and compare with the input.
19404 Deep_Fin := TSS (Typ, TSS_Deep_Finalize);
19406 if Is_Controlled (Typ) then
19407 Fin := Find_Prim_Op (Typ, Name_Finalize);
19408 end if;
19410 return (Present (Deep_Fin) and then Id = Deep_Fin)
19411 or else (Present (Fin) and then Id = Fin);
19412 end;
19413 end if;
19415 return False;
19416 end Is_Finalization_Procedure;
19418 ------------------
19419 -- Output_Calls --
19420 ------------------
19422 procedure Output_Calls
19423 (N : Node_Id;
19424 Check_Elab_Flag : Boolean)
19426 function Emit (Flag : Boolean) return Boolean;
19427 -- Determine whether to emit an error message based on the combination
19428 -- of flags Check_Elab_Flag and Flag.
19430 function Is_Printable_Error_Name return Boolean;
19431 -- An internal function, used to determine if a name, stored in the
19432 -- Name_Buffer, is either a non-internal name, or is an internal name
19433 -- that is printable by the error message circuits (i.e. it has a single
19434 -- upper case letter at the end).
19436 ----------
19437 -- Emit --
19438 ----------
19440 function Emit (Flag : Boolean) return Boolean is
19441 begin
19442 if Check_Elab_Flag then
19443 return Flag;
19444 else
19445 return True;
19446 end if;
19447 end Emit;
19449 -----------------------------
19450 -- Is_Printable_Error_Name --
19451 -----------------------------
19453 function Is_Printable_Error_Name return Boolean is
19454 begin
19455 if not Is_Internal_Name then
19456 return True;
19458 elsif Name_Len = 1 then
19459 return False;
19461 else
19462 Name_Len := Name_Len - 1;
19463 return not Is_Internal_Name;
19464 end if;
19465 end Is_Printable_Error_Name;
19467 -- Local variables
19469 Ent : Entity_Id;
19471 -- Start of processing for Output_Calls
19473 begin
19474 for J in reverse 1 .. Elab_Call.Last loop
19475 Error_Msg_Sloc := Elab_Call.Table (J).Cloc;
19477 Ent := Elab_Call.Table (J).Ent;
19478 Get_Name_String (Chars (Ent));
19480 -- Dynamic elaboration model, warnings controlled by -gnatwl
19482 if Dynamic_Elaboration_Checks then
19483 if Emit (Elab_Warnings) then
19484 if Is_Generic_Unit (Ent) then
19485 Error_Msg_NE ("\\?l?& instantiated #", N, Ent);
19486 elsif Is_Init_Proc (Ent) then
19487 Error_Msg_N ("\\?l?initialization procedure called #", N);
19488 elsif Is_Printable_Error_Name then
19489 Error_Msg_NE ("\\?l?& called #", N, Ent);
19490 else
19491 Error_Msg_N ("\\?l?called #", N);
19492 end if;
19493 end if;
19495 -- Static elaboration model, info messages controlled by -gnatel
19497 else
19498 if Emit (Elab_Info_Messages) then
19499 if Is_Generic_Unit (Ent) then
19500 Error_Msg_NE ("\\?$?& instantiated #", N, Ent);
19501 elsif Is_Init_Proc (Ent) then
19502 Error_Msg_N ("\\?$?initialization procedure called #", N);
19503 elsif Is_Printable_Error_Name then
19504 Error_Msg_NE ("\\?$?& called #", N, Ent);
19505 else
19506 Error_Msg_N ("\\?$?called #", N);
19507 end if;
19508 end if;
19509 end if;
19510 end loop;
19511 end Output_Calls;
19513 ----------------------------
19514 -- Same_Elaboration_Scope --
19515 ----------------------------
19517 function Same_Elaboration_Scope (Scop1, Scop2 : Entity_Id) return Boolean is
19518 S1 : Entity_Id;
19519 S2 : Entity_Id;
19521 begin
19522 -- Find elaboration scope for Scop1
19523 -- This is either a subprogram or a compilation unit.
19525 S1 := Scop1;
19526 while S1 /= Standard_Standard
19527 and then not Is_Compilation_Unit (S1)
19528 and then Ekind (S1) in E_Package | E_Protected_Type | E_Block
19529 loop
19530 S1 := Scope (S1);
19531 end loop;
19533 -- Find elaboration scope for Scop2
19535 S2 := Scop2;
19536 while S2 /= Standard_Standard
19537 and then not Is_Compilation_Unit (S2)
19538 and then Ekind (S2) in E_Package | E_Protected_Type | E_Block
19539 loop
19540 S2 := Scope (S2);
19541 end loop;
19543 return S1 = S2;
19544 end Same_Elaboration_Scope;
19546 -----------------
19547 -- Set_C_Scope --
19548 -----------------
19550 procedure Set_C_Scope is
19551 begin
19552 while not Is_Compilation_Unit (C_Scope) loop
19553 C_Scope := Scope (C_Scope);
19554 end loop;
19555 end Set_C_Scope;
19557 --------------------------------
19558 -- Set_Elaboration_Constraint --
19559 --------------------------------
19561 procedure Set_Elaboration_Constraint
19562 (Call : Node_Id;
19563 Subp : Entity_Id;
19564 Scop : Entity_Id)
19566 Elab_Unit : Entity_Id;
19568 -- Check whether this is a call to an Initialize subprogram for a
19569 -- controlled type. Note that Call can also be a 'Access attribute
19570 -- reference, which now generates an elaboration check.
19572 Init_Call : constant Boolean :=
19573 Nkind (Call) = N_Procedure_Call_Statement
19574 and then Chars (Subp) = Name_Initialize
19575 and then Comes_From_Source (Subp)
19576 and then Present (Parameter_Associations (Call))
19577 and then Is_Controlled (Etype (First_Actual (Call)));
19579 begin
19580 -- If the unit is mentioned in a with_clause of the current unit, it is
19581 -- visible, and we can set the elaboration flag.
19583 if Is_Immediately_Visible (Scop)
19584 or else (Is_Child_Unit (Scop) and then Is_Visible_Lib_Unit (Scop))
19585 then
19586 Activate_Elaborate_All_Desirable (Call, Scop);
19587 Set_Suppress_Elaboration_Warnings (Scop);
19588 return;
19589 end if;
19591 -- If this is not an initialization call or a call using object notation
19592 -- we know that the unit of the called entity is in the context, and we
19593 -- can set the flag as well. The unit need not be visible if the call
19594 -- occurs within an instantiation.
19596 if Is_Init_Proc (Subp)
19597 or else Init_Call
19598 or else Nkind (Original_Node (Call)) = N_Selected_Component
19599 then
19600 null; -- detailed processing follows.
19602 else
19603 Activate_Elaborate_All_Desirable (Call, Scop);
19604 Set_Suppress_Elaboration_Warnings (Scop);
19605 return;
19606 end if;
19608 -- If the unit is not in the context, there must be an intermediate unit
19609 -- that is, on which we need to place to elaboration flag. This happens
19610 -- with init proc calls.
19612 if Is_Init_Proc (Subp) or else Init_Call then
19614 -- The initialization call is on an object whose type is not declared
19615 -- in the same scope as the subprogram. The type of the object must
19616 -- be a subtype of the type of operation. This object is the first
19617 -- actual in the call.
19619 declare
19620 Typ : constant Entity_Id :=
19621 Etype (First (Parameter_Associations (Call)));
19622 begin
19623 Elab_Unit := Scope (Typ);
19624 while Present (Elab_Unit)
19625 and then not Is_Compilation_Unit (Elab_Unit)
19626 loop
19627 Elab_Unit := Scope (Elab_Unit);
19628 end loop;
19629 end;
19631 -- If original node uses selected component notation, the prefix is
19632 -- visible and determines the scope that must be elaborated. After
19633 -- rewriting, the prefix is the first actual in the call.
19635 elsif Nkind (Original_Node (Call)) = N_Selected_Component then
19636 Elab_Unit := Scope (Etype (First (Parameter_Associations (Call))));
19638 -- Not one of special cases above
19640 else
19641 -- Using previously computed scope. If the elaboration check is
19642 -- done after analysis, the scope is not visible any longer, but
19643 -- must still be in the context.
19645 Elab_Unit := Scop;
19646 end if;
19648 Activate_Elaborate_All_Desirable (Call, Elab_Unit);
19649 Set_Suppress_Elaboration_Warnings (Elab_Unit);
19650 end Set_Elaboration_Constraint;
19652 -----------------
19653 -- Spec_Entity --
19654 -----------------
19656 function Spec_Entity (E : Entity_Id) return Entity_Id is
19657 Decl : Node_Id;
19659 begin
19660 -- Check for case of body entity
19661 -- Why is the check for E_Void needed???
19663 if Ekind (E) in E_Void | E_Subprogram_Body | E_Package_Body then
19664 Decl := E;
19666 loop
19667 Decl := Parent (Decl);
19668 exit when Nkind (Decl) in N_Proper_Body;
19669 end loop;
19671 return Corresponding_Spec (Decl);
19673 else
19674 return E;
19675 end if;
19676 end Spec_Entity;
19678 ------------
19679 -- Within --
19680 ------------
19682 function Within (E1, E2 : Entity_Id) return Boolean is
19683 Scop : Entity_Id;
19684 begin
19685 Scop := E1;
19686 loop
19687 if Scop = E2 then
19688 return True;
19689 elsif Scop = Standard_Standard then
19690 return False;
19691 else
19692 Scop := Scope (Scop);
19693 end if;
19694 end loop;
19695 end Within;
19697 --------------------------
19698 -- Within_Elaborate_All --
19699 --------------------------
19701 function Within_Elaborate_All
19702 (Unit : Unit_Number_Type;
19703 E : Entity_Id) return Boolean
19705 type Unit_Number_Set is array (Main_Unit .. Last_Unit) of Boolean;
19706 pragma Pack (Unit_Number_Set);
19708 Seen : Unit_Number_Set := (others => False);
19709 -- Seen (X) is True after we have seen unit X in the walk. This is used
19710 -- to prevent processing the same unit more than once.
19712 Result : Boolean := False;
19714 procedure Helper (Unit : Unit_Number_Type);
19715 -- This helper procedure does all the work for Within_Elaborate_All. It
19716 -- walks the dependency graph, and sets Result to True if it finds an
19717 -- appropriate Elaborate_All.
19719 ------------
19720 -- Helper --
19721 ------------
19723 procedure Helper (Unit : Unit_Number_Type) is
19724 CU : constant Node_Id := Cunit (Unit);
19726 Item : Node_Id;
19727 Item2 : Node_Id;
19728 Elab_Id : Entity_Id;
19729 Par : Node_Id;
19731 begin
19732 if Seen (Unit) then
19733 return;
19734 else
19735 Seen (Unit) := True;
19736 end if;
19738 -- First, check for Elaborate_Alls on this unit
19740 Item := First (Context_Items (CU));
19741 while Present (Item) loop
19742 if Nkind (Item) = N_Pragma
19743 and then Pragma_Name (Item) = Name_Elaborate_All
19744 then
19745 -- Return if some previous error on the pragma itself. The
19746 -- pragma may be unanalyzed, because of a previous error, or
19747 -- if it is the context of a subunit, inherited by its parent.
19749 if Error_Posted (Item) or else not Analyzed (Item) then
19750 return;
19751 end if;
19753 Elab_Id :=
19754 Entity
19755 (Expression (First (Pragma_Argument_Associations (Item))));
19757 if E = Elab_Id then
19758 Result := True;
19759 return;
19760 end if;
19762 Par := Parent (Unit_Declaration_Node (Elab_Id));
19764 Item2 := First (Context_Items (Par));
19765 while Present (Item2) loop
19766 if Nkind (Item2) = N_With_Clause
19767 and then Entity (Name (Item2)) = E
19768 and then not Limited_Present (Item2)
19769 then
19770 Result := True;
19771 return;
19772 end if;
19774 Next (Item2);
19775 end loop;
19776 end if;
19778 Next (Item);
19779 end loop;
19781 -- Second, recurse on with's. We could do this as part of the above
19782 -- loop, but it's probably more efficient to have two loops, because
19783 -- the relevant Elaborate_All is likely to be on the initial unit. In
19784 -- other words, we're walking the with's breadth-first. This part is
19785 -- only necessary in the dynamic elaboration model.
19787 if Dynamic_Elaboration_Checks then
19788 Item := First (Context_Items (CU));
19789 while Present (Item) loop
19790 if Nkind (Item) = N_With_Clause
19791 and then not Limited_Present (Item)
19792 then
19793 -- Note: the following call to Get_Cunit_Unit_Number does a
19794 -- linear search, which could be slow, but it's OK because
19795 -- we're about to give a warning anyway. Also, there might
19796 -- be hundreds of units, but not millions. If it turns out
19797 -- to be a problem, we could store the Get_Cunit_Unit_Number
19798 -- in each N_Compilation_Unit node, but that would involve
19799 -- rearranging N_Compilation_Unit_Aux to make room.
19801 Helper (Get_Cunit_Unit_Number (Library_Unit (Item)));
19803 if Result then
19804 return;
19805 end if;
19806 end if;
19808 Next (Item);
19809 end loop;
19810 end if;
19811 end Helper;
19813 -- Start of processing for Within_Elaborate_All
19815 begin
19816 Helper (Unit);
19817 return Result;
19818 end Within_Elaborate_All;
19820 end Sem_Elab;