Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
48 * The environment task executes the Ada program (if available) for that | 48 * The environment task executes the Ada program (if available) for that |
49 partition. | 49 partition. |
50 | 50 |
51 In addition to the Ada terminology, this appendix defines the following terms: | 51 In addition to the Ada terminology, this appendix defines the following terms: |
52 | 52 |
53 * *Invocation* | |
54 | |
55 The act of calling a subprogram, instantiating a generic, or activating a | |
56 task. | |
57 | |
53 * *Scenario* | 58 * *Scenario* |
54 | 59 |
55 A construct that is elaborated or executed by elaboration code is referred to | 60 A construct that is elaborated or invoked by elaboration code is referred to |
56 as an *elaboration scenario* or simply a **scenario**. GNAT recognizes the | 61 as an *elaboration scenario* or simply a **scenario**. GNAT recognizes the |
57 following scenarios: | 62 following scenarios: |
58 | 63 |
59 - ``'Access`` of entries, operators, and subprograms | 64 - ``'Access`` of entries, operators, and subprograms |
60 | 65 |
100 end Client; | 105 end Client; |
101 | 106 |
102 In the example above, the call to ``Server.Func`` is an elaboration scenario | 107 In the example above, the call to ``Server.Func`` is an elaboration scenario |
103 because it appears at the library level of package ``Client``. Note that the | 108 because it appears at the library level of package ``Client``. Note that the |
104 declaration of package ``Nested`` is ignored according to the definition | 109 declaration of package ``Nested`` is ignored according to the definition |
105 given above. As a result, the call to ``Server.Func`` will be executed when | 110 given above. As a result, the call to ``Server.Func`` will be invoked when |
106 the spec of unit ``Client`` is elaborated. | 111 the spec of unit ``Client`` is elaborated. |
107 | 112 |
108 * *Package body statements* | 113 * *Package body statements* |
109 | 114 |
110 A scenario appears within the statement sequence of a package body when it is | 115 A scenario appears within the statement sequence of a package body when it is |
122 Proc; | 127 Proc; |
123 end Client; | 128 end Client; |
124 | 129 |
125 In the example above, the call to ``Proc`` is an elaboration scenario because | 130 In the example above, the call to ``Proc`` is an elaboration scenario because |
126 it appears within the statement sequence of package body ``Client``. As a | 131 it appears within the statement sequence of package body ``Client``. As a |
127 result, the call to ``Proc`` will be executed when the body of ``Client`` is | 132 result, the call to ``Proc`` will be invoked when the body of ``Client`` is |
128 elaborated. | 133 elaborated. |
129 | 134 |
130 .. _Elaboration_Order: | 135 .. _Elaboration_Order: |
131 | 136 |
132 Elaboration Order | 137 Elaboration Order |
135 The sequence by which the elaboration code of all units within a partition is | 140 The sequence by which the elaboration code of all units within a partition is |
136 executed is referred to as **elaboration order**. | 141 executed is referred to as **elaboration order**. |
137 | 142 |
138 Within a single unit, elaboration code is executed in sequential order. | 143 Within a single unit, elaboration code is executed in sequential order. |
139 | 144 |
140 :: | 145 :: |
141 | 146 |
142 package body Client is | 147 package body Client is |
143 Result : ... := Server.Func; | 148 Result : ... := Server.Func; |
144 | 149 |
145 procedure Proc is | 150 procedure Proc is |
146 package Inst is new Server.Gen; | 151 package Inst is new Server.Gen; |
147 begin | 152 begin |
148 Inst.Eval (Result); | 153 Inst.Eval (Result); |
149 end Proc; | 154 end Proc; |
150 begin | 155 begin |
151 Proc; | 156 Proc; |
152 end Client; | 157 end Client; |
153 | 158 |
154 In the example above, the elaboration order within package body ``Client`` is | 159 In the example above, the elaboration order within package body ``Client`` is |
155 as follows: | 160 as follows: |
156 | 161 |
157 1. The object declaration of ``Result`` is elaborated. | 162 1. The object declaration of ``Result`` is elaborated. |
171 The elaboration order of all units within a partition depends on the following | 176 The elaboration order of all units within a partition depends on the following |
172 factors: | 177 factors: |
173 | 178 |
174 * |withed| units | 179 * |withed| units |
175 | 180 |
181 * parent units | |
182 | |
176 * purity of units | 183 * purity of units |
177 | 184 |
178 * preelaborability of units | 185 * preelaborability of units |
179 | 186 |
180 * presence of elaboration control pragmas | 187 * presence of elaboration-control pragmas |
188 | |
189 * invocations performed in elaboration code | |
181 | 190 |
182 A program may have several elaboration orders depending on its structure. | 191 A program may have several elaboration orders depending on its structure. |
183 | 192 |
184 :: | 193 :: |
185 | 194 |
186 package Server is | 195 package Server is |
187 function Func (Index : Integer) return Integer; | 196 function Func (Index : Integer) return Integer; |
188 end Server; | 197 end Server; |
189 | 198 |
190 :: | 199 :: |
191 | 200 |
192 package body Server is | 201 package body Server is |
193 Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5); | 202 Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5); |
194 | 203 |
195 function Func (Index : Integer) return Integer is | 204 function Func (Index : Integer) return Integer is |
196 begin | 205 begin |
197 return Results (Index); | 206 return Results (Index); |
198 end Func; | 207 end Func; |
199 end Server; | 208 end Server; |
200 | 209 |
201 :: | 210 :: |
202 | 211 |
203 with Server; | 212 with Server; |
204 package Client is | 213 package Client is |
205 Val : constant Integer := Server.Func (3); | 214 Val : constant Integer := Server.Func (3); |
206 end Client; | 215 end Client; |
207 | 216 |
208 :: | 217 :: |
209 | 218 |
210 with Client; | 219 with Client; |
211 procedure Main is begin null; end Main; | 220 procedure Main is begin null; end Main; |
212 | 221 |
213 The following elaboration order exhibits a fundamental problem referred to as | 222 The following elaboration order exhibits a fundamental problem referred to as |
214 *access-before-elaboration* or simply **ABE**. | 223 *access-before-elaboration* or simply **ABE**. |
215 | 224 |
216 :: | 225 :: |
217 | 226 |
218 spec of Server | 227 spec of Server |
219 spec of Client | 228 spec of Client |
220 body of Server | 229 body of Server |
221 body of Main | 230 body of Main |
222 | 231 |
223 The elaboration of ``Server``'s spec materializes function ``Func``, making it | 232 The elaboration of ``Server``'s spec materializes function ``Func``, making it |
224 callable. The elaboration of ``Client``'s spec elaborates the declaration of | 233 callable. The elaboration of ``Client``'s spec elaborates the declaration of |
225 ``Val``. This invokes function ``Server.Func``, however the body of | 234 ``Val``. This invokes function ``Server.Func``, however the body of |
226 ``Server.Func`` has not been elaborated yet because ``Server``'s body comes | 235 ``Server.Func`` has not been elaborated yet because ``Server``'s body comes |
234 ``Program_Error``. | 243 ``Program_Error``. |
235 | 244 |
236 The following elaboration order avoids the ABE problem and the program can be | 245 The following elaboration order avoids the ABE problem and the program can be |
237 successfully elaborated. | 246 successfully elaborated. |
238 | 247 |
239 :: | 248 :: |
240 | 249 |
241 spec of Server | 250 spec of Server |
242 body of Server | 251 body of Server |
243 spec of Client | 252 spec of Client |
244 body of Main | 253 body of Main |
245 | 254 |
246 Ada states that a total elaboration order must exist, but it does not define | 255 Ada states that a total elaboration order must exist, but it does not define |
247 what this order is. A compiler is thus tasked with choosing a suitable | 256 what this order is. A compiler is thus tasked with choosing a suitable |
248 elaboration order which satisfies the dependencies imposed by |with| clauses, | 257 elaboration order which satisfies the dependencies imposed by |with| clauses, |
249 unit categorization, and elaboration control pragmas. Ideally an order which | 258 unit categorization, elaboration-control pragmas, and invocations performed in |
250 avoids ABE problems should be chosen, however a compiler may not always find | 259 elaboration code. Ideally an order that avoids ABE problems should be chosen, |
251 such an order due to complications with respect to control and data flow. | 260 however a compiler may not always find such an order due to complications with |
261 respect to control and data flow. | |
252 | 262 |
253 .. _Checking_the_Elaboration_Order: | 263 .. _Checking_the_Elaboration_Order: |
254 | 264 |
255 Checking the Elaboration Order | 265 Checking the Elaboration Order |
256 ============================== | 266 ============================== |
257 | 267 |
258 To avoid placing the entire elaboration order burden on the programmer, Ada | 268 To avoid placing the entire elaboration-order burden on the programmer, Ada |
259 provides three lines of defense: | 269 provides three lines of defense: |
260 | 270 |
261 * *Static semantics* | 271 * *Static semantics* |
262 | 272 |
263 Static semantic rules restrict the possible choice of elaboration order. For | 273 Static semantic rules restrict the possible choice of elaboration order. For |
266 - the spec of a parent unit is always elaborated prior to the child unit. | 276 - the spec of a parent unit is always elaborated prior to the child unit. |
267 | 277 |
268 * *Dynamic semantics* | 278 * *Dynamic semantics* |
269 | 279 |
270 Dynamic checks are performed at run time, to ensure that a target is | 280 Dynamic checks are performed at run time, to ensure that a target is |
271 elaborated prior to a scenario that executes it, thus avoiding ABE problems. | 281 elaborated prior to a scenario that invokes it, thus avoiding ABE problems. |
272 A failed run-time check raises exception ``Program_Error``. The following | 282 A failed run-time check raises exception ``Program_Error``. The following |
273 restrictions apply: | 283 restrictions apply: |
274 | 284 |
275 - *Restrictions on calls* | 285 - *Restrictions on calls* |
276 | 286 |
288 associated task type has been elaborated. | 298 associated task type has been elaborated. |
289 | 299 |
290 The restrictions above can be summarized by the following rule: | 300 The restrictions above can be summarized by the following rule: |
291 | 301 |
292 *If a target has a body, then this body must be elaborated prior to the | 302 *If a target has a body, then this body must be elaborated prior to the |
293 execution of the scenario that invokes, instantiates, or activates the | 303 scenario that invokes the target.* |
294 target.* | |
295 | 304 |
296 * *Elaboration control* | 305 * *Elaboration control* |
297 | 306 |
298 Pragmas are provided for the programmer to specify the desired elaboration | 307 Pragmas are provided for the programmer to specify the desired elaboration |
299 order. | 308 order. |
344 | 353 |
345 * *pragma Elaborate_Body* | 354 * *pragma Elaborate_Body* |
346 | 355 |
347 Pragma ``Elaborate_Body`` requires that the body of a unit is elaborated | 356 Pragma ``Elaborate_Body`` requires that the body of a unit is elaborated |
348 immediately after its spec. This restriction guarantees that no client | 357 immediately after its spec. This restriction guarantees that no client |
349 scenario can execute a server target before the target body has been | 358 scenario can invoke a server target before the target body has been |
350 elaborated because the spec and body are effectively "glued" together. | 359 elaborated because the spec and body are effectively "glued" together. |
351 | 360 |
352 :: | 361 :: |
353 | 362 |
354 package Server is | 363 package Server is |
534 Note that there are several allowable suborders for the specs and bodies of | 543 Note that there are several allowable suborders for the specs and bodies of |
535 ``Math`` and ``Computer``, but the point is that these specs and bodies will | 544 ``Math`` and ``Computer``, but the point is that these specs and bodies will |
536 be elaborated prior to ``Client``. | 545 be elaborated prior to ``Client``. |
537 | 546 |
538 Removing pragma ``Elaborate_All`` could result in the following incorrect | 547 Removing pragma ``Elaborate_All`` could result in the following incorrect |
539 elaboration order | 548 elaboration order: |
540 | 549 |
541 :: | 550 :: |
542 | 551 |
543 spec of Math | 552 spec of Math |
544 spec of Computer | 553 spec of Computer |
599 | 608 |
600 .. index:: Dynamic elaboration model | 609 .. index:: Dynamic elaboration model |
601 | 610 |
602 * *Dynamic elaboration model* | 611 * *Dynamic elaboration model* |
603 | 612 |
604 This is the most permissive of the three elaboration models. When the | 613 This is the most permissive of the three elaboration models and emulates the |
605 dynamic model is in effect, GNAT assumes that all code within all units in | 614 behavior specified by the Ada Reference Manual. When the dynamic model is in |
606 a partition is elaboration code. GNAT performs very few diagnostics and | 615 effect, GNAT makes the following assumptions: |
607 generates run-time checks to verify the elaboration order of a program. This | 616 |
608 behavior is identical to that specified by the Ada Reference Manual. The | 617 - All code within all units in a partition is considered to be elaboration |
609 dynamic model is enabled with compiler switch :switch:`-gnatE`. | 618 code. |
619 | |
620 - Some of the invocations in elaboration code may not take place at run time | |
621 due to conditional execution. | |
622 | |
623 GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios | |
624 that invoke internal targets. In addition, GNAT generates run-time checks for | |
625 all external targets and for all scenarios that may exhibit ABE problems. | |
626 | |
627 The elaboration order is obtained by honoring all |with| clauses, purity and | |
628 preelaborability of units, and elaboration-control pragmas. The dynamic model | |
629 attempts to take all invocations in elaboration code into account. If an | |
630 invocation leads to a circularity, GNAT ignores the invocation based on the | |
631 assumptions stated above. An order obtained using the dynamic model may fail | |
632 an ABE check at run time when GNAT ignored an invocation. | |
633 | |
634 The dynamic model is enabled with compiler switch :switch:`-gnatE`. | |
610 | 635 |
611 .. index:: Static elaboration model | 636 .. index:: Static elaboration model |
612 | 637 |
613 * *Static elaboration model* | 638 * *Static elaboration model* |
614 | 639 |
615 This is the middle ground of the three models. When the static model is in | 640 This is the middle ground of the three models. When the static model is in |
616 effect, GNAT performs extensive diagnostics on a unit-by-unit basis for all | 641 effect, GNAT makes the following assumptions: |
617 scenarios that elaborate or execute internal targets. GNAT also generates | 642 |
618 run-time checks for all external targets and for all scenarios that may | 643 - Only code at the library level and in package body statements within all |
619 exhibit ABE problems. Finally, GNAT installs implicit ``Elaborate`` and | 644 units in a partition is considered to be elaboration code. |
620 ``Elaborate_All`` pragmas for server units based on the dependencies of | 645 |
621 client units. The static model is the default model in GNAT. | 646 - All invocations in elaboration will take place at run time, regardless of |
647 conditional execution. | |
648 | |
649 GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios | |
650 that invoke internal targets. In addition, GNAT generates run-time checks for | |
651 all external targets and for all scenarios that may exhibit ABE problems. | |
652 | |
653 The elaboration order is obtained by honoring all |with| clauses, purity and | |
654 preelaborability of units, presence of elaboration-control pragmas, and all | |
655 invocations in elaboration code. An order obtained using the static model is | |
656 guaranteed to be ABE problem-free, excluding dispatching calls and | |
657 access-to-subprogram types. | |
658 | |
659 The static model is the default model in GNAT. | |
622 | 660 |
623 .. index:: SPARK elaboration model | 661 .. index:: SPARK elaboration model |
624 | 662 |
625 * *SPARK elaboration model* | 663 * *SPARK elaboration model* |
626 | 664 |
627 This is the most conservative of the three models and enforces the SPARK | 665 This is the most conservative of the three models and enforces the SPARK |
628 rules of elaboration as defined in the SPARK Reference Manual, section 7.7. | 666 rules of elaboration as defined in the SPARK Reference Manual, section 7.7. |
629 The SPARK model is in effect only when a scenario and a target reside in a | 667 The SPARK model is in effect only when a scenario and a target reside in a |
630 region subject to SPARK_Mode On, otherwise the dynamic or static model is in | 668 region subject to ``SPARK_Mode On``, otherwise the dynamic or static model |
631 effect. | 669 is in effect. |
632 | 670 |
633 .. index:: Legacy elaboration model | 671 The SPARK model is enabled with compiler switch :switch:`-gnatd.v`. |
634 | 672 |
635 * *Legacy elaboration model* | 673 .. index:: Legacy elaboration models |
674 | |
675 * *Legacy elaboration models* | |
636 | 676 |
637 In addition to the three elaboration models outlined above, GNAT provides the | 677 In addition to the three elaboration models outlined above, GNAT provides the |
638 elaboration model of pre-18.x versions referred to as `legacy elaboration | 678 following legacy models: |
639 model`. The legacy elaboration model is enabled with compiler switch | 679 |
640 :switch:`-gnatH`. | 680 - `Legacy elaboration-checking model` available in pre-18.x versions of GNAT. |
681 This model is enabled with compiler switch :switch:`-gnatH`. | |
682 | |
683 - `Legacy elaboration-order model` available in pre-20.x versions of GNAT. | |
684 This model is enabled with binder switch :switch:`-H`. | |
641 | 685 |
642 .. index:: Relaxed elaboration mode | 686 .. index:: Relaxed elaboration mode |
643 | 687 |
644 The dynamic, legacy, and static models can be relaxed using compiler switch | 688 The dynamic, legacy, and static models can be relaxed using compiler switch |
645 :switch:`-gnatJ`, making them more permissive. Note that in this mode, GNAT | 689 :switch:`-gnatJ`, making them more permissive. Note that in this mode, GNAT |
646 may not diagnose certain elaboration issues or install run-time checks. | 690 may not diagnose certain elaboration issues or install run-time checks. |
647 | 691 |
648 .. _Common_Elaboration_Model_Traits": | 692 .. _Mixing_Elaboration_Models: |
649 | 693 |
650 Common Elaboration-model Traits | 694 Mixing Elaboration Models |
651 =============================== | 695 ========================= |
652 | 696 |
653 All three GNAT models are able to detect elaboration problems related to | 697 It is possible to mix units compiled with a different elaboration model, |
654 dispatching calls and a particular kind of ABE referred to as *guaranteed ABE*. | 698 however the following rules must be observed: |
655 | 699 |
656 * *Dispatching calls* | 700 * A client unit compiled with the dynamic model can only |with| a server unit |
657 | 701 that meets at least one of the following criteria: |
658 GNAT installs run-time checks for each primitive subprogram of each tagged | 702 |
659 type defined in a partition on the assumption that a dispatching call | 703 - The server unit is compiled with the dynamic model. |
660 invoked at elaboration time will execute one of these primitives. As a | 704 |
661 result, a dispatching call that executes a primitive whose body has not | 705 - The server unit is a GNAT implementation unit from the ``Ada``, ``GNAT``, |
662 been elaborated yet will raise exception ``Program_Error`` at run time. The | 706 ``Interfaces``, or ``System`` hierarchies. |
663 checks can be suppressed using pragma ``Suppress (Elaboration_Check)``. | 707 |
664 | 708 - The server unit has pragma ``Pure`` or ``Preelaborate``. |
665 * *Guaranteed ABE* | 709 |
666 | 710 - The client unit has an explicit ``Elaborate_All`` pragma for the server |
667 A guaranteed ABE arises when the body of a target is not elaborated early | 711 unit. |
668 enough, and causes all scenarios that directly execute the target to fail. | 712 |
713 These rules ensure that elaboration checks are not omitted. If the rules are | |
714 violated, the binder emits a warning: | |
715 | |
716 :: | |
717 | |
718 warning: "x.ads" has dynamic elaboration checks and with's | |
719 warning: "y.ads" which has static elaboration checks | |
720 | |
721 The warnings can be suppressed by binder switch :switch:`-ws`. | |
722 | |
723 .. _ABE_Diagnostics: | |
724 | |
725 ABE Diagnostics | |
726 =============== | |
727 | |
728 GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios | |
729 that invoke internal targets, regardless of whether the dynamic, SPARK, or | |
730 static model is in effect. | |
731 | |
732 Note that GNAT emits warnings rather than hard errors whenever it encounters an | |
733 elaboration problem. This is because the elaboration model in effect may be too | |
734 conservative, or a particular scenario may not be invoked due conditional | |
735 execution. The warnings can be suppressed selectively with ``pragma Warnings | |
736 (Off)`` or globally with compiler switch :switch:`-gnatwL`. | |
737 | |
738 A *guaranteed ABE* arises when the body of a target is not elaborated early | |
739 enough, and causes *all* scenarios that directly invoke the target to fail. | |
669 | 740 |
670 :: | 741 :: |
671 | 742 |
672 package body Guaranteed_ABE is | 743 package body Guaranteed_ABE is |
673 function ABE return Integer; | 744 function ABE return Integer; |
674 | 745 |
675 Val : constant Integer := ABE; | 746 Val : constant Integer := ABE; |
676 | 747 |
677 function ABE return Integer is | 748 function ABE return Integer is |
678 begin | 749 begin |
679 ... | 750 ... |
680 end ABE; | 751 end ABE; |
681 end Guaranteed_ABE; | 752 end Guaranteed_ABE; |
682 | 753 |
683 In the example above, the elaboration of ``Guaranteed_ABE``'s body elaborates | 754 In the example above, the elaboration of ``Guaranteed_ABE``'s body elaborates |
684 the declaration of ``Val``. This invokes function ``ABE``, however the body | 755 the declaration of ``Val``. This invokes function ``ABE``, however the body of |
685 of ``ABE`` has not been elaborated yet. GNAT emits similar diagnostics in all | 756 ``ABE`` has not been elaborated yet. GNAT emits the following diagnostic: |
686 three models: | 757 |
687 | 758 :: |
688 :: | 759 |
689 | 760 4. Val : constant Integer := ABE; |
690 1. package body Guaranteed_ABE is | 761 | |
691 2. function ABE return Integer; | 762 >>> warning: cannot call "ABE" before body seen |
763 >>> warning: Program_Error will be raised at run time | |
764 | |
765 A *conditional ABE* arises when the body of a target is not elaborated early | |
766 enough, and causes *some* scenarios that directly invoke the target to fail. | |
767 | |
768 :: | |
769 | |
770 1. package body Conditional_ABE is | |
771 2. procedure Force_Body is null; | |
692 3. | 772 3. |
693 4. Val : constant Integer := ABE; | 773 4. generic |
694 | | 774 5. with function Func return Integer; |
695 >>> warning: cannot call "ABE" before body seen | 775 6. package Gen is |
696 >>> warning: Program_Error will be raised at run time | 776 7. Val : constant Integer := Func; |
697 | 777 8. end Gen; |
698 5. | |
699 6. function ABE return Integer is | |
700 7. begin | |
701 8. ... | |
702 9. end ABE; | |
703 10. end Guaranteed_ABE; | |
704 | |
705 Note that GNAT emits warnings rather than hard errors whenever it encounters an | |
706 elaboration problem. This is because the elaboration model in effect may be too | |
707 conservative, or a particular scenario may not be elaborated or executed due to | |
708 data and control flow. The warnings can be suppressed selectively with ``pragma | |
709 Warnigns (Off)`` or globally with compiler switch :switch:`-gnatwL`. | |
710 | |
711 .. _Dynamic_Elaboration_Model_in_GNAT: | |
712 | |
713 Dynamic Elaboration Model in GNAT | |
714 ================================= | |
715 | |
716 The dynamic model assumes that all code within all units in a partition is | |
717 elaboration code. As a result, run-time checks are installed for each scenario | |
718 regardless of whether the target is internal or external. The checks can be | |
719 suppressed using pragma ``Suppress (Elaboration_Check)``. This behavior is | |
720 identical to that specified by the Ada Reference Manual. The following example | |
721 showcases run-time checks installed by GNAT to verify the elaboration state of | |
722 package ``Dynamic_Model``. | |
723 | |
724 :: | |
725 | |
726 with Server; | |
727 package body Dynamic_Model is | |
728 procedure API is | |
729 begin | |
730 ... | |
731 end API; | |
732 | |
733 <check that the body of Server.Gen is elaborated> | |
734 package Inst is new Server.Gen; | |
735 | |
736 T : Server.Task_Type; | |
737 | |
738 begin | |
739 <check that the body of Server.Task_Type is elaborated> | |
740 | |
741 <check that the body of Server.Proc is elaborated> | |
742 Server.Proc; | |
743 end Dynamic_Model; | |
744 | |
745 The checks verify that the body of a target has been successfully elaborated | |
746 before a scenario activates, calls, or instantiates a target. | |
747 | |
748 Note that no scenario within package ``Dynamic_Model`` calls procedure ``API``. | |
749 In fact, procedure ``API`` may not be invoked by elaboration code within the | |
750 partition, however the dynamic model assumes that this can happen. | |
751 | |
752 The dynamic model emits very few diagnostics, but can make suggestions on | |
753 missing ``Elaborate`` and ``Elaborate_All`` pragmas for library-level | |
754 scenarios. This information is available when compiler switch :switch:`-gnatel` | |
755 is in effect. | |
756 | |
757 :: | |
758 | |
759 1. with Server; | |
760 2. package body Dynamic_Model is | |
761 3. Val : constant Integer := Server.Func; | |
762 | | |
763 >>> info: call to "Func" during elaboration | |
764 >>> info: missing pragma "Elaborate_All" for unit "Server" | |
765 | |
766 4. end Dynamic_Model; | |
767 | |
768 .. _Static_Elaboration_Model_in_GNAT: | |
769 | |
770 Static Elaboration Model in GNAT | |
771 ================================ | |
772 | |
773 In contrast to the dynamic model, the static model is more precise in its | |
774 analysis of elaboration code. The model makes a clear distinction between | |
775 internal and external targets, and resorts to different diagnostics and | |
776 run-time checks based on the nature of the target. | |
777 | |
778 * *Internal targets* | |
779 | |
780 The static model performs extensive diagnostics on scenarios which elaborate | |
781 or execute internal targets. The warnings resulting from these diagnostics | |
782 are enabled by default, but can be suppressed selectively with ``pragma | |
783 Warnings (Off)`` or globally with compiler switch :switch:`-gnatwL`. | |
784 | |
785 :: | |
786 | |
787 1. package body Static_Model is | |
788 2. generic | |
789 3. with function Func return Integer; | |
790 4. package Gen is | |
791 5. Val : constant Integer := Func; | |
792 6. end Gen; | |
793 7. | |
794 8. function ABE return Integer; | |
795 9. | 778 9. |
796 10. function Cause_ABE return Boolean is | 779 10. function ABE return Integer; |
797 11. package Inst is new Gen (ABE); | 780 11. |
781 12. function Cause_ABE return Boolean is | |
782 13. package Inst is new Gen (ABE); | |
783 14. begin | |
784 15. ... | |
785 16. end Cause_ABE; | |
786 17. | |
787 18. Val : constant Boolean := Cause_ABE; | |
788 19. | |
789 20. function ABE return Integer is | |
790 21. begin | |
791 22. ... | |
792 23. end ABE; | |
793 24. | |
794 25. Safe : constant Boolean := Cause_ABE; | |
795 26. end Conditional_ABE; | |
796 | |
797 In the example above, the elaboration of package body ``Conditional_ABE`` | |
798 elaborates the declaration of ``Val``. This invokes function ``Cause_ABE``, | |
799 which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of | |
800 ``Inst`` invokes function ``ABE``, however the body of ``ABE`` has not been | |
801 elaborated yet. GNAT emits the following diagnostic: | |
802 | |
803 :: | |
804 | |
805 13. package Inst is new Gen (ABE); | |
798 | | 806 | |
799 >>> warning: in instantiation at line 5 | 807 >>> warning: in instantiation at line 7 |
800 >>> warning: cannot call "ABE" before body seen | 808 >>> warning: cannot call "ABE" before body seen |
801 >>> warning: Program_Error may be raised at run time | 809 >>> warning: Program_Error may be raised at run time |
802 >>> warning: body of unit "Static_Model" elaborated | 810 >>> warning: body of unit "Conditional_ABE" elaborated |
803 >>> warning: function "Cause_ABE" called at line 16 | 811 >>> warning: function "Cause_ABE" called at line 18 |
804 >>> warning: function "ABE" called at line 5, instance at line 11 | 812 >>> warning: function "ABE" called at line 7, instance at line 13 |
805 | 813 |
806 12. begin | 814 Note that the same ABE problem does not occur with the elaboration of |
807 13. ... | 815 declaration ``Safe`` because the body of function ``ABE`` has already been |
808 14. end Cause_ABE; | 816 elaborated at that point. |
809 15. | 817 |
810 16. Val : constant Boolean := Cause_ABE; | 818 .. _SPARK_Diagnostics: |
811 17. | 819 |
812 18. function ABE return Integer is | 820 SPARK Diagnostics |
813 19. begin | 821 ================= |
814 20. ... | 822 |
815 21. end ABE; | 823 GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference |
816 22. end Static_Model; | 824 Manual section 7.7 when compiler switch :switch:`-gnatd.v` is in effect. Note |
817 | 825 that GNAT emits hard errors whenever it encounters a violation of the SPARK |
818 The example above illustrates an ABE problem within package ``Static_Model``, | 826 rules. |
819 which is hidden by several layers of indirection. The elaboration of package | 827 |
820 body ``Static_Model`` elaborates the declaration of ``Val``. This invokes | 828 :: |
821 function ``Cause_ABE``, which instantiates generic unit ``Gen`` as ``Inst``. | 829 |
822 The elaboration of ``Inst`` invokes function ``ABE``, however the body of | 830 1. with Server; |
823 ``ABE`` has not been elaborated yet. | 831 2. package body SPARK_Diagnostics with SPARK_Mode is |
824 | 832 3. Val : constant Integer := Server.Func; |
825 * *External targets* | 833 | |
826 | 834 >>> call to "Func" during elaboration in SPARK |
827 The static model installs run-time checks to verify the elaboration status | 835 >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server" |
828 of server targets only when the scenario that elaborates or executes that | 836 >>> body of unit "SPARK_Model" elaborated |
829 target is part of the elaboration code of the client unit. The checks can be | 837 >>> function "Func" called at line 3 |
830 suppressed using pragma ``Suppress (Elaboration_Check)``. | 838 |
831 | 839 4. end SPARK_Diagnostics; |
832 :: | 840 |
833 | 841 .. _Elaboration_Circularities: |
834 with Server; | 842 |
835 package body Static_Model is | 843 Elaboration Circularities |
836 generic | 844 ========================= |
837 with function Func return Integer; | 845 |
838 package Gen is | 846 An **elaboration circularity** occurs whenever the elaboration of a set of |
839 Val : constant Integer := Func; | 847 units enters a deadlocked state, where each unit is waiting for another unit |
840 end Gen; | 848 to be elaborated. This situation may be the result of improper use of |with| |
841 | 849 clauses, elaboration-control pragmas, or invocations in elaboration code. |
842 function Call_Func return Boolean is | 850 |
843 <check that the body of Server.Func is elaborated> | 851 The following example exhibits an elaboration circularity. |
844 package Inst is new Gen (Server.Func); | 852 |
853 :: | |
854 | |
855 with B; pragma Elaborate (B); | |
856 package A is | |
857 end A; | |
858 | |
859 :: | |
860 | |
861 package B is | |
862 procedure Force_Body; | |
863 end B; | |
864 | |
865 :: | |
866 | |
867 with C; | |
868 package body B is | |
869 procedure Force_Body is null; | |
870 | |
871 Elab : constant Integer := C.Func; | |
872 end B; | |
873 | |
874 :: | |
875 | |
876 package C is | |
877 function Func return Integer; | |
878 end C; | |
879 | |
880 :: | |
881 | |
882 with A; | |
883 package body C is | |
884 function Func return Integer is | |
845 begin | 885 begin |
846 ... | 886 ... |
847 end Call_Func; | 887 end Func; |
848 | 888 end C; |
849 Val : constant Boolean := Call_Func; | 889 |
850 end Static_Model; | 890 The binder emits the following diagnostic: |
851 | 891 |
852 In the example above, the elaboration of package body ``Static_Model`` | 892 :: |
853 elaborates the declaration of ``Val``. This invokes function ``Call_Func``, | 893 |
854 which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of | 894 error: Elaboration circularity detected |
855 ``Inst`` invokes function ``Server.Func``. Since ``Server.Func`` is an | 895 info: |
856 external target, GNAT installs a run-time check to verify that its body has | 896 info: Reason: |
857 been elaborated. | 897 info: |
858 | 898 info: unit "a (spec)" depends on its own elaboration |
859 In addition to checks, the static model installs implicit ``Elaborate`` and | 899 info: |
860 ``Elaborate_All`` pragmas to guarantee safe elaboration use of server units. | 900 info: Circularity: |
861 This information is available when compiler switch :switch:`-gnatel` is in | 901 info: |
862 effect. | 902 info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)" |
863 | 903 info: unit "b (body)" is in the closure of pragma Elaborate |
864 :: | 904 info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time |
865 | 905 info: unit "c (body)" has with clause for unit "a (spec)" |
866 1. with Server; | 906 info: |
867 2. package body Static_Model is | 907 info: Suggestions: |
868 3. generic | 908 info: |
869 4. with function Func return Integer; | 909 info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)" |
870 5. package Gen is | 910 info: use the dynamic elaboration model (compiler switch -gnatE) |
871 6. Val : constant Integer := Func; | 911 |
872 7. end Gen; | 912 The diagnostic consist of the following sections: |
873 8. | 913 |
874 9. function Call_Func return Boolean is | 914 * Reason |
875 10. package Inst is new Gen (Server.Func); | 915 |
876 | | 916 This section provides a short explanation describing why the set of units |
877 >>> info: instantiation of "Gen" during elaboration | 917 could not be ordered. |
878 >>> info: in instantiation at line 6 | 918 |
879 >>> info: call to "Func" during elaboration | 919 * Circularity |
880 >>> info: in instantiation at line 6 | 920 |
881 >>> info: implicit pragma "Elaborate_All" generated for unit "Server" | 921 This section enumerates the units comprising the deadlocked set, along with |
882 >>> info: body of unit "Static_Model" elaborated | 922 their interdependencies. |
883 >>> info: function "Call_Func" called at line 15 | 923 |
884 >>> info: function "Func" called at line 6, instance at line 10 | 924 * Suggestions |
885 | 925 |
886 11. begin | 926 This section enumerates various tactics for eliminating the circularity. |
887 12. ... | |
888 13. end Call_Func; | |
889 14. | |
890 15. Val : constant Boolean := Call_Func; | |
891 | | |
892 >>> info: call to "Call_Func" during elaboration | |
893 | |
894 16. end Static_Model; | |
895 | |
896 In the example above, the elaboration of package body ``Static_Model`` | |
897 elaborates the declaration of ``Val``. This invokes function ``Call_Func``, | |
898 which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of | |
899 ``Inst`` invokes function ``Server.Func``. Since ``Server.Func`` is an | |
900 external target, GNAT installs an implicit ``Elaborate_All`` pragma for unit | |
901 ``Server``. The pragma guarantees that both the spec and body of ``Server``, | |
902 along with any additional dependencies that ``Server`` may require, are | |
903 elaborated prior to the body of ``Static_Model``. | |
904 | |
905 .. _SPARK_Elaboration_Model_in_GNAT: | |
906 | |
907 SPARK Elaboration Model in GNAT | |
908 =============================== | |
909 | |
910 The SPARK model is identical to the static model in its handling of internal | |
911 targets. The SPARK model, however, requires explicit ``Elaborate`` or | |
912 ``Elaborate_All`` pragmas to be present in the program when a target is | |
913 external, and compiler switch :switch:`-gnatd.v` is in effect. | |
914 | |
915 :: | |
916 | |
917 1. with Server; | |
918 2. package body SPARK_Model with SPARK_Mode is | |
919 3. Val : constant Integer := Server.Func; | |
920 | | |
921 >>> call to "Func" during elaboration in SPARK | |
922 >>> unit "SPARK_Model" requires pragma "Elaborate_All" for "Server" | |
923 >>> body of unit "SPARK_Model" elaborated | |
924 >>> function "Func" called at line 3 | |
925 | |
926 4. end SPARK_Model; | |
927 | |
928 Legacy Elaboration Model in GNAT | |
929 ================================ | |
930 | |
931 The legacy elaboration model is provided for compatibility with code bases | |
932 developed with pre-18.x versions of GNAT. It is similar in functionality to | |
933 the dynamic and static models of post-18.x version of GNAT, but may differ | |
934 in terms of diagnostics and run-time checks. The legacy elaboration model is | |
935 enabled with compiler switch :switch:`-gnatH`. | |
936 | |
937 .. _Mixing_Elaboration_Models: | |
938 | |
939 Mixing Elaboration Models | |
940 ========================= | |
941 | |
942 It is possible to mix units compiled with a different elaboration model, | |
943 however the following rules must be observed: | |
944 | |
945 * A client unit compiled with the dynamic model can only |with| a server unit | |
946 that meets at least one of the following criteria: | |
947 | |
948 - The server unit is compiled with the dynamic model. | |
949 | |
950 - The server unit is a GNAT implementation unit from the Ada, GNAT, | |
951 Interfaces, or System hierarchies. | |
952 | |
953 - The server unit has pragma ``Pure`` or ``Preelaborate``. | |
954 | |
955 - The client unit has an explicit ``Elaborate_All`` pragma for the server | |
956 unit. | |
957 | |
958 These rules ensure that elaboration checks are not omitted. If the rules are | |
959 violated, the binder emits a warning: | |
960 | |
961 :: | |
962 | |
963 warning: "x.ads" has dynamic elaboration checks and with's | |
964 warning: "y.ads" which has static elaboration checks | |
965 | |
966 The warnings can be suppressed by binder switch :switch:`-ws`. | |
967 | |
968 .. _Elaboration_Circularities: | |
969 | |
970 Elaboration Circularities | |
971 ========================= | |
972 | |
973 If the binder cannot find an acceptable elaboration order, it outputs detailed | |
974 diagnostics describing an **elaboration circularity**. | |
975 | |
976 :: | |
977 | |
978 package Server is | |
979 function Func return Integer; | |
980 end Server; | |
981 | |
982 :: | |
983 | |
984 with Client; | |
985 package body Server is | |
986 function Func return Integer is | |
987 begin | |
988 ... | |
989 end Func; | |
990 end Server; | |
991 | |
992 :: | |
993 | |
994 with Server; | |
995 package Client is | |
996 Val : constant Integer := Server.Func; | |
997 end Client; | |
998 | |
999 :: | |
1000 | |
1001 with Client; | |
1002 procedure Main is begin null; end Main; | |
1003 | |
1004 :: | |
1005 | |
1006 error: elaboration circularity detected | |
1007 info: "server (body)" must be elaborated before "client (spec)" | |
1008 info: reason: implicit Elaborate_All in unit "client (spec)" | |
1009 info: recompile "client (spec)" with -gnatel for full details | |
1010 info: "server (body)" | |
1011 info: must be elaborated along with its spec: | |
1012 info: "server (spec)" | |
1013 info: which is withed by: | |
1014 info: "client (spec)" | |
1015 info: "client (spec)" must be elaborated before "server (body)" | |
1016 info: reason: with clause | |
1017 | |
1018 In the example above, ``Client`` must be elaborated prior to ``Main`` by virtue | |
1019 of a |with| clause. The elaboration of ``Client`` invokes ``Server.Func``, and | |
1020 static model generates an implicit ``Elaborate_All`` pragma for ``Server``. The | |
1021 pragma implies that both the spec and body of ``Server``, along with any units | |
1022 they |with|, must be elaborated prior to ``Client``. However, ``Server``'s body | |
1023 |withs| ``Client``, implying that ``Client`` must be elaborated prior to | |
1024 ``Server``. The end result is that ``Client`` must be elaborated prior to | |
1025 ``Client``, and this leads to a circularity. | |
1026 | 927 |
1027 .. _Resolving_Elaboration_Circularities: | 928 .. _Resolving_Elaboration_Circularities: |
1028 | 929 |
1029 Resolving Elaboration Circularities | 930 Resolving Elaboration Circularities |
1030 =================================== | 931 =================================== |
1031 | 932 |
1032 When faced with an elaboration circularity, a programmer has several options | 933 The most desirable option from the point of view of long-term maintenance is to |
1033 available. | 934 rearrange the program so that the elaboration problems are avoided. One useful |
1034 | 935 technique is to place the elaboration code into separate child packages. |
1035 * *Fix the program* | 936 Another is to move some of the initialization code to explicitly invoked |
1036 | 937 subprograms, where the program controls the order of initialization explicitly. |
1037 The most desirable option from the point of view of long-term maintenance | 938 Although this is the most desirable option, it may be impractical and involve |
1038 is to rearrange the program so that the elaboration problems are avoided. | 939 too much modification, especially in the case of complex legacy code. |
1039 One useful technique is to place the elaboration code into separate child | 940 |
1040 packages. Another is to move some of the initialization code to explicitly | 941 When faced with an elaboration circularity, the programmer should also consider |
1041 invoked subprograms, where the program controls the order of initialization | 942 the tactics given in the suggestions section of the circularity diagnostic. |
1042 explicitly. Although this is the most desirable option, it may be impractical | 943 Depending on the units involved in the circularity, their |with| clauses, |
1043 and involve too much modification, especially in the case of complex legacy | 944 purity, preelaborability, presence of elaboration-control pragmas and |
1044 code. | 945 invocations at elaboration time, the binder may suggest one or more of the |
1045 | 946 following tactics to eliminate the circularity: |
1046 * *Switch to more permissive elaboration model* | 947 |
1047 | 948 * Pragma Elaborate elimination |
1048 If the compilation was performed using the static model, enable the dynamic | 949 |
1049 model with compiler switch :switch:`-gnatE`. GNAT will no longer generate | 950 :: |
1050 implicit ``Elaborate`` and ``Elaborate_All`` pragmas, resulting in a behavior | 951 |
1051 identical to that specified by the Ada Reference Manual. The binder will | 952 remove pragma Elaborate for unit "..." in unit "..." |
1052 generate an executable program that may or may not raise ``Program_Error``, | 953 |
1053 and it is the programmer's responsibility to ensure that it does not raise | 954 This tactic is suggested when the binder has determined that pragma |
1054 ``Program_Error``. | 955 ``Elaborate``: |
1055 | 956 |
1056 If the compilation was performed using a post-18.x version of GNAT, consider | 957 - Prevents a set of units from being elaborated. |
1057 using the legacy elaboration model, in the following order: | 958 |
1058 | 959 - The removal of the pragma will not eliminate the semantic effects of the |
1059 - Use the legacy static elaboration model, with compiler switch | 960 pragma. In other words, the argument of the pragma will still be elaborated |
1060 :switch:`-gnatH`. | 961 prior to the unit containing the pragma. |
1061 | 962 |
1062 - Use the legacy dynamic elaboration model, with compiler switches | 963 - The removal of the pragma will enable the successful ordering of the units. |
1063 :switch:`-gnatH` :switch:`-gnatE`. | 964 |
1064 | 965 The programmer should remove the pragma as advised, and rebuild the program. |
1065 - Use the relaxed legacy static elaboration model, with compiler switches | 966 |
1066 :switch:`-gnatH` :switch:`-gnatJ`. | 967 * Pragma Elaborate_All elimination |
1067 | 968 |
1068 - Use the relaxed legacy dynamic elaboration model, with compiler switches | 969 :: |
1069 :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE`. | 970 |
1070 | 971 remove pragma Elaborate_All for unit "..." in unit "..." |
1071 * *Suppress all elaboration checks* | 972 |
1072 | 973 This tactic is suggested when the binder has determined that pragma |
1073 The drawback of run-time checks is that they generate overhead at run time, | 974 ``Elaborate_All``: |
1074 both in space and time. If the programmer is absolutely sure that a program | 975 |
1075 will not raise an elaboration-related ``Program_Error``, then using the | 976 - Prevents a set of units from being elaborated. |
1076 pragma ``Suppress (Elaboration_Check)`` globally (as a configuration pragma) | 977 |
1077 will eliminate all run-time checks. | 978 - The removal of the pragma will not eliminate the semantic effects of the |
1078 | 979 pragma. In other words, the argument of the pragma along with its |with| |
1079 * *Suppress elaboration checks selectively* | 980 closure will still be elaborated prior to the unit containing the pragma. |
1080 | 981 |
1081 If a scenario cannot possibly lead to an elaboration ``Program_Error``, | 982 - The removal of the pragma will enable the successful ordering of the units. |
1082 and the binder nevertheless complains about implicit ``Elaborate`` and | 983 |
1083 ``Elaborate_All`` pragmas that lead to elaboration circularities, it | 984 The programmer should remove the pragma as advised, and rebuild the program. |
1084 is possible to suppress the generation of implicit ``Elaborate`` and | 985 |
1085 ``Elaborate_All`` pragmas, as well as run-time checks. Clearly this can | 986 * Pragma Elaborate_All downgrade |
1086 be unsafe, and it is the responsibility of the programmer to make sure | 987 |
1087 that the resulting program has no elaboration anomalies. Pragma | 988 :: |
1088 ``Suppress (Elaboration_Check)`` can be used with different levels of | 989 |
1089 granularity to achieve these effects. | 990 change pragma Elaborate_All for unit "..." to Elaborate in unit "..." |
1090 | 991 |
1091 - *Target suppression* | 992 This tactic is always suggested with the pragma ``Elaborate_All`` elimination |
1092 | 993 tactic. It offers a different alernative of guaranteeing that the argument of |
1093 When the pragma is placed in a declarative part, without a second argument | 994 the pragma will still be elaborated prior to the unit containing the pragma. |
1094 naming an entity, it will suppress implicit ``Elaborate`` and | 995 |
1095 ``Elaborate_All`` pragma generation, as well as run-time checks, on all | 996 The programmer should update the pragma as advised, and rebuild the program. |
1096 targets within the region. | 997 |
1097 | 998 * Pragma Elaborate_Body elimination |
1098 :: | 999 |
1099 | 1000 :: |
1100 package Range_Suppress is | 1001 |
1101 pragma Suppress (Elaboration_Check); | 1002 remove pragma Elaborate_Body in unit "..." |
1102 | 1003 |
1103 function Func return Integer; | 1004 This tactic is suggested when the binder has determined that pragma |
1104 | 1005 ``Elaborate_Body``: |
1105 generic | 1006 |
1106 procedure Gen; | 1007 - Prevents a set of units from being elaborated. |
1107 | 1008 |
1108 pragma Unsuppress (Elaboration_Check); | 1009 - The removal of the pragma will enable the successful ordering of the units. |
1109 | 1010 |
1110 task type Tsk; | 1011 Note that the binder cannot determine whether the pragma is required for |
1111 end Range_Suppress; | 1012 other purposes, such as guaranteeing the initialization of a variable |
1112 | 1013 declared in the spec by elaboration code in the body. |
1113 In the example above, a pair of Suppress/Unsuppress pragmas define a region | 1014 |
1114 of suppression within package ``Range_Suppress``. As a result, no implicit | 1015 The programmer should remove the pragma as advised, and rebuild the program. |
1115 ``Elaborate`` and ``Elaborate_All`` pragmas, nor any run-time checks, will | 1016 |
1116 be generated by callers of ``Func`` and instantiators of ``Gen``. Note that | 1017 * Use of pragma Restrictions |
1117 task type ``Tsk`` is not within this region. | 1018 |
1118 | 1019 :: |
1119 An alternative to the region-based suppression is to use multiple | 1020 |
1120 ``Suppress`` pragmas with arguments naming specific entities for which | 1021 use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code) |
1121 elaboration checks should be suppressed: | 1022 |
1122 | 1023 This tactic is suggested when the binder has determined that a task |
1123 :: | 1024 activation at elaboration time: |
1124 | 1025 |
1125 package Range_Suppress is | 1026 - Prevents a set of units from being elaborated. |
1126 function Func return Integer; | 1027 |
1127 pragma Suppress (Elaboration_Check, Func); | 1028 Note that the binder cannot determine with certainty whether the task will |
1128 | 1029 block at elaboration time. |
1129 generic | 1030 |
1130 procedure Gen; | 1031 The programmer should create a configuration file, place the pragma within, |
1131 pragma Suppress (Elaboration_Check, Gen); | 1032 update the general compilation arguments, and rebuild the program. |
1132 | 1033 |
1133 task type Tsk; | 1034 * Use of dynamic elaboration model |
1134 end Range_Suppress; | 1035 |
1135 | 1036 :: |
1136 - *Scenario suppression* | 1037 |
1137 | 1038 use the dynamic elaboration model (compiler switch -gnatE) |
1138 When the pragma ``Suppress`` is placed in a declarative or statement | 1039 |
1139 part, without an entity argument, it will suppress implicit ``Elaborate`` | 1040 This tactic is suggested when the binder has determined that an invocation at |
1140 and ``Elaborate_All`` pragma generation, as well as run-time checks, on | 1041 elaboration time: |
1141 all scenarios within the region. | 1042 |
1142 | 1043 - Prevents a set of units from being elaborated. |
1143 :: | 1044 |
1144 | 1045 - The use of the dynamic model will enable the successful ordering of the |
1145 with Server; | 1046 units. |
1146 package body Range_Suppress is | 1047 |
1147 pragma Suppress (Elaboration_Check); | 1048 The programmer has two options: |
1148 | 1049 |
1149 function Func return Integer is | 1050 - Determine the units involved in the invocation using the detailed |
1150 begin | 1051 invocation information, and add compiler switch :switch:`-gnatE` to the |
1151 return Server.Func; | 1052 compilation arguments of selected files only. This approach will yield |
1152 end Func; | 1053 safer elaboration orders compared to the other option because it will |
1153 | 1054 minimize the opportunities presented to the dynamic model for ignoring |
1154 procedure Gen is | 1055 invocations. |
1155 begin | 1056 |
1156 Server.Proc; | 1057 - Add compiler switch :switch:`-gnatE` to the general compilation arguments. |
1157 end Gen; | 1058 |
1158 | 1059 * Use of detailed invocation information |
1159 pragma Unsuppress (Elaboration_Check); | 1060 |
1160 | 1061 :: |
1161 task body Tsk is | 1062 |
1162 begin | 1063 use detailed invocation information (compiler switch -gnatd_F) |
1163 Server.Proc; | 1064 |
1164 end Tsk; | 1065 This tactic is always suggested with the use of the dynamic model tactic. It |
1165 end Range_Suppress; | 1066 causes the circularity section of the circularity diagnostic to describe the |
1166 | 1067 flow of elaboration code from a unit to a unit, enumerating all such paths in |
1167 In the example above, a pair of Suppress/Unsuppress pragmas define a region | 1068 the process. |
1168 of suppression within package body ``Range_Suppress``. As a result, the | 1069 |
1169 calls to ``Server.Func`` in ``Func`` and ``Server.Proc`` in ``Gen`` will | 1070 The programmer should analyze this information to determine which units |
1170 not generate any implicit ``Elaborate`` and ``Elaborate_All`` pragmas or | 1071 should be compiled with the dynamic model. |
1171 run-time checks. | 1072 |
1172 | 1073 * Forced-dependency elimination |
1173 .. _Resolving_Task_Issues: | 1074 |
1174 | 1075 :: |
1175 Resolving Task Issues | 1076 |
1176 ===================== | 1077 remove the dependency of unit "..." on unit "..." from the argument of switch -f |
1177 | 1078 |
1178 The model of execution in Ada dictates that elaboration must first take place, | 1079 This tactic is suggested when the binder has determined that a dependency |
1179 and only then can the main program be started. Tasks which are activated during | 1080 present in the forced-elaboration-order file indicated by binder switch |
1180 elaboration violate this model and may lead to serious concurrent problems at | 1081 :switch:`-f`: |
1181 elaboration time. | 1082 |
1182 | 1083 - Prevents a set of units from being elaborated. |
1183 A task can be activated in two different ways: | 1084 |
1184 | 1085 - The removal of the dependency will enable the successful ordering of the |
1185 * The task is created by an allocator in which case it is activated immediately | 1086 units. |
1186 after the allocator is evaluated. | 1087 |
1187 | 1088 The programmer should edit the forced-elaboration-order file, remove the |
1188 * The task is declared at the library level or within some nested master in | 1089 dependency, and rebind the program. |
1189 which case it is activated before starting execution of the statement | 1090 |
1190 sequence of the master defining the task. | 1091 * All forced-dependency elimination |
1191 | 1092 |
1192 Since the elaboration of a partition is performed by the environment task | 1093 :: |
1193 servicing that partition, any tasks activated during elaboration may be in | 1094 |
1194 a race with the environment task, and lead to unpredictable state and behavior. | 1095 remove switch -f |
1195 The static model seeks to avoid such interactions by assuming that all code in | 1096 |
1196 the task body is executed at elaboration time, if the task was activated by | 1097 This tactic is suggested in case editing the forced-elaboration-order file is |
1197 elaboration code. | 1098 not an option. |
1198 | 1099 |
1199 :: | 1100 The programmer should remove binder switch :switch:`-f` from the binder |
1200 | 1101 arguments, and rebind. |
1201 package Decls is | 1102 |
1202 task Lib_Task is | 1103 * Multiple-circularities diagnostic |
1203 entry Start; | 1104 |
1204 end Lib_Task; | 1105 :: |
1205 | 1106 |
1206 type My_Int is new Integer; | 1107 diagnose all circularities (binder switch -d_C) |
1207 | 1108 |
1208 function Ident (M : My_Int) return My_Int; | 1109 By default, the binder will diagnose only the highest-precedence circularity. |
1209 end Decls; | 1110 If the program contains multiple circularities, the binder will suggest the |
1210 | 1111 use of binder switch :switch:`-d_C` in order to obtain the diagnostics of all |
1211 :: | 1112 circularities. |
1212 | 1113 |
1213 with Utils; | 1114 The programmer should add binder switch :switch:`-d_C` to the binder |
1214 package body Decls is | 1115 arguments, and rebind. |
1215 task body Lib_Task is | 1116 |
1216 begin | 1117 If none of the tactics suggested by the binder eliminate the elaboration |
1217 accept Start; | 1118 circularity, the programmer should consider using one of the legacy elaboration |
1218 Utils.Put_Val (2); | 1119 models, in the following order: |
1219 end Lib_Task; | 1120 |
1220 | 1121 * Use the pre-20.x legacy elaboration-order model, with binder switch |
1221 function Ident (M : My_Int) return My_Int is | 1122 :switch:`-H`. |
1222 begin | 1123 |
1223 return M; | 1124 * Use both pre-18.x and pre-20.x legacy elaboration models, with compiler |
1224 end Ident; | 1125 switch :switch:`-gnatH` and binder switch :switch:`-H`. |
1225 end Decls; | 1126 |
1226 | 1127 * Use the relaxed static-elaboration model, with compiler switches |
1227 :: | 1128 :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`. |
1228 | 1129 |
1229 with Decls; | 1130 * Use the relaxed dynamic-elaboration model, with compiler switches |
1230 package Utils is | 1131 :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch |
1231 procedure Put_Val (Arg : Decls.My_Int); | 1132 :switch:`-H`. |
1232 end Utils; | |
1233 | |
1234 :: | |
1235 | |
1236 with Ada.Text_IO; use Ada.Text_IO; | |
1237 package body Utils is | |
1238 procedure Put_Val (Arg : Decls.My_Int) is | |
1239 begin | |
1240 Put_Line (Arg'Img); | |
1241 end Put_Val; | |
1242 end Utils; | |
1243 | |
1244 :: | |
1245 | |
1246 with Decls; | |
1247 procedure Main is | |
1248 begin | |
1249 Decls.Lib_Task.Start; | |
1250 end Main; | |
1251 | |
1252 When the above example is compiled with the static model, an elaboration | |
1253 circularity arises: | |
1254 | |
1255 :: | |
1256 | |
1257 error: elaboration circularity detected | |
1258 info: "decls (body)" must be elaborated before "decls (body)" | |
1259 info: reason: implicit Elaborate_All in unit "decls (body)" | |
1260 info: recompile "decls (body)" with -gnatel for full details | |
1261 info: "decls (body)" | |
1262 info: must be elaborated along with its spec: | |
1263 info: "decls (spec)" | |
1264 info: which is withed by: | |
1265 info: "utils (spec)" | |
1266 info: which is withed by: | |
1267 info: "decls (body)" | |
1268 | |
1269 In the above example, ``Decls`` must be elaborated prior to ``Main`` by virtue | |
1270 of a with clause. The elaboration of ``Decls`` activates task ``Lib_Task``. The | |
1271 static model conservatibely assumes that all code within the body of | |
1272 ``Lib_Task`` is executed, and generates an implicit ``Elaborate_All`` pragma | |
1273 for ``Units`` due to the call to ``Utils.Put_Val``. The pragma implies that | |
1274 both the spec and body of ``Utils``, along with any units they |with|, | |
1275 must be elaborated prior to ``Decls``. However, ``Utils``'s spec |withs| | |
1276 ``Decls``, implying that ``Decls`` must be elaborated before ``Utils``. The end | |
1277 result is that ``Utils`` must be elaborated prior to ``Utils``, and this | |
1278 leads to a circularity. | |
1279 | |
1280 In reality, the example above will not exhibit an ABE problem at run time. | |
1281 When the body of task ``Lib_Task`` is activated, execution will wait for entry | |
1282 ``Start`` to be accepted, and the call to ``Utils.Put_Val`` will not take place | |
1283 at elaboration time. Task ``Lib_Task`` will resume its execution after the main | |
1284 program is executed because ``Main`` performs a rendezvous with | |
1285 ``Lib_Task.Start``, and at that point all units have already been elaborated. | |
1286 As a result, the static model may seem overly conservative, partly because it | |
1287 does not take control and data flow into account. | |
1288 | |
1289 When faced with a task elaboration circularity, a programmer has several | |
1290 options available: | |
1291 | |
1292 * *Use the dynamic model* | |
1293 | |
1294 The dynamic model does not generate implicit ``Elaborate`` and | |
1295 ``Elaborate_All`` pragmas. Instead, it will install checks prior to every | |
1296 call in the example above, thus verifying the successful elaboration of | |
1297 ``Utils.Put_Val`` in case the call to it takes place at elaboration time. | |
1298 The dynamic model is enabled with compiler switch :switch:`-gnatE`. | |
1299 | |
1300 * *Isolate the tasks* | |
1301 | |
1302 Relocating tasks in their own separate package could decouple them from | |
1303 dependencies that would otherwise cause an elaboration circularity. The | |
1304 example above can be rewritten as follows: | |
1305 | |
1306 :: | |
1307 | |
1308 package Decls1 is -- new | |
1309 task Lib_Task is | |
1310 entry Start; | |
1311 end Lib_Task; | |
1312 end Decls1; | |
1313 | |
1314 :: | |
1315 | |
1316 with Utils; | |
1317 package body Decls1 is -- new | |
1318 task body Lib_Task is | |
1319 begin | |
1320 accept Start; | |
1321 Utils.Put_Val (2); | |
1322 end Lib_Task; | |
1323 end Decls1; | |
1324 | |
1325 :: | |
1326 | |
1327 package Decls2 is -- new | |
1328 type My_Int is new Integer; | |
1329 function Ident (M : My_Int) return My_Int; | |
1330 end Decls2; | |
1331 | |
1332 :: | |
1333 | |
1334 with Utils; | |
1335 package body Decls2 is -- new | |
1336 function Ident (M : My_Int) return My_Int is | |
1337 begin | |
1338 return M; | |
1339 end Ident; | |
1340 end Decls2; | |
1341 | |
1342 :: | |
1343 | |
1344 with Decls2; | |
1345 package Utils is | |
1346 procedure Put_Val (Arg : Decls2.My_Int); | |
1347 end Utils; | |
1348 | |
1349 :: | |
1350 | |
1351 with Ada.Text_IO; use Ada.Text_IO; | |
1352 package body Utils is | |
1353 procedure Put_Val (Arg : Decls2.My_Int) is | |
1354 begin | |
1355 Put_Line (Arg'Img); | |
1356 end Put_Val; | |
1357 end Utils; | |
1358 | |
1359 :: | |
1360 | |
1361 with Decls1; | |
1362 procedure Main is | |
1363 begin | |
1364 Decls1.Lib_Task.Start; | |
1365 end Main; | |
1366 | |
1367 * *Declare the tasks* | |
1368 | |
1369 The original example uses a single task declaration for ``Lib_Task``. An | |
1370 explicit task type declaration and a properly placed task object could avoid | |
1371 the dependencies that would otherwise cause an elaboration circularity. The | |
1372 example can be rewritten as follows: | |
1373 | |
1374 :: | |
1375 | |
1376 package Decls is | |
1377 task type Lib_Task is -- new | |
1378 entry Start; | |
1379 end Lib_Task; | |
1380 | |
1381 type My_Int is new Integer; | |
1382 | |
1383 function Ident (M : My_Int) return My_Int; | |
1384 end Decls; | |
1385 | |
1386 :: | |
1387 | |
1388 with Utils; | |
1389 package body Decls is | |
1390 task body Lib_Task is | |
1391 begin | |
1392 accept Start; | |
1393 Utils.Put_Val (2); | |
1394 end Lib_Task; | |
1395 | |
1396 function Ident (M : My_Int) return My_Int is | |
1397 begin | |
1398 return M; | |
1399 end Ident; | |
1400 end Decls; | |
1401 | |
1402 :: | |
1403 | |
1404 with Decls; | |
1405 package Utils is | |
1406 procedure Put_Val (Arg : Decls.My_Int); | |
1407 end Utils; | |
1408 | |
1409 :: | |
1410 | |
1411 with Ada.Text_IO; use Ada.Text_IO; | |
1412 package body Utils is | |
1413 procedure Put_Val (Arg : Decls.My_Int) is | |
1414 begin | |
1415 Put_Line (Arg'Img); | |
1416 end Put_Val; | |
1417 end Utils; | |
1418 | |
1419 :: | |
1420 | |
1421 with Decls; | |
1422 package Obj_Decls is -- new | |
1423 Task_Obj : Decls.Lib_Task; | |
1424 end Obj_Decls; | |
1425 | |
1426 :: | |
1427 | |
1428 with Obj_Decls; | |
1429 procedure Main is | |
1430 begin | |
1431 Obj_Decls.Task_Obj.Start; -- new | |
1432 end Main; | |
1433 | |
1434 * *Use restriction No_Entry_Calls_In_Elaboration_Code* | |
1435 | |
1436 The issue exhibited in the original example under this section revolves | |
1437 around the body of ``Lib_Task`` blocking on an accept statement. There is | |
1438 no rule to prevent elaboration code from performing entry calls, however in | |
1439 practice this is highly unusual. In addition, the pattern of starting tasks | |
1440 at elaboration time and then immediately blocking on accept or select | |
1441 statements is quite common. | |
1442 | |
1443 If a programmer knows that elaboration code will not perform any entry | |
1444 calls, then the programmer can indicate that the static model should not | |
1445 process the remainder of a task body once an accept or select statement has | |
1446 been encountered. This behavior can be specified by a configuration pragma: | |
1447 | |
1448 :: | |
1449 | |
1450 pragma Restrictions (No_Entry_Calls_In_Elaboration_Code); | |
1451 | |
1452 In addition to the change in behavior with respect to task bodies, the | |
1453 static model will verify that no entry calls take place at elaboration time. | |
1454 | 1133 |
1455 .. _Elaboration_Related_Compiler_Switches: | 1134 .. _Elaboration_Related_Compiler_Switches: |
1456 | 1135 |
1457 Elaboration-related Compiler Switches | 1136 Elaboration-related Compiler Switches |
1458 ===================================== | 1137 ===================================== |
1463 .. index:: -gnatE (gnat) | 1142 .. index:: -gnatE (gnat) |
1464 | 1143 |
1465 :switch:`-gnatE` | 1144 :switch:`-gnatE` |
1466 Dynamic elaboration checking mode enabled | 1145 Dynamic elaboration checking mode enabled |
1467 | 1146 |
1468 When this switch is in effect, GNAT activates the dynamic elaboration model. | 1147 When this switch is in effect, GNAT activates the dynamic model. |
1469 | 1148 |
1470 .. index:: -gnatel (gnat) | 1149 .. index:: -gnatel (gnat) |
1471 | 1150 |
1472 :switch:`-gnatel` | 1151 :switch:`-gnatel` |
1473 Turn on info messages on generated Elaborate[_All] pragmas | 1152 Turn on info messages on generated Elaborate[_All] pragmas |
1474 | 1153 |
1154 This switch is only applicable to the pre-20.x legacy elaboration models. | |
1155 The post-20.x elaboration model no longer relies on implicitly generated | |
1156 ``Elaborate`` and ``Elaborate_All`` pragmas to order units. | |
1157 | |
1475 When this switch is in effect, GNAT will emit the following supplementary | 1158 When this switch is in effect, GNAT will emit the following supplementary |
1476 information depending on the elaboration model in effect. | 1159 information depending on the elaboration model in effect. |
1477 | 1160 |
1478 - *Dynamic model* | 1161 - *Dynamic model* |
1479 | 1162 |
1480 GNAT will indicate missing ``Elaborate`` and ``Elaborate_All`` pragmas for | 1163 GNAT will indicate missing ``Elaborate`` and ``Elaborate_All`` pragmas for |
1481 all library-level scenarios within the partition. | 1164 all library-level scenarios within the partition. |
1482 | 1165 |
1483 - *Static model* | 1166 - *Static model* |
1484 | 1167 |
1485 GNAT will indicate all scenarios executed during elaboration. In addition, | 1168 GNAT will indicate all scenarios invoked during elaboration. In addition, |
1486 it will provide detailed traceback when an implicit ``Elaborate`` or | 1169 it will provide detailed traceback when an implicit ``Elaborate`` or |
1487 ``Elaborate_All`` pragma is generated. | 1170 ``Elaborate_All`` pragma is generated. |
1488 | 1171 |
1489 - *SPARK model* | 1172 - *SPARK model* |
1490 | 1173 |
1613 model to output trace information of elaboration issues. The trace | 1296 model to output trace information of elaboration issues. The trace |
1614 information could shed light on previously unforeseen dependencies, as well | 1297 information could shed light on previously unforeseen dependencies, as well |
1615 as their origins. Elaboration warnings are enabled with compiler switch | 1298 as their origins. Elaboration warnings are enabled with compiler switch |
1616 :switch:`-gnatwl`. | 1299 :switch:`-gnatwl`. |
1617 | 1300 |
1618 * Use switch :switch:`-gnatel` to obtain messages on generated implicit | 1301 * Cosider the tactics given in the suggestions section of the circularity |
1619 ``Elaborate`` and ``Elaborate_All`` pragmas. The trace information could | 1302 diagnostic. |
1620 indicate why a server unit must be elaborated prior to a client unit. | |
1621 | |
1622 * If the warnings produced by the static model indicate that a task is | |
1623 involved, consider the options in section `Resolving Task Issues`_. | |
1624 | 1303 |
1625 * If none of the steps outlined above resolve the circularity, use a more | 1304 * If none of the steps outlined above resolve the circularity, use a more |
1626 permissive elaboration model, in the following order: | 1305 permissive elaboration model, in the following order: |
1627 | 1306 |
1628 - Use the dynamic elaboration model, with compiler switch :switch:`-gnatE`. | 1307 - Use the pre-20.x legacy elaboration-order model, with binder switch |
1629 | 1308 :switch:`-H`. |
1630 - Use the legacy static elaboration model, with compiler switch | 1309 |
1631 :switch:`-gnatH`. | 1310 - Use both pre-18.x and pre-20.x legacy elaboration models, with compiler |
1632 | 1311 switch :switch:`-gnatH` and binder switch :switch:`-H`. |
1633 - Use the legacy dynamic elaboration model, with compiler switches | 1312 |
1634 :switch:`-gnatH` :switch:`-gnatE`. | 1313 - Use the relaxed static elaboration model, with compiler switches |
1635 | 1314 :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`. |
1636 - Use the relaxed legacy static elaboration model, with compiler switches | 1315 |
1637 :switch:`-gnatH` :switch:`-gnatJ`. | 1316 - Use the relaxed dynamic elaboration model, with compiler switches |
1638 | 1317 :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch |
1639 - Use the relaxed legacy dynamic elaboration model, with compiler switches | 1318 :switch:`-H`. |
1640 :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE`. | |
1641 | 1319 |
1642 .. _Inspecting_the_Chosen_Elaboration_Order: | 1320 .. _Inspecting_the_Chosen_Elaboration_Order: |
1643 | 1321 |
1644 Inspecting the Chosen Elaboration Order | 1322 Inspecting the Chosen Elaboration Order |
1645 ======================================= | 1323 ======================================= |
1648 `b~xxx.adb`. On certain targets, this file appears as `b_xxx.adb`. The | 1326 `b~xxx.adb`. On certain targets, this file appears as `b_xxx.adb`. The |
1649 elaboration order appears as a sequence of calls to ``Elab_Body`` and | 1327 elaboration order appears as a sequence of calls to ``Elab_Body`` and |
1650 ``Elab_Spec``, interspersed with assignments to `Exxx` which indicates that a | 1328 ``Elab_Spec``, interspersed with assignments to `Exxx` which indicates that a |
1651 particular unit is elaborated. For example: | 1329 particular unit is elaborated. For example: |
1652 | 1330 |
1653 :: | 1331 :: |
1654 | 1332 |
1655 System.Soft_Links'Elab_Body; | 1333 System.Soft_Links'Elab_Body; |
1656 E14 := True; | 1334 E14 := True; |
1657 System.Secondary_Stack'Elab_Body; | 1335 System.Secondary_Stack'Elab_Body; |
1658 E18 := True; | 1336 E18 := True; |
1659 System.Exception_Table'Elab_Body; | 1337 System.Exception_Table'Elab_Body; |
1660 E24 := True; | 1338 E24 := True; |
1661 Ada.Io_Exceptions'Elab_Spec; | 1339 Ada.Io_Exceptions'Elab_Spec; |
1662 E67 := True; | 1340 E67 := True; |
1663 Ada.Tags'Elab_Spec; | 1341 Ada.Tags'Elab_Spec; |
1664 Ada.Streams'Elab_Spec; | 1342 Ada.Streams'Elab_Spec; |
1665 E43 := True; | 1343 E43 := True; |
1666 Interfaces.C'Elab_Spec; | 1344 Interfaces.C'Elab_Spec; |
1667 E69 := True; | 1345 E69 := True; |
1668 System.Finalization_Root'Elab_Spec; | 1346 System.Finalization_Root'Elab_Spec; |
1669 E60 := True; | 1347 E60 := True; |
1670 System.Os_Lib'Elab_Body; | 1348 System.Os_Lib'Elab_Body; |
1671 E71 := True; | 1349 E71 := True; |
1672 System.Finalization_Implementation'Elab_Spec; | 1350 System.Finalization_Implementation'Elab_Spec; |
1673 System.Finalization_Implementation'Elab_Body; | 1351 System.Finalization_Implementation'Elab_Body; |
1674 E62 := True; | 1352 E62 := True; |
1675 Ada.Finalization'Elab_Spec; | 1353 Ada.Finalization'Elab_Spec; |
1676 E58 := True; | 1354 E58 := True; |
1677 Ada.Finalization.List_Controller'Elab_Spec; | 1355 Ada.Finalization.List_Controller'Elab_Spec; |
1678 E76 := True; | 1356 E76 := True; |
1679 System.File_Control_Block'Elab_Spec; | 1357 System.File_Control_Block'Elab_Spec; |
1680 E74 := True; | 1358 E74 := True; |
1681 System.File_Io'Elab_Body; | 1359 System.File_Io'Elab_Body; |
1682 E56 := True; | 1360 E56 := True; |
1683 Ada.Tags'Elab_Body; | 1361 Ada.Tags'Elab_Body; |
1684 E45 := True; | 1362 E45 := True; |
1685 Ada.Text_Io'Elab_Spec; | 1363 Ada.Text_Io'Elab_Spec; |
1686 Ada.Text_Io'Elab_Body; | 1364 Ada.Text_Io'Elab_Body; |
1687 E07 := True; | 1365 E07 := True; |
1688 | 1366 |
1689 Note also binder switch :switch:`-l`, which outputs the chosen elaboration | 1367 Note also binder switch :switch:`-l`, which outputs the chosen elaboration |
1690 order and provides a more readable form of the above: | 1368 order and provides a more readable form of the above: |
1691 | 1369 |
1692 :: | 1370 :: |
1693 | 1371 |
1694 ada (spec) | 1372 ada (spec) |
1695 interfaces (spec) | 1373 interfaces (spec) |
1696 system (spec) | 1374 system (spec) |
1697 system.case_util (spec) | 1375 system.case_util (spec) |
1698 system.case_util (body) | 1376 system.case_util (body) |
1699 system.concat_2 (spec) | 1377 system.concat_2 (spec) |
1700 system.concat_2 (body) | 1378 system.concat_2 (body) |
1701 system.concat_3 (spec) | 1379 system.concat_3 (spec) |
1702 system.concat_3 (body) | 1380 system.concat_3 (body) |
1703 system.htable (spec) | 1381 system.htable (spec) |
1704 system.parameters (spec) | 1382 system.parameters (spec) |
1705 system.parameters (body) | 1383 system.parameters (body) |
1706 system.crtl (spec) | 1384 system.crtl (spec) |
1707 interfaces.c_streams (spec) | 1385 interfaces.c_streams (spec) |
1708 interfaces.c_streams (body) | 1386 interfaces.c_streams (body) |
1709 system.restrictions (spec) | 1387 system.restrictions (spec) |
1710 system.restrictions (body) | 1388 system.restrictions (body) |
1711 system.standard_library (spec) | 1389 system.standard_library (spec) |
1712 system.exceptions (spec) | 1390 system.exceptions (spec) |
1713 system.exceptions (body) | 1391 system.exceptions (body) |
1714 system.storage_elements (spec) | 1392 system.storage_elements (spec) |
1715 system.storage_elements (body) | 1393 system.storage_elements (body) |
1716 system.secondary_stack (spec) | 1394 system.secondary_stack (spec) |
1717 system.stack_checking (spec) | 1395 system.stack_checking (spec) |
1718 system.stack_checking (body) | 1396 system.stack_checking (body) |
1719 system.string_hash (spec) | 1397 system.string_hash (spec) |
1720 system.string_hash (body) | 1398 system.string_hash (body) |
1721 system.htable (body) | 1399 system.htable (body) |
1722 system.strings (spec) | 1400 system.strings (spec) |
1723 system.strings (body) | 1401 system.strings (body) |
1724 system.traceback (spec) | 1402 system.traceback (spec) |
1725 system.traceback (body) | 1403 system.traceback (body) |
1726 system.traceback_entries (spec) | 1404 system.traceback_entries (spec) |
1727 system.traceback_entries (body) | 1405 system.traceback_entries (body) |
1728 ada.exceptions (spec) | 1406 ada.exceptions (spec) |
1729 ada.exceptions.last_chance_handler (spec) | 1407 ada.exceptions.last_chance_handler (spec) |
1730 system.soft_links (spec) | 1408 system.soft_links (spec) |
1731 system.soft_links (body) | 1409 system.soft_links (body) |
1732 ada.exceptions.last_chance_handler (body) | 1410 ada.exceptions.last_chance_handler (body) |
1733 system.secondary_stack (body) | 1411 system.secondary_stack (body) |
1734 system.exception_table (spec) | 1412 system.exception_table (spec) |
1735 system.exception_table (body) | 1413 system.exception_table (body) |
1736 ada.io_exceptions (spec) | 1414 ada.io_exceptions (spec) |
1737 ada.tags (spec) | 1415 ada.tags (spec) |
1738 ada.streams (spec) | 1416 ada.streams (spec) |
1739 interfaces.c (spec) | 1417 interfaces.c (spec) |
1740 interfaces.c (body) | 1418 interfaces.c (body) |
1741 system.finalization_root (spec) | 1419 system.finalization_root (spec) |
1742 system.finalization_root (body) | 1420 system.finalization_root (body) |
1743 system.memory (spec) | 1421 system.memory (spec) |
1744 system.memory (body) | 1422 system.memory (body) |
1745 system.standard_library (body) | 1423 system.standard_library (body) |
1746 system.os_lib (spec) | 1424 system.os_lib (spec) |
1747 system.os_lib (body) | 1425 system.os_lib (body) |
1748 system.unsigned_types (spec) | 1426 system.unsigned_types (spec) |
1749 system.stream_attributes (spec) | 1427 system.stream_attributes (spec) |
1750 system.stream_attributes (body) | 1428 system.stream_attributes (body) |
1751 system.finalization_implementation (spec) | 1429 system.finalization_implementation (spec) |
1752 system.finalization_implementation (body) | 1430 system.finalization_implementation (body) |
1753 ada.finalization (spec) | 1431 ada.finalization (spec) |
1754 ada.finalization (body) | 1432 ada.finalization (body) |
1755 ada.finalization.list_controller (spec) | 1433 ada.finalization.list_controller (spec) |
1756 ada.finalization.list_controller (body) | 1434 ada.finalization.list_controller (body) |
1757 system.file_control_block (spec) | 1435 system.file_control_block (spec) |
1758 system.file_io (spec) | 1436 system.file_io (spec) |
1759 system.file_io (body) | 1437 system.file_io (body) |
1760 system.val_uns (spec) | 1438 system.val_uns (spec) |
1761 system.val_util (spec) | 1439 system.val_util (spec) |
1762 system.val_util (body) | 1440 system.val_util (body) |
1763 system.val_uns (body) | 1441 system.val_uns (body) |
1764 system.wch_con (spec) | 1442 system.wch_con (spec) |
1765 system.wch_con (body) | 1443 system.wch_con (body) |
1766 system.wch_cnv (spec) | 1444 system.wch_cnv (spec) |
1767 system.wch_jis (spec) | 1445 system.wch_jis (spec) |
1768 system.wch_jis (body) | 1446 system.wch_jis (body) |
1769 system.wch_cnv (body) | 1447 system.wch_cnv (body) |
1770 system.wch_stw (spec) | 1448 system.wch_stw (spec) |
1771 system.wch_stw (body) | 1449 system.wch_stw (body) |
1772 ada.tags (body) | 1450 ada.tags (body) |
1773 ada.exceptions (body) | 1451 ada.exceptions (body) |
1774 ada.text_io (spec) | 1452 ada.text_io (spec) |
1775 ada.text_io (body) | 1453 ada.text_io (body) |
1776 text_io (spec) | 1454 text_io (spec) |
1777 gdbstr (body) | 1455 gdbstr (body) |