Version 1.1 of ais/ai-00245.txt

Unformatted version of ais/ai-00245.txt version 1.1
Other versions for file ais/ai-00245.txt

!standard 10.1.4 (07)          00-10-30 AI95-00245/01
!class confirmation 00-10-30
!status work item 00-10-30
!status received 00-10-30
!qualifier Clarification
!priority Low
!difficulty Medium
!subject Consistency of inlined calls
!summary
The implementation must insure that a partition containing inlined subprograms is consistent. It can do this by requiring recompilation of units, or via a automatic recompilation mechanism.
!question
Consider a package P that contains explicitly inlined subprograms, and a main subprogram Q that is compiled after P's body and calls such subprograms. P's body is later changed and recompiled without any subsequent user actions causing Q to be recompiled or Q's code to be regenerated.
May program Q be rejected at link time, or must the linker automatically regenerate Q's code to be consistent with the new version of P's body? (The program may be rejected.)
Apparently, the obsolete version of P's body is not needed in the program because there is no semantic dependence on it, see 10.2(4). And the permission to remove Q from the environment when P's body is recompiled, see 10.1.4(7), is simply a permission. There are rules to prevent multiple versions of a compilation unit in a program, see 10.1.4(5), but they don't seem to help here because they are based on semantic dependence, and they are compile-time rules.
!response
The implementation permission to remove Q from the environment is intended to handle this case. It allows the implementation to require the recompilation of Q; alternatively, the implementation can automatically recompile Q at link-time.
10.2(27) ensures that an inconsistent partition cannot be linked. That means that an implementation that neither removed Q from the environment nor automatically recompiled it would be incorrect.
!ACATS test
An L-Test could be created to check that a program such as the one described is consistent.
!appendix

From: Dan Eilers
Sent: Thursday, October 19, 2000 8:27 PM

!topic consistency of inlined calls
!reference RM95-10.1.4(5-7)
!reference RM95-10.1.1(24-26)
!reference RM95-10.2(4)
!reference AARM95-10.1.4(7.d)
!reference AARM95-10.1.4(10.a)
!from Dan Eilers
!discussion

Consider a package P that contains explicitly inlined subprograms,
and a main subprogram Q that is compiled after P's body and calls such
subprograms.  P's body is later changed and recompiled without any
subsequent user actions causing Q to be recompiled or Q's code to be
regenerated.

May program Q be rejected at link time, or must the linker automatically
regenerate Q's code to be consistent with the new version of P's body?

Apparently, the obsolete version of P's body is not needed in the program
because there is no semantic dependence on it, see 10.2(4).  And the
permission to remove Q from the environment when P's body is recompiled,
see 10.1.4(7), is simply a permission.  There are rules to prevent multiple
versions of a compilation unit in a program, see 10.1.4(5), but they don't
seem to help here because they are based on semantic dependence, and they
are compile-time rules.

The concept of automatic linktime regeneration of code is mentioned
twice in the AARM, see 10.1.4(7.d) regarding inlined subprograms without
an explicit pragma inline, and 10.1.4(10.a) regarding macro-expanded
generics, but never even as implementation advise in the RM as far as
I can tell.

Note that the index for "dependence semantic" is missing 10.1.4(5) and
10.2(4), and the index for pragma inline is missing 10.1.4(7).

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

From: Tucker Taft
Sent: Thursday, October 19, 2000 10:33 PM

Program Q may be rejected at link time.  Subprogram Q need
not be implicitly recompiled, but rather it may be considered
to be out-of-date.  In contrast, instantiation bodies are
required to be implicitly recompiled in Ada 95.

> Apparently, the obsolete version of P's body is not needed in the program
> because there is no semantic dependence on it, see 10.2(4).  And the
> permission to remove Q from the environment when P's body is recompiled,
> see 10.1.4(7), is simply a permission.

This is the key permission.  This is intended to mean
that the implementation may force the user to take
an explicit action to get Q back into the
environment (i.e. explicitly recompile it).  In other
words, Q may be considered "out of date."

No such permission exists for generic instantiations if
the generic body is updated, so the instantiations must
remain in the environment, and the linker must not complain
that they have become out-of-date.  At least that was the intent.

