6.1 Subprogram Declarations
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
[A subprogram_declaration
declares a procedure or function.]
Syntax
2/3subprogram_declaration
::=
[overriding_indicator
]
subprogram_specification
[aspect_specification
];
3/2This paragraph was deleted.
subprogram_specification
::=
procedure_specification
| function_specification
4.1/2procedure_specification
::=
procedure defining_program_unit_name
parameter_profile
4.2/2function_specification
::=
function defining_designator
parameter_and_result_profile
5designator
::=
[parent_unit_name
. ]identifier
| operator_symbol
6defining_designator
::=
defining_program_unit_name
| defining_operator_symbol
7defining_program_unit_name
::=
[parent_unit_name
. ]defining_identifier
8[The optional parent_unit_name
is only allowed for library units (see 10.1.1).]
operator_symbol
::=
string_literal
10/3The sequence of characters in an operator_symbol
shall form a reserved word, a delimiter, or compound delimiter that corresponds to an operator belonging to one of the six categories of operators defined in subclause 4.5.
defining_operator_symbol
::=
operator_symbol
12parameter_profile
::=
[formal_part
]
13/2parameter_and_result_profile
::=
[formal_part
] return [null_exclusion
] subtype_mark
| [formal_part
] return access_definition
14formal_part
::=
(parameter_specification
{; parameter_specification
})
15/5parameter_specification
::=
defining_identifier_list
: [aliased] mode
[null_exclusion
] subtype_mark
[:= default_expression
]
[aspect_specification
]
| defining_identifier_list
: access_definition
[:= default_expression
]
[aspect_specification
]
mode
::=
[in] | in out | out
Name Resolution Rules
17A formal parameter is an object [directly visible within a subprogram_body
] that represents the actual parameter passed to the subprogram in a call; it is declared by a parameter_specification
. For a formal parameter, the expected type for its default_expression
, if any, is that of the formal parameter.
Legality Rules
18/3The parameter mode of a formal parameter conveys the direction of information transfer with the actual parameter: in, in out, or out. Mode in is the default, and is the mode of a parameter defined by an access_definition
.
A default_expression
is only allowed in a parameter_specification
for a formal parameter of mode in.
A subprogram_declaration
or a generic_subprogram_declaration
requires a completion [unless the Import aspect (see B.1) is True for the declaration; the completion shall be a body or a renaming_declaration
(see 8.5)]. [A completion is not allowed for an abstract_subprogram_declaration
(see 3.9.3), a null_procedure_declaration
(see 6.7), or an expression_function_declaration
(see 6.8).]
subprogram_declaration
s, and so do not require completion (although the latter two can be completions). Protected subprograms are declared by subprogram_declaration
s, and so require completion. Note that an abstract subprogram is a subprogram, a null procedure is a subprogram, an expression function is a subprogram, and a protected subprogram is a subprogram, but a generic subprogram is not a subprogram. A name
that denotes a formal parameter is not allowed within the formal_part
in which it is declared, nor within the formal_part
of a corresponding body or accept_statement
.
generic_formal_parameter_declaration
s are visible to subsequent declarations in the same generic_formal_part
. Static Semantics
22The profile of (a view of) a callable entity is either a parameter_profile
or parameter_and_result_profile
[; it embodies information about the interface to that entity — for example, the profile includes information about parameters passed to the callable entity. All callable entities have a profile — enumeration literals, other subprograms, and entries. An access-to-subprogram type has a designated profile.] Associated with a profile is a calling convention. A subprogram_declaration
declares a procedure or a function, as indicated by the initial reserved word, with name and profile as given by its specification.
The nominal subtype of a formal parameter is the subtype determined by the optional null_exclusion
and the subtype_mark
, or defined by the access_definition
, in the parameter_specification
. The nominal subtype of a function result is the subtype determined by the optional null_exclusion
and the subtype_mark
, or defined by the access_definition
, in the parameter_and_result_profile
.
An explicitly aliased parameter is a formal parameter whose parameter_specification
includes the reserved word aliased.
An access parameter is a formal in parameter specified by an access_definition
. An access result type is a function result type specified by an access_definition
. An access parameter or result type is of an anonymous access type (see 3.10). [Access parameters of an access-to-object type allow dispatching calls to be controlled by access values. Access parameters of an access-to-subprogram type permit calls to subprograms passed as parameters irrespective of their accessibility level.]
The subtypes of a profile are:
- For any non-access parameters, the nominal subtype of the parameter.
- For any access parameters of an access-to-object type, the designated subtype of the parameter type.
- For any access parameters of an access-to-subprogram type, the subtypes of the designated profile of the parameter type.
- For any non-access result, the nominal subtype of the function result.
- For any access result type of an access-to-object type, the designated subtype of the result type.
- For any access result type of an access-to-subprogram type, the subtypes of the designated profile of the result type.
[ The types of a profile are the types of those subtypes.]
[A subprogram declared by an abstract_subprogram_declaration
is abstract; a subprogram declared by a subprogram_declaration
is not. See 3.9.3, “Abstract Types and Subprograms”. Similarly, a procedure declared by a null_procedure_declaration
is a null procedure; a procedure declared by a subprogram_declaration
is not. See 6.7, “Null Procedures”. Finally, a function declared by an expression_function_declaration
is an expression function; a function declared by a subprogram_declaration
is not. See 6.8, “Expression Functions”.]
[An overriding_indicator
is used to indicate whether overriding is intended. See 8.3.1, “Overriding Indicators”.]
Dynamic Semantics
31/2The elaboration of a subprogram_declaration
has no effect.
parameter_specification
with several identifiers is equivalent to a sequence of single parameter_specification
s, as explained in 3.3.default_expression
s is caused by certain calls, as described in 6.4.1. They are not evaluated during the elaboration of the subprogram declaration.Examples
36Examples of subprogram declarations:
procedure Traverse_Tree;
procedure Increment(X : in out Integer);
procedure Right_Indent(Margin : out Line_Size); -- see 3.5.4
procedure Switch(From, To : in out Link); -- see 3.10.1
38function Random return Probability; -- see 3.5.7
39/4function Min_Cell(X : Link) return Cell; -- see 3.10.1
function Next_Frame(K : Positive) return Frame; -- see 3.10
function Dot_Product(Left, Right : Vector) return Real; -- see 3.6
function Find(B : aliased in out Barrel; Key : String) return Real;
-- see 4.1.5
40function "*"(Left, Right : Matrix) return Matrix; -- see 3.6
41Examples of in parameters with default expressions:
procedure Print_Header(Pages : in Natural;
Header : in Line := (1 .. Line'Last => ' '); -- see 3.6
Center : in Boolean := True);
Extensions to Ada 83
abstract_subprogram_declaration
is added. The syntax for parameter_specification
is revised to allow for access parameters (see 3.10)parent_unit_name
to indicate the parent of a child (see 10.1.1). Wording Changes from Ada 83
defining_operator_symbol
is new. It is used for the defining occurrence of an operator_symbol
, analogously to defining_identifier
. Usage occurrences use the direct_name
or selector_name
syntactic categories. The syntax rules for defining_designator
and defining_program_unit_name
are new. Extensions to Ada 95
null_exclusion
can be used in a formal parameter declaration. Similarly, an optional null_exclusion
can be used in a function result.Wording Changes from Ada 95
subprogram_specification
in order to make the declaration of null procedures (see 6.7) easier.abstract_subprogram_declaration
to 3.9.3, so that the syntax and semantics are together. This also keeps abstract and null subprograms similar.other_format
characters in operator_symbol
s in the same way as the underlying constructs. Extensions to Ada 2005
aspect_specification
can be used in a subprogram_declaration
. This is described in 13.1.1. Wording Changes from Ada 2005
Extensions to Ada 2012
aspect_specification
, allowing the specification of (implementation-defined) aspects for individual parameters. 6.1.1 Preconditions and Postconditions
1/5For a noninstance subprogram [(including a generic formal subprogram)], a generic subprogram, an entry, or an access-to-subprogram type, the following language-defined assertion aspects may be specified with an aspect_specification
(see 13.1.1):
Pre
- This aspect specifies a specific precondition for a callable entity or an access-to-subprogram type; it shall be specified by an
expression
, called a specific precondition expression. If not specified for an entity, the specific precondition expression for the entity is the enumeration literal True.
Pre'Class
- This aspect specifies a class-wide precondition for a dispatching operation of a tagged type and its descendants; it shall be specified by an
expression
, called a class-wide precondition expression. If not specified for an entity, then if no other class-wide precondition applies to the entity, the class-wide precondition expression for the entity is the enumeration literal True.
Post
- This aspect specifies a specific postcondition for a callable entity or an access-to-subprogram type; it shall be specified by an
expression
, called a specific postcondition expression. If not specified for an entity, the specific postcondition expression for the entity is the enumeration literal True.
Post'Class
- This aspect specifies a class-wide postcondition for a dispatching operation of a tagged type and its descendants; it shall be specified by an
expression
, called a class-wide postcondition expression. If not specified for an entity, the class-wide postcondition expression for the entity is the enumeration literal True.
Name Resolution Rules
7/3The expected type for a precondition or postcondition expression is any boolean type.
Within the expression for a Pre'Class or Post'Class aspect for a primitive subprogram S of a tagged type T, a name
that denotes a formal parameter (or S'Result) of type T is interpreted as though it had a (notional) nonabstract type NT that is a formal derived type whose ancestor type is T, with directly visible primitive operations. Similarly, a name
that denotes a formal access parameter (or S'Result for an access result) of type access-to-T is interpreted as having type access-to-NT. [The result of this interpretation is that the only operations that can be applied to such name
s are those defined for such a formal derived type.]
For an attribute_reference
with attribute_designator
Old, if the attribute reference has an expected type (or class of types) or shall resolve to a given type, the same applies to the prefix
; otherwise, the prefix
shall be resolved independently of context.
Legality Rules
10/3The Pre or Post aspect shall not be specified for an abstract subprogram or a null procedure. [Only the Pre'Class and Post'Class aspects may be specified for such a subprogram.]
If a type T has an implicitly declared subprogram P inherited from a parent type T1 and a homograph (see 8.3) of P from a progenitor type T2, and
- the corresponding primitive subprogram P1 of type T1 is neither null nor abstract; and
- the class-wide precondition expression True does not apply to P1 (implicitly or explicitly); and
- there is a class-wide precondition expression that applies to the corresponding primitive subprogram P2 of T2 that does not fully conform to any class-wide precondition expression that applies to P1,
then:
- If the type T is abstract, the implicitly declared subprogram P is abstract.
- Otherwise, the subprogram P requires overriding and shall be overridden with a nonabstract subprogram.
If a renaming of a subprogram or entry S1 overrides an inherited subprogram S2, then the overriding is illegal unless each class-wide precondition expression that applies to S1 fully conforms to some class-wide precondition expression that applies to S2 and each class-wide precondition expression that applies to S2 fully conforms to some class-wide precondition expression that applies to S1.
Pre'Class shall not be specified for an overriding primitive subprogram of a tagged type T unless the Pre'Class aspect is specified for the corresponding primitive subprogram of some ancestor of T.
In addition to the places where Legality Rules normally apply (see 12.3), these rules also apply in the private part of an instance of a generic unit.
Static Semantics
19/5If a Pre'Class or Post'Class aspect is specified for a primitive subprogram S of a tagged type T, or such an aspect defaults to True, then a corresponding expression also applies to the corresponding primitive subprogram S of each descendant of T [(including T itself)]. The corresponding expression is constructed from the associated expression as follows:
- References to formal parameters of S (or to S itself) are replaced with references to the corresponding formal parameters of the corresponding inherited or overriding subprogram S (or to the corresponding subprogram S itself).
If the primitive subprogram S is not abstract, but the given descendant of T is abstract, then a nondispatching call on S is illegal if any Pre'Class or Post'Class aspect that applies to S is other than a static boolean expression. Similarly, a primitive subprogram of an abstract type T, to which a non-static Pre'Class or Post'Class aspect applies, shall neither be the prefix of an Access attribute_reference, nor shall it be a generic actual subprogram for a formal subprogram declared by a formal_concrete_subprogram_declaration
.
If performing checks is required by the Pre, Pre'Class, Post, or Post'Class assertion policies (see 11.4.2) in effect at the point of a corresponding aspect specification applicable to a given subprogram, entry, or access-to-subprogram type, then the respective precondition or postcondition expressions are considered enabled.
A subexpression of a postcondition expression is known on entry if it is any of:
- a static subexpression (see 4.9) ;
- a literal whose type does not have any Integer_Literal, Real_Literal, or String_Literal aspect specified, or the function specified by such an attribute has aspect Global specified to be null ;
- a name statically denoting a full constant declaration which is known to have no variable views (see 3.3) ;
- a name statically denoting a nonaliased in parameter of an elementary type;
- an Old
attribute_reference
; 23.4/5 - an invocation of a predefined operator where all of the operands are known on entry;
- a function call where the function has aspect Global => null where all of the actual parameters are known on entry;
- a
selected_component
of a known-on-entryprefix
; 23.7/5 - an
indexed_component
of a known-on-entryprefix
where all indexexpression
s are known on entry; 23.8/5 - a parenthesized known-on-entry
expression
; 23.9/5 - a
qualified_expression
ortype_conversion
whose operand is a known-on-entry expression; 23.10/5 - a
conditional_expression
where all of thecondition
s, selecting_expression
s, and dependent_expression
s are known on entry.
A subexpression of a postcondition expression is unconditionally evaluated, conditionally evaluated, or repeatedly evaluated. A subexpression is considered unconditionally evaluated unless it is conditionally evaluated or repeatedly evaluated.
The following subexpressions are repeatedly evaluated:
- A subexpression of a predicate of a
quantified_expression
; 23.14/5 - A subexpression of the expression of an
array_component_association
; 23.15/5 - A subexpression of the expression of a
container_element_association
.
For a subexpression that is conditionally evaluated, there is a set of determining expressions that determine whether the subexpression is actually evaluated at run time. Subexpressions that are conditionally evaluated and their determining expressions are as follows:
- For an
if_expression
that is not repeatedly evaluated, a subexpression of any part other than the first condition is conditionally evaluated, and its determining expressions include allcondition
s of theif_expression
that precede the subexpression textually; 23.18/5 - For a
case_expression
that is not repeatedly evaluated, a subexpression of any dependent_expression
is conditionally evaluated, and its determining expressions include the selecting_expression
of thecase_expression
; 24/5 - For a short-circuit control form that is not repeatedly evaluated, a subexpression of the right-hand operand is conditionally evaluated, and its determining expressions include the left-hand operand of the short-circuit control form;
- For a membership test that is not repeatedly evaluated, a subexpression of a
membership_choice
other than the first is conditionally evaluated, and its determining expressions include the tested_simple_expression
and the precedingmembership_choice
s of the membership test .
A conditionally evaluated subexpression is determined to be unevaluated at run time if its set of determining expressions are all known on entry, and when evaluated on entry their values are such that the given subexpression is not evaluated.
- Within an
if_expression
, a dependent_expression
with an associatedcondition
that evaluates to False, or acondition
or dependent_expression
where a condition of a preceding part of theif_expression
evaluates to True; 25.c - Within a
case_expression
, a dependent_expression
with andiscrete_choice_list
that is not covered by the value of the selecting_expression
; 25.d/5 - The right-hand operand of a short-circuit control form where the left-hand operand evaluates to False for and then or True for or else;
- A
membership_choice
of a membership test where the individual membership test defined by any priormembership_choice
evaluates to True.
For a prefix
X that denotes an object of a nonlimited type, the following attribute is defined:
X'Old
- Each X'Old in a postcondition expression that is enabled, other than those that occur in subexpressions that are determined to be unevaluated, denotes a constant that is implicitly declared at the beginning of the subprogram body, entry body, or accept statement.
- The implicitly declared entity denoted by each occurrence of X'Old is declared as follows:
- If X is of an anonymous access type defined by an
access_definition
A then
X'Old : constant A := X;
- If X is of a specific tagged type T then
anonymous : constant T'Class := T'Class(X);
X'Old : T renames T(anonymous);
- where the name X'Old denotes the object renaming.
- Otherwise
X'Old : constant S := X;
- where S is the nominal subtype of X. This includes the case where the type of S is an anonymous array type or a universal type.
- The type and nominal subtype of X'Old are as implied by the above definitions.
- Reference to this attribute is only allowed within a postcondition expression. The
prefix
of an Oldattribute_reference
shall not contain a Resultattribute_reference
, nor an Oldattribute_reference
, nor a use of an entity declared within the postcondition expression but not withinprefix
itself (for example, the loop parameter of an enclosingquantified_expression
). Theprefix
of an Oldattribute_reference
shall statically name (see 4.9) an entity, unless theattribute_reference
is unconditionally evaluated, or is conditionally evaluated where all of the determining expressions are known on entry.
prefix
X can be any nonlimited object that obeys the syntax for prefix other than the few exceptions given above (discussed below). Useful cases are: the name
of a formal parameter of mode [in] out, the name
of a global variable updated by the subprogram, a function call passing those as parameters, a subcomponent of those things, etc.prefix
of an Old attribute_reference
is evaluated when the subprogram is called (if it is evaluated at all), we cannot allow it to include values that do not exist at that time (like 'Result and loop parameters of quantified_expression
s). We also do not allow the prefix
itself to include 'Old references, as those would be redundant (because the evaluation of the prefix
, if it occurs, already happens on entry to the subprogram ), and allowing them would require some sort of order to the implicit constant declarations (because in A(I'Old)'Old, we surely would want the value of I'Old evaluated before the A(I'Old) is evaluated).attribute_reference
will or will not be evaluated when the overall postcondition expression is evaluated. In such cases , we require that the prefix
of the Old attribute_reference
to statically name some object . This is necessary because the Old prefix
es have to be evaluated when the subprogram is called if there is any possibility that they might be needed; the compiler cannot in general know whether they will be needed in the postcondition expression. To see the problem, consider:Table : array (1..10) of Integer := ...
procedure Bar (I : in out Natural)
with Post => I > 0 and then Table(I)'Old = 1; -- Illegal
prefix
of any Old attribute_reference
in such a context to statically name an object, which eliminates anything that could change during execution.accept E do
statements
exception
handlers
end;
accept E do
declare
declarations, if any, of 'Old constants
begin
begin
statements
exception
handlers
end;
postcondition checks
end;
end;
prefix
of an Old attribute_reference
has to statically name an entity if it appears within a repeatedly evaluated expression. For a prefix
F that denotes a function declaration or an access-to-function type, the following attribute is defined:
F'Result
- Within a postcondition expression for F, denotes the return object of the function call for which the postcondition expression is evaluated. The type of this attribute is that of the result subtype of the function or access-to-function type except within a Post'Class postcondition expression for a function with a controlling result or with a controlling access result; in those cases the type of the attribute is described above as part of the Name Resolution Rules for Post'Class .
- Use of this attribute is allowed only within a postcondition expression for F.
For a prefix
E that denotes an entry declaration of an entry family (see 9.5.2), the following attribute is defined:
E'Index
- Within a precondition or postcondition expression for entry family E, denotes the value of the entry index for the call of E. The nominal subtype of this attribute is the entry index subtype.
- Use of this attribute is allowed only within a precondition or postcondition expression for E.
Dynamic Semantics
32/3Upon a call of the subprogram or entry, after evaluating any actual parameters, precondition checks are performed as follows:
- The specific precondition check begins with the evaluation of the specific precondition expression that applies to the subprogram or entry, if it is enabled; if the expression evaluates to False, Assertions.Assertion_Error is raised; if the expression is not enabled, the check succeeds.
- The class-wide precondition check begins with the evaluation of any enabled class-wide precondition expressions that apply to the subprogram or entry. If and only if all the class-wide precondition expressions evaluate to False, Assertions.Assertion_Error is raised.
The precondition checks are performed in an arbitrary order, and if any of the class-wide precondition expressions evaluate to True, it is not specified whether the other class-wide precondition expressions are evaluated. The precondition checks and any check for elaboration of the subprogram body are performed in an arbitrary order. In a call on a protected operation, the checks are performed before starting the protected action. For an entry call, the checks are performed prior to checking whether the entry is open.
Upon successful return from a call of the subprogram or entry, prior to copying back any by-copy in out or out parameters, the postcondition check is performed. This consists of the evaluation of any enabled specific and class-wide postcondition expressions that apply to the subprogram or entry. If any of the postcondition expressions evaluate to False, then Assertions.Assertion_Error is raised. The postcondition expressions are evaluated in an arbitrary order, and if any postcondition expression evaluates to False, it is not specified whether any other postcondition expressions are evaluated. The postcondition check, and any constraint or predicate checks associated with in out or out parameters are performed in an arbitrary order.
For a call to a task entry, the postcondition check is performed before the end of the rendezvous; for a call to a protected operation, the postcondition check is performed before the end of the protected action of the call. The postcondition check for any call is performed before the finalization of any implicitly-declared constants associated (as described above) with Old attribute_reference
s but after the finalization of any other entities whose accessibility level is that of the execution of the callable construct.
If a precondition or postcondition check fails, the exception is raised at the point of the call[; the exception cannot be handled inside the called subprogram or entry]. Similarly, any exception raised by the evaluation of a precondition or postcondition expression is raised at the point of call.
For any call to a subprogram or entry S (including dispatching calls), the checks that are performed to verify specific precondition expressions and specific and class-wide postcondition expressions are determined by those for the subprogram or entry actually invoked. Note that the class-wide postcondition expressions verified by the postcondition check that is part of a call on a primitive subprogram of type T includes all class-wide postcondition expressions originating in any progenitor of T[, even if the primitive subprogram called is inherited from a type T1 and some of the postcondition expressions do not apply to the corresponding primitive subprogram of T1]. Any operations within a class-wide postcondition expression that were resolved as primitive operations of the (notional) formal derived type NT, are in the evaluation of the postcondition bound to the corresponding operations of the type identified by the controlling tag of the call on S.[ This applies to both dispatching and non-dispatching calls on S.]
The class-wide precondition check for a call to a subprogram or entry S consists solely of checking the class-wide precondition expressions that apply to the denoted callable entity (not necessarily to the one that is invoked). Any operations within such an expression that were resolved as primitive operations of the (notional) formal derived type NT are in the evaluation of the precondition bound to the corresponding operations of the type identified by the controlling tag of the call on S.[ This applies to both dispatching and non-dispatching calls on S.]
For the purposes of the above rules, a call on an inherited subprogram is considered to involve a call on a subprogram S' whose body consists only of a call (with appropriate conversions) on the non-inherited subprogram S from which the inherited subprogram was derived. It is not specified whether class-wide precondition or postcondition expressions that are equivalent (with respect to which non-inherited function bodies are executed) for S and S' are evaluated once or twice. If evaluated only once, the value returned is used for both associated checks.
For a call via an access-to-subprogram value, precondition and postcondition checks performed are as determined by the subprogram or entry denoted by the prefix of the Access attribute reference that produced the value. In addition, a precondition check of any precondition expression associated with the access-to-subprogram type is performed. Similarly, a postcondition check of any postcondition expression associated with the access-to-subprogram type is performed.
[For a call on a generic formal subprogram, precondition and postcondition checks performed are as determined by the subprogram or entry denoted by the actual subprogram, along with any specific precondition and specific postcondition of the formal subprogram itself.]
Implementation Permissions
43/5An implementation may evaluate a known-on-entry subexpression of a postcondition expression of an entity at the place where X'Old constants are created for the entity, with the normal evaluation of the postcondition expression, or both.
Extensions to Ada 2005
Inconsistencies With Ada 2012
Incompatibilities With Ada 2012
expression
in an array aggregate can now be potentially unevaluated, requiring the prefix to be statically determined. Existing code that uses the Old attribute with a dynamic prefix in such contexts will now be illegal. However, in many cases, the existing code will not do what the programmer is expecting (as Old is evaluated textually, once per occurrence, while array aggregate components are evaluated once per component). In addition, Old is a new Ada 2012 feature, so most Ada legacy code will not contain it. The problem is usually easily fixed by moving Old to an outer object (such as the entire aggregate). Extensions to Ada 2012
prefix
of a statically unevaluated Old attribute_reference
can be a selected_component
or indexed_component
. This is considered a correction as the old rule is unintentionally too fierce, rejecting safe cases.prefix
of an Old attribute_reference
if we can determine when the subprogram is entered (which is the point when Old prefixes are evaluated) whether it will be needed in the evaluation of the postcondition.Wording Changes from Ada 2012
6.1.2 The Global and Global'Class Aspects
1/5The Global and Global'Class aspects of a program unit are used to identify the objects global to the unit that can be read or written during its execution.
Syntax
2/5global_aspect_definition
::=
null
| Unspecified
| global_mode
global_designator
| (global_aspect_element
{; global_aspect_element
})
3/5global_aspect_element
::=
global_mode
global_set
| global_mode
all
| global_mode
synchronized
4/5global_mode
::=
basic_global_mode
| extended_global_mode
5/5basic_global_mode
::=
in | in out | out
6/5global_set
::=
global_name
{, global_name
}
7/5global_designator
::=
all | synchronized | global_name
8/5global_name
::=
object_name
| package_name
Name Resolution Rules
9/5A global_name
shall resolve to statically name an object or a package (including a limited view of a package).
Static Semantics
10/5For a subprogram, an entry, an access-to-subprogram type, a task unit, a protected unit, or a library package or generic library package, the following language-defined aspect may be specified with an aspect_specification
(see 13.1.1):
Global
- The Global aspect shall be specified with a
global_aspect_definition
.
- The Global aspect identifies the set of variables (which, for the purposes of this clause, includes all constants except those which are known to have no variable views (see 3.3)) that are global to a callable entity or task body, and that are read or updated as part of the execution of the callable entity or task body. If specified for a protected unit, it refers to all of the protected operations of the protected unit. Constants of any type may also be mentioned in a Global aspect.
- If not specified or otherwise defined below, the aspect defaults to the Global aspect for the enclosing library unit if the entity is declared at library level, and to Unspecified otherwise. If not specified for a library unit, the aspect defaults to Global => null for a library unit that is declared Pure, and to Global => Unspecified otherwise.
For a dispatching subprogram, the following language-defined aspect may be specified with an aspect_specification
(see 13.1.1):
Global'Class
- The Global'Class aspect shall be specified with a
global_aspect_definition
. This aspect identifies an upper bound on the set of variables global to a dispatching operation that can be read or updated as a result of a dispatching call on the operation. If not specified, the aspect defaults to the Global aspect for the dispatching subprogram.
Together, we refer to the Global and Global'Class aspects as global aspects.
A global_aspect_definition
defines the Global or Global'Class aspect of some entity. The Global aspect identifies the sets of global variables that can be read, written, or modified as a side effect of executing the operation(s) associated with the entity. The Global'Class aspect associated with a dispatching operation of type T represents a restriction on the Global aspect on a corresponding operation of any descendant of type T.
The Global aspect for a callable entity defines the global variables that can be referenced as part of a call on the entity, including any assertion expressions that apply to the call (even if not enabled), such as preconditions, postconditions, predicates, and type invariants.
The Global aspect for an access-to-subprogram object (or subtype) identifies the global variables that can be referenced when calling via the object (or any object of that subtype) including assertion expressions that apply.
For a predefined operator of an elementary type, the function representing an enumeration literal, or any other static function (see 4.9), the Global aspect is null. For a predefined operator of a composite type, the Global aspect of the operator defaults to that of the enclosing library unit (unless a Global aspect is specified for the type — see H.7).
The following is defined in terms of operations that are performed by or on behalf of an entity. The rules on operations apply to the entity(s) associated with those operations.
The global variables associated with any global_mode
can be read as a side effect of an operation. The in out and out global_mode
s together identify the set of global variables that can be updated as a side effect of an operation. Creating an access-to-variable value that designates an object is considered an update of the designated object, and creating an access-to-constant value that designates an object is considered a read of the designated object.
The overall set of objects associated with each global_mode
includes all objects identified for the mode in the global_aspect_definition
.
A global_set
identifies a global variable set as follows:
- all identifies the set of all global variables;
- synchronized identifies the set of all synchronized variables (see 9.10), as well as variables of a composite type all of whose non-discriminant subcomponents are synchronized;
global_name
{,global_name
} identifies the union of the sets of variables identified by theglobal_name
s in the list, for the following forms ofglobal_name
: 28/5- object_
name
identifies the specified global variable (or constant); 29/5 - package_
name
identifies the set of all variables declared in the private part or body of the package, or anywhere within a private descendant of the package.
Legality Rules
30/5Within a global_aspect_definition
, a given global_mode
shall be specified at most once. Similarly, within a global_aspect_definition
, a given entity shall be named at most once by a global_name
.
If an entity (other than a library package or generic library package) has a Global aspect other than Unspecified or in out all, then the associated operation(s) shall read only those variables global to the entity that are within the global variable set associated with the in, in out, or out global_mode
s, and the operation(s) shall update only those variables global to the entity that are within the global variable set associated with either the in out or out global_mode
s. In the absence of the No_Hidden_Indirect_Globals restriction (see H.4), this ignores objects reached via a dereference of an access value. The above rule includes any possible Global effects of calls occurring during the execution of the operation, except for the following excluded calls:
- calls to formal subprograms;
- calls associated with operations on formal subtypes;
- calls through formal objects of an access-to-subprogram type;
- calls through access-to-subprogram parameters;
- calls on operations with Global aspect Unspecified.
The possible Global effects of these excluded calls (other than those that are Unspecified) are taken into account by the caller of the original operation, by presuming they occur at least once during its execution. For calls that are not excluded, the possible Global effects of the call are those permitted by the Global aspect of the associated entity, or by its Global'Class aspect if a dispatching call.
If a Global aspect other than Unspecified or in out all applies to an access-to-subprogram type, then the prefix
of an Access attribute_reference
producing a value of such a type shall denote a subprogram whose Global aspect is not Unspecified and is covered by that of the result type, where a global aspect G1 is covered by a global aspect G2 if the set of variables that G1 identifies as readable or updatable is a subset of the corresponding set for G2. Similarly on a conversion to such a type, the operand shall be of a named access-to-subprogram type whose Global aspect is covered by that of the target type.
If an implementation-defined global_mode
applies to a given set of variables, an implementation-defined rule determines what sort of references to them are permitted.
For a subprogram that is a dispatching operation of a tagged type T, each mode of its Global aspect shall identify a subset of the variables identified by the corresponding mode, or by the in out mode, of the Global'Class aspect of a corresponding dispatching subprogram of any ancestor of T, unless the aspect of that ancestor is Unspecified.
Implementation Permissions
41/5An implementation can allow some references to a constant object which are not accounted for by the Global or Global'Class aspect when it is considered a variable in the above rules, if the implementation can determine that the object is in fact immutable.
Implementations may perform additional checks on calls to operations with an Unspecified Global aspect to ensure that they do not violate any limitations associated with the point of call.
Implementations may extend the syntax or semantics of the Global aspect in an implementation-defined manner[; for example, supporting additional global_mode
s].