Version 1.7 of ai12s/ai12-0154-1.txt

Unformatted version of ai12s/ai12-0154-1.txt version 1.7
Other versions for file ai12s/ai12-0154-1.txt

!standard 13.1.1(32/3)          15-03-03 AI12-0154-1/03
!class binding interpretation 15-02-20
!status Corrigendum 1-2012 15-02-26
!status WG9 Approved 15-06-26
!status ARG Approved 10-0-0 15-02-26
!status work item 15-02-20
!status received 15-02-18
!priority Low
!difficulty Easy
!qualifier Omission
!subject Aspects of library units
!summary
The expression of an aspect associated with library unit pragma is resolved and evaluated immediately.
!question
(1) The first sentence 13.14(3/4) determines when the contents of a library package are frozen. But there does not seem to be any definition of when the library package itself is frozen. Taken literally, that would imply that it is frozen at the end of package Standard (as all library units are nested within it, and its end would trigger 13.14(3/4)). But is there in fact an end to Standard, given that a subsequent compilation can add additional units at any time?
This matters because 13.1.1(37/3) and 13.14(7.2/3) say that expressions in an aspect specification are evaluated no sooner than the first freezing point (and are resolved based on the end of the enclosing declaration list [13.1.1(11/3)]). We obviously need to know how aspects of library packages are resolved and evaluated.
When is a library package frozen?
(2) Most library package aspects correspond to library unit pragmas. Library unit pragmas take effect immediately. If the aspect is evaluated at the end of the package or even later, then the aspect is quite different than the associated pragma.
For instance:
package P with Pure => Purity is -- Var : Integer; Purity : constant Boolean := True; end P;
If this is legal, then compilers need to make a retroactive check for Purity on declarations. This is a new capability not contemplated when these pragmas were given aspect forms, and it does not seem particularly useful.
When does aspect Pure and similar aspects take effect? (Immediately.)
!recommendation
(See Summary.)
!wording
Modify 13.1.1(32/3):
Any aspect specified by a representation pragma or library unit pragma that has a local_name as its single argument may be specified by an aspect_specification, with the entity being the local_name. The aspect_definition is expected to be of type Boolean. The expression shall be static.{ Notwithstanding what this International Standard says elsewhere, the expression of an aspect that can be specified by a library unit pragma is resolved and evaluated at the point where it occurs in the aspect_specification Redundant[, rather than the first freezing point of the associated package].}
[Editor's note: I wouldn't have had to use "notwithstanding" wording here, as 13.1.1(36/3) allows us to ignore everything said in 13.1.1 if we want. But it seems the best way to put that this is defining alternative semantics for aspects associated with library unit pragmas. There is also the question of whether depending upon 13.1.1(36/3) would be circular, given this wording also appears in 13.1.1.]
!discussion
There are a number of answers to question (1), and which ones make the most sense depends upon the usage of any aspects or representation pragmas that apply to a package. It's easy to imagine package aspects that need visibility into the package. For instance:
package P with Finalize => Cleanup is ... procedure Cleanup; end P;
or
package P with Package_Invariant => All_Is_Copacetic is ... function All_Is_Copacetic return Boolean; end P;
We also likely want to allow the use of trailing pragmas to specify values.
Thus, we probably want to freeze the package no sooner than the end of the enclosing compilation.
However (question (2)), it's clear that we want language-defined aspects that are associated with library unit pragmas to be resolved and frozen immediately. There is no benefit to allowing examples where retroactive checking of categorization restrictions is required; it seems that such examples would only appear in ACATS-style tests. Moreover, there was no intention of requiring additional work for implementers beyond that needed to directly support the aspect syntax. Having the effect of such aspects start immediately requires immediate evaluation of the expressions given for such aspects.
It turns out that the only language-defined aspects of a package are associated with library unit pragmas. Since we don't want to prevent implementation-defined aspects like the above, we do not want to freeze packages early. As such, we'll need a rule not related to freezing to handle package aspects. Once that is the case, we no longer need to answer the freezing question, so we don't. (Although we may need to do so in the future should we add any language-defined package aspects that need to be evaluated at the end of a library package, rather than the beginning.)
!corrigendum 13.1.1(32/3)
Replace the paragraph:
Any aspect specified by a representation pragma or library unit pragma that has a local_name as its single argument may be specified by an aspect_specification, with the entity being the local_name. The aspect_definition is expected to be of type Boolean. The expression shall be static.
by:
Any aspect specified by a representation pragma or library unit pragma that has a local_name as its single argument may be specified by an aspect_specification, with the entity being the local_name. The aspect_definition is expected to be of type Boolean. The expression shall be static. Notwithstanding what this International Standard says elsewhere, the expression of an aspect that can be specified by a library unit pragma is resolved and evaluated at the point where it occurs in the aspect_specification, rather than the first freezing point of the associated package.
!ASIS
No ASIS effect.
!ACATS test
Create an ACATS B-Test that library unit aspect evaluation happens immediately.
!appendix