> ... There are rules to prevent multiple
> versions of a compilation unit in a program, see 10.1.4(5), but they don't
> seem to help here because they are based on semantic dependence, and they
> are compile-time rules.
>
> The concept of automatic linktime regeneration of code is mentioned
> twice in the AARM, see 10.1.4(7.d) regarding inlined subprograms without
> an explicit pragma inline, and 10.1.4(10.a) regarding macro-expanded
> generics, but never even as implementation advise in the RM as far as
> I can tell.

Automatic linktime regeneration is required for implicit inlining
and macro-expanded generics, so no implementation advice is
necessary.  It is permitted, but not required for explicit inlining,
and the manual gives no advice either way for this case.

> Note that the index for "dependence semantic" is missing 10.1.4(5) and
> 10.2(4), and the index for pragma inline is missing 10.1.4(7).

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

From: Dan Eilers
Sent: Friday, October 20, 2000 1:24 AM

Tuck wrote:
> >                                                              And the
> > permission to remove Q from the environment when P's body is recompiled,
> > see 10.1.4(7), is simply a permission.
>
> This is the key permission.  This is intended to mean
> that the implementation may force the user to take
> an explicit action to get Q back into the
> environment (i.e. explicitly recompile it).  In other
> words, Q may be considered "out of date."

I understood the environment to be a compile-time concept (see 10.1.4(1)),
rather than a link-time concept.

10.1.4(5) requires a unit to exist in the environment in order to
compile a unit that depends on it, but 10.2(27) has no corresponding
requirement for linking.

I assume that "consistency" in 10.2(27) is intended to have the
same meaning as in 10.1.4(5), based on semantic dependency,
which doesn't cover "out of date" inlines.

Note: the index entry for "consistency among compilation units"
should add 10.2(27).

In an implementation where units are never removed from the environment
as long as their source file still exists, could a program be rejected
at link time for "out of date" inlines.

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

From: Tucker Taft
Sent: Friday, October 20, 2000 10:52 AM

Dan Eilers wrote:

> I understood the environment to be a compile-time concept (see 10.1.4(1)),
> rather than a link-time concept.

The environment is a compile-time, link-time, and run-time
concept (see 10.1.4(1), 10.2(13), and 10.2(25)).

> 10.1.4(5) requires a unit to exist in the environment in order to
> compile a unit that depends on it, but 10.2(27) has no corresponding
> requirement for linking.
>
> I assume that "consistency" in 10.2(27) is intended to have the
> same meaning as in 10.1.4(5), based on semantic dependency,
> which doesn't cover "out of date" inlines.

Out of date inlines is a concept that doesn't exist in
the manual.  Inlining is supposed to be semantically
neutral, except for certain subtleties having to do
with 11.6 "independence", so clearly an inlined call
must be based on the same body as any out-of-line call.

The "consistency" of 10.2(27) is intended to require that
no two versions of the same unit will exist in the partition.
The semantics of executing the partition are determined by
the source code for the units included in the partition;
whether or not the source is translated into some other form
(e.g. machine code) is irrelevant to this, as is it irrelevant
whether or not inline expansion is occurring (modulo 11.6).

> Note: the index entry for "consistency among compilation units"
> should add 10.2(27).

Good point.

> In an implementation where units are never removed from the environment
> as long as their source file still exists, could a program be rejected
> at link time for "out of date" inlines.

From a legalistic point of view, the manual actually doesn't
say anything about what are the full prerequisites to linking,
since the whole process of building a partition is
implementation defined.  I think the intent was that the
rules for compilation would apply to linking, in particular
that if something is still "in" the environment with respect
to compilation, it should be considered "in" the environment
with respect to linking.  However, now that I look through
10.2, I don't really see anything explicit to that effect,
so I suppose your linker could be as "unfriendly" as you
want it to be.  From a practical point of view, the ACATS
tests have generally made the interpretation suggested above,
and presumably vendors have lived with it, and probably users
have grown accustomed to the availability of a semi-automatic
linking process.

I think the key legalistic requirement is that *if*
a unit gets included in an environment, then its semantics
must be based on a single version of its source code and
a single, consistent version of the source code
of the other units.  Whether the user has to take
explicit actions before linking is not really specified
by 10.2.  By contrast, 10.1.4 seems clearer that no
explicit actions are required before compiling in certain
cases, such as a change to a generic body or an implicitly
inlined body.

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

From: Robert Dewar
Sent: Friday, October 20, 2000 11:02 AM

