In rare cases, the static elaboration model fails to prevent dispatching calls to not-yet-elaborated subprograms. In such cases, we fall back to run-time checks; premature calls to any primitive operation of a tagged type before the body of the operation has been elaborated will raise Program_Error.
Access-to-subprogram types, however, are handled conservatively in many cases. This was not true in earlier versions of the compiler; you can use the `-gnatd.U' debug switch to revert to the old behavior if the new conservative behavior causes elaboration cycles. Here, ’conservative’ means that if you do P’Access during elaboration, the compiler will normally assume that you might call P indirectly during elaboration, so it adds an implicit pragma Elaborate_All on the library unit containing P. The `-gnatd.U' switch is safe if you know there are no such calls. If the program worked before, it will continue to work with `-gnatd.U'. But beware that code modifications such as adding an indirect call can cause erroneous behavior in the presence of `-gnatd.U'.
These implicit Elaborate_All pragmas are not added in all cases, because they cause elaboration cycles in certain common code patterns. If you want even more conservative handling of P’Access, you can use the `-gnatd.o' switch.
See debug.adb for documentation on the `-gnatd...' debug switches.