Version 1.2 of ai05s/ai05-0124-1.txt

Unformatted version of ai05s/ai05-0124-1.txt version 1.2
Other versions for file ai05s/ai05-0124-1.txt

!standard 11.5(7.1/2)          10-04-02 AI05-0124-1/02
!standard 11.5(20)
!class ramification 10-02-28
!status ARG Approved 10-0-0 10-02-28
!status work item 08-10-18
!status received 08-09-23
!priority Low
!difficulty Easy
!qualifier Omission
!subject Where is the elaboration check suppressed?
!summary
It not specified where an elaboration check is suppressed.
!question
Does Pragma Suppress(Elaboration_Check) apply to a call, or to the called entity? Specifically:
package Pack1 is pragma Unsuppress(Elaboration_Check); procedure Proc1; end Pack1;
package body Pack1 is procedure Proc1 is begin -- whatever end Proc1; end Pack1;
package Pack2 is pragma Elaborate_Body; end Pack2;
with Pack1; package body Pack2 is begin pragma Suppress(Elaboration_Check); Pack1.Proc1; end Pack2;
Assuming that Pack2's body is elaborated before Pack1's body (the language doesn't specify which is elaborated first), then without the Suppress, Program_Error would be raised when Pack2's body is elaborated. But with the Suppress pragma in effect, does it apply to the call? Or should Program_Error be raised because there's no Suppress(Elaboration_Check) that applies to Proc1's declaration or body? The Standard isn't quite clear on this; 11.5(7.1/2) says that checking pragmas apply to entities, and a call isn't an entity; but the wording of 11.5(20) makes it seem that the pragma might apply to the call.
!response
The model of checking pragmas applying specifically to entities was made obsolescent in Ada 2005. Other than the obsolescent forms, such pragmas apply to everything in a region of text.
In this case, the use of "entity" is unfortunate, because that is a technical term that doesn't include expressions like calls. That could be taken to mean that the user's clear intent to suppress the check on the call should be ignored. That doesn't make a lot of sense.
In any case, the Standard never describes which entity is involved in a particular check. That was the primary reason that the specific checking pragmas were made obsolescent: it's not possible to use them in any portable way. It makes no more sense in this case to specify that the check is suppressed on the subprogram and not on the call. Depending on the implementation model of elaboration checking (which can be done at either the call site or inside of the called subprogram), which place a compiler would naturally check the suppression state can vary a lot between implementations.
We could of course confirm the letter of the wording. This would have the effect of requiring implementations that do elaboration checking at the call site to do a version of entity-level suppression (even though the intent of Ada 2005 was that that would not need to be supported). And doing so would make suppression of all kinds of entities much less predictable. Do we really want the suppress in the following to be always ignored?
Data : array (1..20) of ...;
function Get_It (Index : Positive) return ... pragma Suppress (Index_Check); begin return Data (Index); end Get_It;
In this case, the scope of the suppress pragma does not include any entities in the technical sense ("items that are declared"). Following the strict reading suggested by the question would mean that pragma would not suppress anything.
Another alternative would be to change the wording in 11.5(7.1/2) to use "construct" rather than "entity". But that also isn't quite right (since "construct" means anything syntactical -- but we really want Suppress to apply to implicit things as well). It seems insufficiently broken to change the wording.
--!corrigendum 11.5(7.1/2)
!ACATS Test
There is nothing that can be tested about "unspecified".
!appendix

!topic Where is elaboration check suppressed?
!reference RM 11.5(7.1,20)
!from Adam Beneschan 08-09-23
!discussion

Does Pragma Suppress(Elaboration_Check) apply to a call, or to a callee?
Specifically:

   package Pack1 is
      pragma Unsuppress(Elaboration_Check);
      procedure Proc1;
   end Pack1;
   
   package body Pack1 is
      procedure Proc1 is
      begin
         -- whatever
      end Proc1;
   end Pack1;

   package Pack2 is
      pragma Elaborate_Body;
   end Pack2;
   
   with Pack1;
   package body Pack2 is
   begin
      pragma Suppress(Elaboration_Check);
      Pack1.Proc1;
   end Pack2;

Assuming that Pack2's body is elaborated before Pack1's body (the language
doesn't specify which is elaborated first), then without the Suppress,
Program_Error would be raised when Pack2's body is elaborated.  But with
the Suppress pragma in effect, does it apply to the call?  Or should
Program_Error be raised because there's no Suppress(Elaboration_Check)
that applies to Proc1's declaration or body?  The RM isn't quite clear
on this; 11.5(7.1) says that checking pragmas apply to entities, and a
call isn't an entity; but the wording of 11.5(20) makes it seem that the
pragma might apply to the call.

I realize that this may be a "don't care" item, and that's fine with me,
since there's no requirement that Suppress has to be obeyed, and this
may not be the sort of coding practice we wish to encourage anyway.  But
if it is important that the answer to my question be one way or the other,
which is it?

****************************************************************

From: Randy Brukardt
Sent: Thursday, September 25, 2008  2:36 PM

I think this is purposely unspecified. There are at least two models for
the implementation of the elaboration check: make the check at the call
site, or make the check at the start of the called subprogram. (Janus/Ada
usually does the latter, if I remember correctly.) I don't think the RM
intends to force implementers to use one or the other.

The obvious implementation of Suppress will omit the check if-and-only-if
the pragma is in effect at the point where the compiler is going to
generate the actual check. A more complex implementation would be needed
to implement some other rule, and it is far from clear that such an
implementation would offer much benefit.

One could argue that the existing wording says that the pragma only applies
to the subprogram (which is an entity), and not to the call (which is not).
That would mean that suppressing the check in your example would be wrong.
But I don't think that there is much point to such an interpretation
(it simply would mean that some programs would generate more code and the
possibility of checks even in the presence of a Suppress pragma). And
in any case, the implementation can always make the check anyway (even
with Suppress in effect), so it's not clear that additional determinism
buys much.

****************************************************************

Questions? Ask the ACAA Technical Agent