<<May program Q be rejected at link time, or must the linker automatically
regenerate Q's code to be consistent with the new version of P's body?>>

Of course the answer is yes, it can be rejected, there is never a requirement
for the linker to do "compilation" in this sense.

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

From: Dan Eilers
Sent: Saturday, October 21, 2000 12:28 PM

If there is never a requirement for the linker to do automatic "compilation"
to fix up "out-of-date" explicit inlines, is there a requirement for the
linker to do automatic "compilation" to fix up "out-of-date" units where
the compiler acted "as if" there was an explicit inline on a unit that
it noticed contained lots of very small subprograms?  This seems to be
required by AARM 10.1.4(7.d), but perhaps that should just be considered
implementation advise and not be tested by ACATS.

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

From: Robert Dewar
Sent: Saturday, October 21, 2000 7:14 PM

<<If there is never a requirement for the linker to do automatic "compilation"
to fix up "out-of-date" explicit inlines, is there a requirement for the
linker to do automatic "compilation" to fix up "out-of-date" units where
the compiler acted "as if" there was an explicit inline on a unit that
it noticed contained lots of very small subprograms?  This seems to be
required by AARM 10.1.4(7.d), but perhaps that should just be considered
implementation advise and not be tested by ACATS.>>

Obviously if a compiler does something in "as-if" mode then it must do
whatever is necessary to ensure that the behavior really is "as-if".

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

From: Dan Eilers
Sent: Monday, October 23, 2000 3:38 AM

I take that to mean no, there is no requirement for the linker to do
automatic "compilation" for either explicit inlines or properly
implemented implicit inlines, and so AARM 10.1.4(7.d) should not
be tested by ACATS.  Did I understand correctly?  If so, I hope
that AARM 10.1.4(10.a) should also not be tested for the same reason.

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

From: Randy Brukardt
Sent: Monday, October 30, 2000 10:10 PM

Dan said:

> Note that the index for "dependence semantic" is missing 10.1.4(5) and
> 10.2(4), and the index for pragma inline is missing 10.1.4(7).

Based on my understanding of the RM's index, I don't think these would be
justified.
As I understand the index, it indexes only places where things are
*defined*, not where they are *used*. These are all *uses*. (Whether that is
a good idea is another issue altogether, but I think it is important to keep
the index consistent.)

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

From: Randy Brukardt
Sent: Monday, October 30, 2000 10:28 PM

> I take that to mean no, there is no requirement for the linker to do
> automatic "compilation" for either explicit inlines or properly
> implemented implicit inlines, and so AARM 10.1.4(7.d) should not
> be tested by ACATS.  Did I understand correctly?  If so, I hope
> that AARM 10.1.4(10.a) should also not be tested for the same reason.

I don't think Robert meant to imply that. I thought he meant that implicit
inlines ought to behave "as-if" there is no inline at all.

Certainly, *I* think that implicit inlines should be exactly that, and if
that means that you have to do link-time compilation, so be it. (If you
don't like that, don't implement implicit inlining!!!)

OTOH, I don't think it would ever be possible for AARM 10.1.4(7.d) to be
explicitly tested by an ACATS test: how could you possibly insure that a
unit had an implicit inline? But certainly, your interpretation would allow
an implementation to reject linking of any ACATS test that tried to replace
a unit with a new body after compiling another unit containing a call to a
subprogram in the first unit (because you could always claim that the
subprogram had been implicitly inlined). That would be madness.

So, whether or not 10.1.4(7.d) is tested, it is still true. And it has no
bearing on whether 10.1.4(10.a) should be tested, given that there is a
Defect Report (8652/0108) confirming  10.1.4(10-10.a). Indeed, there is
already a test requiring this behavior. (I converted the test to a 'C' test
after an implementor complained that the test was misclassified as an 'L'
test.)

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

From: Robert Dewar
Sent: Tuesday, October 31, 2000 7:18 AM

<<I don't think Robert meant to imply that. I thought he meant that implicit
inlines ought to behave "as-if" there is no inline at all.

Certainly, *I* think that implicit inlines should be exactly that, and if
that means that you have to do link-time compilation, so be it. (If you
don't like that, don't implement implicit inlining!!!)>>

Yes, of course that's what I meant, if you do anything like this implicitly,
it needs to stay implicit :-)

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



Questions? Ask the ACAA Technical Agent