3.28 Aspect Local_Restrictions

This aspect may be specified for a subprogram (and for other declarations as described below). It is used to specify that a particular subprogram does not violate one or more local restrictions, nor can it call a subprogram that is not subject to the same requirement. Positional aggregate syntax (with parentheses, not square brackets) may be used to specify more than one local restriction, as in

procedure Do_Something
  with Local_Restrictions => (Some_Restriction, Another_Restriction);

Parentheses are currently required even in the case of specifying a single local restriction (this requirement may be relaxed in the future). Supported local restrictions currently include (only) No_Heap_Allocations and No_Secondary_Stack. No_Secondary_Stack corresponds to the GNAT-defined (global) restriction of the same name. No_Heap_Allocations corresponds to the conjunction of the Ada-defined restrictions No_Allocators and No_Implicit_Heap_Allocations.

Additional requirements are imposed in order to ensure that restriction violations cannot be achieved via overriding dispatching operations, calling through an access-to-subprogram value, calling a generic formal subprogram, or calling through a subprogram renaming. For a dispatching operation, an overrider must be subject to (at least) the same restrictions as the overridden inherited subprogram; similarly, the actual subprogram corresponding to a generic formal subprogram in an instantiation must be subject to (at least) the same restrictions as the formal subprogram. A call through an access-to-subprogram value is conservatively assumed to violate all local restrictions; tasking-related constructs (notably entry calls) are treated similarly. A renaming-as-body is treated like a subprogram body containing a call to the renamed subprogram.

The Local_Restrictions aspect can be specified for a package specification, in which case the aspect specification also applies to all eligible entities declared with the package. This includes types. Default initialization of an object of a given type is treated like a call to an implicitly-declared initialization subprogram. Such a “call” is subject to the same local restriction checks as any other call. If a type is subject to a local restriction, then any violations of that restriction within the default initialization expressions (if any) of the type are rejected. This may include “calls” to the default initialization subprograms of other types.

Local_Restrictions aspect specifications are additive (for example, in the case of a declaration that occurs within nested packages that each have a Local_Restrictions specification).