From: Randy Brukardt
Sent: Wednesday, February 18, 2015  3:46 PM

The first sentence 13.14(3/4) determines when the contents of a library package
are frozen. But I don't see anything anywhere that says when the library package
itself is frozen. Taken literally, that would imply that it is frozen at the end
of Standard, but do you ever reach the end of Standard (given that you can add
[compile] additional units at any time])?

I care because 13.1.1(37/3) and 13.14(7.2/3) say that expressions in an aspect
specification are evaluated no sooner than the first freezing point (and are
resolved based on the end of the enclosing declaration list [13.1.1(11/3)],
something that never happens for a library unit).

Thus, I wonder when the aspect for a categorization pragma is resolved and
evaluated. In particular, is the following legal?

    package P with Pure => Purity is
        -- Var : Integer;
        Purity : constant Boolean := True;
    end P;

The above seems to violate the Dewar rule, given that we weren't trying to add
any capabilities with these aspect and pragma Pure takes effect immediately.
Note that if this is legal there would need to be some sort of retroactive check
for purity of the preceding declarations (imagine that Var was uncommented).
That seems like a lot of work for virtually no benefit.

(There is a similar question about where pragma Convention is allowed for P, but
as that's not required of any implementation, it's the sort of question not
worth asking.)

Did we intend P to be frozen immediately upon declaration? Or did we intend a
special rule (that doesn't exist) for the categorization aspects? Or did we
really intend the above example to work?

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

From: Edmond Schonberg
Sent: Wednesday, February 18, 2015  4:00 PM

That example must be illegal. The aspect should be equivalent to a pragma
appearing after the declaration of the package, but then environment-level
visibility rules prevent the pragma from mentioning anything declared within the
package.

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

From: Tucker Taft
Sent: Wednesday, February 18, 2015  4:04 PM

> The first sentence 13.14(3/4) determines when the contents of a
> library package are frozen. But I don't see anything anywhere that
> says when the library package itself is frozen. Taken literally, that
> would imply that it is frozen at the end of Standard, but do you ever
> reach the end of Standard (given that you can add [compile] additional units
> at any time])?

Interesting point.  I would say that the end of a compilation unit freezes any
contained library unit declaration.  I say compilation unit instead of library
unit so that it includes any trailing pragmas.

> I care because 13.1.1(37/3) and 13.14(7.2/3) say that expressions in an
> aspect specification are evaluated no sooner than the first freezing point
> (and are resolved based on the end of the enclosing declaration list
> [13.1.1(11/3)], something that never happens for a library unit).
>
> Thus, I wonder when the aspect for a categorization pragma is resolved and
> evaluated. In particular, is the following legal?
>
>      package P with Pure => Purity is
>          -- Var : Integer;
>          Purity : constant Boolean := True;
>      end P;

We need to specify what is visible in such an aspect clause, and whether it is
inside or outside the declarative region associated with P.  The above is
admittedly weird, but less weird would be specifying, say, a procedure of a
package that is supposed to be called when the package is about to be finalized.
E.g.

    package P with Finalize => Cleanup is
       ...
       procedure Cleanup;
    end P;

or a boolean expression that represents a package invariant:

    package P with Package_Invariant => All_Is_Copacetic is
       ...
       function All_Is_Copacetic return Boolean;
    end P;


