Subprogram parameters (GNAT Reference Manual)

#### 17.3.5.2 Subprogram parameters ¶

    procedure P (V : access T; X : access constant T);

In most cases (the exceptions are described below), a No_Dynamic_Accessibility_Checks restriction means that the “statically deeper” relationship does apply to the anonymous type of an access parameter specifying an access-to-object type (contrary to RM 3.10.2(19.1)) and, for purposes of compile-time “statically deeper” checks, the accessibility level of the type of such a parameter is the accessibility level of the parameter.

This change (at least as described so far) doesn’t affect the caller’s side, but on the callee’s side it means that object designated by a non-null parameter of an anonymous access type is treated as having the same accessibility level as a local object declared immediately within the called subprogram.

With the restriction in effect, the otherwise-legal type conversion in the following example becomes illegal:

    type Ref is access all Integer;
    Ptr : Ref;

    procedure Proc (Param : access Integer) is
    begin
       Ptr := Ref (Param);
    end Proc;

The aforementioned exceptions have to do with return statements from functions that either return the given parameter (in the case of a function whose result type is an anonymous access type) or return the given parameter value as an access discriminant of the function result (or of some discriminated part thereof). More specifically, the “statically deeper” changes described above do not apply for purposes of checking the “shall not be statically deeper” rule for access discriminant parts of function results (RM 6.5(5.9)) or in determining the legality of an (implicit) type conversion from the anonymous access type of a parameter of a function to an anonymous access result type of that function. In order to prevent these rule relaxations from introducing the possibility of dynamic accessibility check failures, compensating compile-time checks are performed at the call site to prevent cases where including the value of an access parameter as part of a function result could make such check failures possible (specifically, the discriminant checks of RM 6.5(21) or, in the case of an anonymous access result type, the RM 4.6(48) check performed when converting to that result type). These compile-time checks are described in the next section.

From the callee’s perspective, the level of anonymous access formal parameters would be between the level of the subprogram and the level of the subprogram’s locals. This has the effect of formal parameters being treated as local to the callee except in:

- Use as a function result
- Use as a value for an access discriminant in result object
- Use as an assignments between formal parameters

Note that with these more restricted rules we lose track of accessibility levels when assigned to local objects thus making (in the example below) the assignment to Node2.Link from Temp below compile-time illegal.

    type Node is record
       Data : Integer;
       Link : access Node;
    end record;

    procedure Swap_Links (Node1, Node2 : in out Node) is
       Temp : constant access Node := Node1.Link; -- We lose the "association" to Node1
    begin
       Node1.Link := Node2.Link; -- Allowed
       Node2.Link := Temp;       -- Not allowed
    end;

    function Identity (N : access Node) return access Node is
       Local : constant access Node := N;
    begin
       if True then
          return N;              -- Allowed
       else
          return Local;          -- Not allowed
       end if;
    end;