!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; -- Legal? (No.) 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 96-05-07 !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------------- ****************************************************************