> ... Did we intend P to be frozen immediately upon declaration? Or did we
> intend a special rule (that doesn't exist) for the categorization aspects? Or
> did we really intend the above example to work?

I would say that the name resolution should be deferred for these as well, so
that you can specify things like package invariants.  In general, one would hope
that library packages and nested packages have nearly the same functionality
w.r.t. aspects.

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

From: Tucker Taft
Sent: Wednesday, February 18, 2015  4:05 PM

> That example must be illegal. The aspect should be equivalent to a
> pragma  appearing after the declaration of the package, but then
> environment-level visibility rules prevent the pragma from mentioning anything
> declared within the package.

Not sure I agree.  Presumably aspects on library subprograms at least "see" the
parameters, so perhaps package aspects should "see" their visible components.

I already sent a longer response.

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

From: Edmond Schonberg
Sent: Wednesday, February 18, 2015  4:21 PM

In general aspects can be specified equivalently with aspect specifications and
with pragmas. I imagine we want to preserve that equivalence as much as
possible. so for aspect specifications that apply to compilation units we need a
rule that says whether the equivalent pragma appears at the end of the
specification, or as a compilation unit pragma.  Visibility rules for pre- and
post-conditions are already special, I'm not sure I see the equivalence between
formals of subprograms and local entities in a package.

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

From: Tucker Taft
Sent: Wednesday, February 18, 2015  4:42 PM

> In general aspects can be specified equivalently with aspect
> specifications and with pragmas. I imagine we want to preserve that
> equivalence as much as possible. so for aspect specifications that
> apply to compilation units we need a rule that says whether the
> equivalent pragma appears at the end of the specification, or as a compilation
> unit pragma.

Well for the pragmas that became aspects in Ada 2012, the pragmas had generally
been pragmas that occurred at the beginning of the specification, such as pragma
Pure, which are usually "library unit pragmas" or "program unit pragmas."

> ... Visibility
> rules for pre- and post-conditions are already special, I'm not sure I
> see the equivalence between formals of subprograms and local entities
> in a package.

Well, I saw them as related because both are declared "inside" the declarative
region of the entity associated with the aspect.

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

From: Randy Brukardt
Sent: Wednesday, February 18, 2015  4:50 PM

>In general aspects can be specified equivalently with aspect specifications
>and with pragmas. I imagine we want to preserve that equivalence as much as
>possible. so for aspect specifications that apply to compilation units we need
>a rule that says whether the equivalent pragma appears at the end of the
>specification, or as a compilation unit pragma.  Visibility rules for
>pre- and post-conditions are already special, I'm not sure I see the
>equivalence between formals of subprograms and local entities in a package.

I find Ed's logic backwards, but I agree with his conclusion. In particular, I'd
expect that aspects that correspond to library unit pragmas (which have to
appear first inside of a library package), have to be resolved and evaluated
immediately. It doesn't make sense to delay their effect in any way, as that
would require retroactive action compared to the pragmas, and we surely didn't
intend to make that much work for implementers (given that it isn't useful in
any way that I can think of).

OTOH, other aspects might want different rules. Perhaps saying that it happens
at the end would make sense for them.

Thus, it seems to me that we need a rule that overrides whatever the rules are
for other aspects for library unit pragmas. (We already have part of that
(13.1.1(32/3)) for such pragmas. I'd simply add another rule that library unit
pragmas "nothwithstanding other rules" are resolved and evaluated immediately.
Presuming that's what we want. (Ed and I are in agreement on this point, not
sure about the rest.)

Note that there still is the possibility of using an object from outside of the
package:

package Consts is
    Purity : constant Boolean := True;
end Consts;

with Consts;
package P with Pure => Consts.Purity is
    ...
end P;

I believe that P is legal here and we intended that to be the case. (That does
mean that the aspects have slightly more capability than the pragmas, but I
don't think that capability is particularly useful. Perhaps in conjuction with
debugging, turning off purity in a bunch of units at once would be helpful?
Dunno.)

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


Questions? Ask the ACAA Technical Agent