Version 1.4 of ai05s/ai05-0095-1.txt

Unformatted version of ai05s/ai05-0095-1.txt version 1.4
Other versions for file ai05s/ai05-0095-1.txt

!standard 13.3(11/1)          08-11-19 AI05-0095-1/03
!standard 13.3(13/1)
!class binding interpretation 08-05-21
!status Amendment 201Z 08-11-26
!status ARG Approved 8-0-1 08-10-31
!status work item 08-05-21
!status received 06-03-24
!priority Low
!difficulty Medium
!qualifier Omission
!subject Address of intrinsic subprograms
!summary
The prefix of 'Address cannot statically denote a subprogram with convention Intrinsic.
'Address raises Program_Error if the prefix denotes a subprogram with convention Intrinsic.
!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
Add after 8.5.4(7.b.1):
AARM Ramification: Similarly, if the renamed entity is not a program unit, then neither is the renaming. (Implicitly declared subprograms are not program units, see 10.1.)
Add after 13.3(11):
"The prefix of X'Address shall not statically denote a subprogram that has convention Intrinsic. X'Address raises Program_Error if X denotes a subprogram that has convention Intrinsic."
!discussion
The intent of the language is that a rename preserves all of the properties of the renamed entity. That includes whether or not the entity is a program unit. Thus, Func1 and Func2 in the question are not program units and thus are illegal.
However, that doesn't really solve the problem, for two reasons.
First, it is 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.
Moreover, the Standard has routines that are not operators that are declared to be Intrinsic. Some examples include 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.
Thus we make it illegal for the prefix of 'Address to statically denote something.
However, because of generics, it's not possible to tell in general at compile-time what the convention of the prefix is. For instance:
with System; generic type T is private; with function "+" (Left, Right : T) return T is <>; package Gen is A : System.Address := Gen."+"'Address; end Gen;
"+" in this generic could be Intrinsic (for instance, if Gen is instantiated with Integer) or Ada (if Gen is instantiated with a user-defined type). Since there is no valid address if the prefix is an intrinsic subprogram, we require raising Program_Error.
!corrigendum 13.3(11/1)
Insert after the paragraph:
Denotes the address of the first of the storage elements allocated to X. For a program unit or label, this value refers to the machine code associated with the corresponding body or statement. The value of this attribute is of type System.Address.
the new paragraph:
The prefix of X'Address shall not statically denote a subprogram that has convention Intrinsic. X'Address raises Program_Error if X denotes a subprogram that has convention Intrinsic.
!ACATS Test
A B-Test should be created to test the "statically denotes" part of the rule. A C-Test could be created to test the Program_Error case, but that 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.

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


Questions? Ask the ACAA Technical Agent