!standard 13.3(11/1) 08-05-21 AI05-0095-1/01 !standard 13.3(13/1) !class binding interpretation 08-05-21 !status work item 08-05-21 !status received 06-03-24 !priority Low !difficulty Medium !qualifier Omission !subject Address of intrinsic subprograms !summary Option 1: The prefix of 'Address cannot have convention Intrinsic. Option 2: 'Address can be rejected if the implementation cannot produce a useful result. !question What, according to the language rules, is supposed to happen in these cases? with System; procedure Proc is function Func1 return Boolean renames False; function Func2 (Left, Right : Integer) return Integer renames Standard."+"; A1 : System.Address := Func1'Address; A2 : System.Address := Func2'Address; begin...end; 13.3(10) says that X'Address is defined for any program unit X. The definition of "program unit" includes "an explicitly declared subprogram other than an enumeration literal". Although "False" and Standard."+" don't meet that definition, Func1 and Func2 seem to meet it, since they are explicitly declared and are declared as subprograms. Thus, it appears that the compiler must accept Func1'Address and Func2'Address, according to the rules. However, in the Implementation Advice for 'Address, there is nothing at all about the recommended level of support for 'Address on a subprogram, which seems to imply that an implementation never has to return a useful result. But I also see nothing that says implementations are allowed to reject 'Address when the result would be useless. What is the intent here? !wording Option 1: Add to 13.3(11): "The prefix of X'Address shall not have convention Intrinsic." Option 2: Add after 13.3(13): Implementation Permissions An implementation may reject use of the value X'Address if it is unable to produce a useful address for X. !discussion [Randy's rant on this topic.] It has been suggested since False and Standard."+" is not a program unit, and program units are entities, not declarations, the rename of it is also not a program unit. This logic is suspicious as it seems to assume that "views" are not involved. But as we all know, views are always involved for static rules. It also assumes that this property is passed through a renames, but that is not really covered by 8.5.4(7). Even if we grant all of the above [which I'm not willing to do - RLB], it doesn't really help. It's easy to find explicitly declared intrinsic subprograms in the Ada standard, and it is likely that implementations have many more. For instance, change the example to: with System; procedure Proc2 is function Func3 (Left, Right : System.Address) return Boolean renames System."<"; A3 : System.Address := Func3'Address; begin...end; "<" is explicitly declared in the specification of System (13.7(14)) and is explicitly given convention Intrinsic. Still not convinced because the use of operators? Try the routines in System.Storage_Elements (like To_Address and To_Pointer), instances of Unchecked_Conversion and Unchecked_Deallocation, and routines inside of instances of Access_to_Address_Conversions and Interfaces.C.Pointers. Many of these can even be directly referenced without using a rename (as is usually needed for operators because of overloading). It's pretty clear that these latter examples are indeed program units, but it does no one any good to allow them as prefixes of 'Address and require the attribute to produce a useless result. Rules that require the production of junk (not useful) results have no possible value, and surely do nothing to enhance portability. Therefore, it seems that something should be illegal here. The easy fix is to make it illegal to take 'Address of a prefix with convention Intrinsic. That seems like a no-brainer, given that 'Access has long been disallowed for that, and 'Address is simply the untyped form of 'Access. A better fix (IMHO) would be give implementations permission to reject any 'Address that they cannot usefully implement. Anything that we wish to require should already be covered in the Recommended Level of Support, so such a rule would have little impact on portability. But it would help catch programs that have no chance of working earlier. These two options are not exclusive: the first improves error detection somewhat by forcing all compilers to reject intrinsic prefixes, and the second allows compilers to go further and prevent junk uses of 'Address. --!corrigendum 13.3(11/1) !ACATS Test A B-Test could be created to test the rule of the first option, but it seems to be fairly low value. !appendix !topic 'Address of subprograms that rename intrinsics !reference RM05 13.3, 10.1 !from Adam Beneschan 08-03-24 !discussion What, according to the language rules, is supposed to happen in these cases? with System; procedure Proc is function Func1 return Boolean renames False; function Func2 (Left, Right : Integer) return Integer renames Standard."+"; A1 : System.Address := Func1'Address; A2 : System.Address := Func2'Address; begin...end; Which of the following is true for the declarations of A1 and A2? (1) The compiler is allowed to reject them. (2) The compiler must accept the declarations but may initialize the variables to useless values. (3) The compiler must accept the declaration and must generate "dummy" functions so that a sensible 'Address value can be generated. 13.3(10) seems to say that X'Address is defined for any program unit X. The definition of "program unit" includes "an explicitly declared subprogram other than an enumeration literal". Although "False" and Standard."+" don't meet that definition, Func1 and Func2 seem to meet it, since they are explicitly declared and are declared as subprograms. (I don't think it works to say that a subprogram declared by a subprogram_renaming_declaration, rather than a subprogram_declaration, is not an explicitly declared subprogram, since we need the ability to apply 'Address to renaming subprograms when the original subprogram is overloaded. Also, I don't see any language in the RM that implies that a renaming subprogram is or isn't a "program unit" based on *what* it renames.) If I'm reading it right, therefore, it appears that the compiler must accept Func1'Address and Func2'Address, according to the rules. However, in the Implementation Advice for 'Address, there is nothing at all about the recommended level of support for 'Address on a subprogram, which seems to imply that an implementation never has to return a useful result. But I also see nothing that says implementations are allowed to reject 'Address when the result would be useless. 13.3(6) notes that an attribute_definition_clause can be applied only to subprograms whose convention is Ada (which would not be the case for Func1 and Func2 here); but that doesn't apply to the use of 'Address in an expression. If (2) is the correct answer, I'm not really happy with it. It seems to me that in a case an implementation is allowed to return a useless result for 'Address, it would be best to allow the implementation to reject the program (or, possibly, to raise Program_Error if the use is in a generic instance body). What purpose would be served by forcing an implementation to accept a program when it "knows" the result is going to be incorrect? I think it could be harmful if, say, a programmer changes a function declaration in a package spec to be one of these renaming functions, without realizing that somewhere else in some other package, another programmer used the 'Address of that function. **************************************************************** From: Tucker Taft Sent: Monday, March 24, 2008 12:56 PM A renaming-as-declaration of a subprogram creates a new view of the existing entity. "Program unit" is defined in terms of entities, not declarations. Hence, a renaming of a subprogram that is not a program unit is (still) not a program unit. Hence 'Address is not defined for such a renaming. ****************************************************************