Version 1.3 of ais/ai-00403.txt

Unformatted version of ais/ai-00403.txt version 1.3
Other versions for file ais/ai-00403.txt

!standard 10.2.1(11)          05-05-05 AI95-00403/03
!class binding interpretation 05-01-27
!status Amendment 200Y 05-03-17
!status ARG Approved 11-0-0 05-04-17
!status work item 05-01-27
!status received 05-01-27
!qualifier omission
!subject Preelaboration checks and formal objects
!summary
For the purposes of determining whether a unit can be declared to be preelaborable, a generic formal object is nonstatic.
!question
In this example: (Pak2 is a library unit)
generic x1: integer; package Pak2 is pragma Preelaborate; pragma Elaborate_Body; end Pak2;
package body Pak2 is x2: integer := x1; end Pak2;
Is this legal? (No.) It seems that the intent is that 10.2.1(10) makes this illegal, because it's possible to instantiate Pak2 with an actual for "x1" that would cause the declaration of x2 to perform an action that 10.2.1(6-7) makes nonpreelaborable. For instance, wou could instantiate Pak2 with an actual that contains a function call or the name of an object.
!recommendation
(See wording.)
!wording
Replace 10.2.1(10) by:
A generic body is preelaborable only if elaboration of a corresponding instance body would not perform any such actions, presuming that:
o the actual for each formal private type (or extension) declared within the formal part of the generic unit is a private type (or extension) that does not have preelaborable initialization;
o the actual for each formal type is nonstatic;
o the actual for each formal object is nonstatic; and
o the actual for each formal subprogram is a user-defined subprogram.
AARM Note: This is an "assume-the-worst" rule. The elaboration of a generic unit doesn't perform any of the actions listed above, because its sole effect is to establish that the generic can from now on be instantiated. So the elaboration of the generic itself is not the interesting part when it comes to preelaboration rules. The interesting part is what happens when you elaborate "any instantiation" of the generic. For instance, declaring an object of a limited formal private type might well start tasks, call functions, and do all sorts of non-preelaborable things. We prevent these situations by assuming that the actual parameters are as badly behaved as possible.
!discussion
10.2.1(10) is intended to be an "assume-the-worst" rule. However, it explicitly requires assuming properties that have that effect for types and subprograms; objects aren't mentioned. Objects should be assumed to be non-static, because then 10.2.1(8) must apply. We must also specify that the private type used when assuming the worst doesn't have preelaborable initialization.
!corrigendum 10.2.1(10)
Replace the paragraph:
A generic body is preelaborable only if elaboration of a corresponding instance body would not perform any such actions, presuming that the actual for each formal private type (or extension) is a private type (or extension), and the actual for each formal subprogram is a user-defined subprogram.
by:
A generic body is preelaborable only if elaboration of a corresponding instance body would not perform any such actions, presuming that:
!ACATS Test
Construct an ACATS B-Test to insure that generics of this form are not allowed to be preelaborable.
!appendix

!topic Preelaborable generics
!reference RM95 10.2.1
!from Adam Beneschan 04-12-01
!discussion

We've had a couple of questions regarding the use of Preelaborate on a
library generic unit.  Trying to find the answers to these questions
seems to have led to confusion about what the RM means, so it was
suggested that I ask Ada-Comment for clarification and perhaps suggest
that the next version of the RM or AARM needs a note to clarify the
meaning.  I previously posted the first question on comp.lang.ada, and
only got one response from someone who also wasn't sure what the RM
said about this.

Question 1:

In this example:  (Pak2 is a library unit)

    generic
       x1: integer;
    package Pak2 is
       pragma Preelaborate;
       pragma Elaborate_Body;
    end Pak2;

    package body Pak2 is
       x2: integer := x1;
    end Pak2;

My reading is that 10.2.1(10) makes this illegal, because it's
possible to instantiate Pak2 with an actual for "x1" that would cause
the declaration of x2 to perform an action that 10.2.1(6-7) makes
nonpreelaborable.  (You could instantiate Pak2 with an actual that
contains a function call or the name of an object, e.g.)

Is my reading correct?


Question 2:

In this case, the object declaration is moved to the spec, so that
10.2.1(10) doesn't apply.

    generic
       x1: integer;
    package Pak2 is
       pragma Preelaborate;
       x2: integer := x1;
    end Pak2;

Pak2 is a library unit.  The Preelaborate on Pak2 makes it legal for
other preelaborable units to "with" Pak2; but (Question 2A) does this
Preelaborate have any effect on the legality of an instance of Pak2?
Specifically, suppose Pak2 (1) is instantiated as a library-level
instantiation New_Pak2, where there is *no* Preelaborate(New_Pak2)
pragma; or (2) is instantiated inside another library unit that is not
preelaborable.  Question 2B: Is it legal to instantiate Pak2 with an
actual for "x1" that contains a non-static function call or the name
of an object?  I think the answer to Question 2B is "yes" [in both
cases], and the answer to Question 2A is "no"; but different people
have come to different conclusions, so it would appear that the RM or
AARM ought to be clearer about this.

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

From: Randy Brukardt
Sent: Wednesday, December 1, 2004  6:16 PM

I don't (off-hand) know the answer to Question 1, but Question 2 is exactly
the question of AI-41, which was included in the corrigendum. Thus the
answers are 2A) No, and 2B) Yes.

Note that AI-41 changes wording in 10.1.5, and thus is discussed there;
there isn't any mention of it in 10.2.1 because it applies to all program
unit pragmas. (There's nothing special about Preelaborate this way.)

I would expect that anyone that's confused hasn't read AI-41 or the
Corrigendum, but perhaps I've missed something.

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

From: Adam Beneschan
Sent: Wednesday, December 1, 2004  6:36 PM

Yes, thanks; I wasn't aware of AI-41.  I looked for the AI cross
reference under section 10.2.1 and didn't find anything there, but I
missed this one.  I probably should have thought to look at 10.1.5.
My fault.

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

From: Gary Dismukes
Sent: Wednesday, December 1, 2004  7:08 PM

> My reading is that 10.2.1(10) makes this illegal, because it's
> possible to instantiate Pak2 with an actual for "x1" that would cause
> the declaration of x2 to perform an action that 10.2.1(6-7) makes
> nonpreelaborable.  (You could instantiate Pak2 with an actual that
> contains a function call or the name of an object, e.g.)
>
> Is my reading correct?

That's the way I read it as well, that is, that it's intended to be an
assume-the-worst rule.

It does seem though that for completeness the wording of the rule should also
say something about presuming that the actual for a formal 'in' object is a
nonstatic object or some such, rather than just specifying the form of the
actual for formal types and formal subprograms.

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

From: Tucker Taft
Sent: Wednesday, December 1, 2004  9:37 PM

I agree with Gary.

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


Questions? Ask the ACAA Technical Agent