Version 1.1 of ais/ai-00135.txt
!standard 08.05.04 (05) 97-04-11 AI95-00135/02
!class binding interpretation 96-05-07
!status WG9 approved (8-0-0) 97-07-04
!status ARG approved (6-0-3) 97-04-11
!status work item 96-05-08
!status received 96-05-07
!reference AI95-00064
!priority Medium
!difficulty Medium
!subject Circular Renamings as Body
!summary 96-05-08
A circular renaming-as-body represents infinite recursion. If the
renaming-as-body occurs before the subprogram whose body is being
defined is frozen, the renaming-as-body is illegal.
!question 96-05-08
Consider the following example:
package Example is
function F return Boolean;
function G return Boolean renames F;
function H return Boolean renames G;
private
function F return Boolean renames H; --
end EXAMPLE;
8.5.4(5) says:
5 The profile of a renaming-as-body shall be subtype-conformant with that
of the renamed callable entity, and shall conform fully to that of the
declaration it completes. If the renaming-as-body completes that declaration
before the subprogram it declares is frozen, the subprogram it declares takes
its convention from the renamed subprogram; otherwise the convention of the
renamed subprogram shall not be Intrinsic.
In the above example, the renaming-as-body for F occurs before F is
frozen. Therefore, F takes its calling convention from H, which comes
from G, which comes from F. So what is the calling convention of F?
!recommendation 96-05-08
For a subprogram whose body is defined by a renaming-as-body, if the
rule in 8.5.4(5) requires the calling convention of the subprogram to be
taken ultimately from itself, then the renaming-as-body is illegal.
!wording 96-05-08
!discussion 96-07-23
In the above example, the definition of the calling convention of F is
not well-defined, because of the circular definition in 8.5.4(5).
Therefore, we choose to make this case illegal.
An alternative would be to define the calling convention to be Ada in
this case. However, the compiler needs to detect the circularity
anyway, in order to avoid an infinite loop during semantic analysis.
Therefore, we might as well let the compiler give an error message,
rather than generating infinitely-recursive code.
The wording of the recommendation refers to the effect of the rule in
8.5.4(5), rather than stating the exact cases explicitly, because the
explicit definition would be complicated. Here's another way to state
the rule: Start from the renaming-as-body in question. Follow all
renamings-as-declaration. Follow all renamings-as-body that occur
before their own freezing point. Do not follow other renamings-as-body.
If you eventually get back to the declaration of the subprogram in
question, then it's illegal.
Note that some circularities are legal. In particular, if the
renaming-as-body completes a subprogram after that subprogram is
frozen, the circularity is legal, and will be infinitely recursive at
run time. For example:
package Pack_1 is
procedure P;
end Pack_1;
package Pack_2 is
procedure Q;
end Pack_2;
with Pack_2;
package body Pack_1 is
procedure P renames Pack_2.Q;
end Pack_1;
with Pack_1;
package body Pack_2 is
procedure Q renames Pack_1.P;
end Pack_2;
The above is legal, the convention of P and Q is Ada, and a call to P or
Q will be infinitely recursive. Note that we don't want to make this
case illegal, since it cannot be detected at compile time.
Here is another example of legal circularity:
type Ptr is access function return Integer:
function F return Integer;
P: Ptr := F'access;
function F return Integer renames P.all;
The convention of P.all is Ada, by 6.3.1(3). F is frozen by the
declaration of P, by 13.14(6,4,11). Therefore, 8.5.4(5) does not
specify the convention of F; it defaults to Ada, and the subtype
conformance required by 8.5.4(5) is satisfied.
Any call to F or P.all will result in infinite recursion.
!appendix
!section 8.5.4(05)
!subject Renaming as Body
!reference RM95-8.5.4(5)
!from Ivan B. Cvar 96-04-25
!keywords renaming renaming-as-body body
!reference 96-5517.a Ivan B. Cvar 96-4-25>>
!discussion
Here's a copy of a note I sent to Tucker Taft on this topic, followed by
his response...
-------------attachment starts here-------------
Tucker,
Would you mind answering another Ada95 language question?
This one's for renaming-as-body declarations that rename themselves
via another renaming (eg, circularity).
What RM95 rule makes this completion of "&" illegal? Or, is it really legal,
but supposedly caught at runtime by elaboration checks when the renaming is
called (per 6.3(6), notwithstanding 3.11(10))?
I hope it's not a legal completion, but we could not find a rule that would
make it illegal. I checked 3.11, 6.all, 7.all, 8.all, etc. And neither
8.3(19) not 8.3(26) apply here.
package EXAMPLE is
function "&" ( L,R : Integer) return Integer;
function OK ( L,R : Integer) return Integer renames "&";
private
function "&" ( L,R : Integer) return Integer renames OK; --LEGAL OR NOT?
end EXAMPLE;
Thanks
...Ivan
Date: Tue, 19 Mar 1996 15:37:15 -0500
From: stt@dsd.camb.inmet.com (Tucker Taft)
To: ibc@ocsystems.com
Subject: Re: Renaming as Body
Sounds like a bug in the manual, since there is no way to decide what
should be the calling convention for the subprogram, based on 8.5.4(10).
The circularity is not by itself illegal, since you might not know
at compile-time that there is a circularity (if the circularity
involved multiple library units). The semantic model of a
renaming-as-body is that one subprogram calls the other, so a circularity
is no more illegal than is infinite recursion. (I suppose you could
replace any call on such a routine with a "raise Storage_Error" ;-).
But a circularity within a single package spec introduces
problems because of the calling convention, and hence should be
illegal.
-Tucker Taft stt@inmet.com
-------------attachment ends here-------------
****************************************************************
Questions? Ask the ACAA Technical Agent