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)