C.6. Default Behavior in XGC Ada - Ensuring Safety

The default behavior in XGC Ada ensures elaboration safety. What XGC Ada does in its default mode is to automatically and implicitly implement the rule we previously suggested as the right approach. Let's restate the rule:

If a unit has elaboration code that can directly or indirectly make a call to a subprogram in a with'ed unit, or instantiate a generic unit in a with'ed unit, then if the with'ed unit does not have pragma Pure, Preelaborate, or Elaborate_Body, then the client should have an Elaborate_All for the with'ed unit. By following this rule a client is assured that calls can be made without risk of an exception.

What XGC Ada does is to trace all calls that are potentially made from elaboration code, and put in any missing implicit Elaborate_All pragmas. The advantage of this approach is that no elaboration problems are possible if the binder can find an elaboration order that is consistent with these implicit Elaborate_All pragmas. The disadvantage of this approach is that no such order may exist.

If the binder does not generate any diagnostics, then it means that it has found an elaboration order that is guaranteed to be safe. However, the binder may still be relying on implicitly generated Elaborate_All pragmas so portability to other compilers than XGC Ada is not guaranteed.

If it is important to guarantee portability, then the compilations should use the -gnatwl (warn on elaboration problems) switch. This will cause warning messages to be generated indicating the missing Elaborate_All pragmas. Consider the following source program:


with k;
package j is
  m : integer := k.r;
end;

where it is clear that there really should be a pragma Elaborate_All for unit k. An implicit pragma will be generated, and it is likely that the binder will be able to honor this implicit pragma. However it is safer to include the pragma explicitly in the source. If this unit is compiled with the -gnatwl switch, then the compiler outputs a warning:


1. with k;
2. package j is
3. m : integer := k.r;
                     |
   >>> warning: call to "r" may raise Program_Error
   >>> warning: missing pragma Elaborate_All for "k"

4. end;

and these warnings can be used as a guide for supplying the missing pragmas.