6.1.1 Preconditions and Postconditions
For a noninstance subprogram, 
a generic subprogram, or an entry, the following language-defined aspects 
may be specified with an 
aspect_specification 
(see 
13.1.1):
Pre
This aspect specifies a specific precondition for a callable entity; 
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 an 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; 
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 an 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
The 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) 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) 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 
names 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 shall resolve 
to a given type, the same applies to the 
prefix; 
otherwise, the 
prefix 
shall be resolved independently of context.
Legality Rules
The 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
 If 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. 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).
   The primitive subprogram S is illegal if 
it is not abstract and the corresponding expression for a Pre'Class or 
Post'Class aspect would be illegal.
 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 or entry, then the respective precondition or postcondition 
expressions are considered 
enabled.
 An 
expression 
is 
potentially unevaluated if it occurs within:
the right operand of a short-circuit control form; 
or
 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 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:
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 nominal subtype of X'Old is as implied 
by the above definitions. The expected type of the prefix of an Old attribute 
is that of the attribute. Similarly, if an Old attribute shall resolve 
to be of some type, then the prefix of the attribute shall resolve to 
be of that type.
Reference to this attribute is only allowed 
within a postcondition expression. The 
prefix 
of an Old 
attribute_reference 
shall not contain a Result 
attribute_reference, 
nor an Old 
attribute_reference, 
nor a use of an entity declared within the postcondition expression but 
not within 
prefix 
itself (for example, the loop parameter of an enclosing 
quantified_expression). 
The 
prefix 
of an Old 
attribute_reference 
that is potentially unevaluated shall statically denote an entity.
 For a 
prefix 
F that denotes a function declaration, the following attribute is defined: 
 F'Result
Within a postcondition expression 
for function F, denotes the result object of the function. The type of 
this attribute is that of the function result except within a Post'Class 
postcondition expression for a function with a controlling result or 
with a controlling access result. For a controlling result, the type 
of the attribute is 
T'Class, where 
T is the function result 
type. For a controlling access result, the type of the attribute is an 
anonymous access type whose designated type is 
T'Class, where 
T is the designated type of the function result type.
 
Use of this attribute is allowed only within 
a postcondition expression for F. 
Dynamic Semantics
 Upon 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. 
It is not specified whether in a call on a protected operation, the checks 
are performed before or after 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_references 
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 a call via an access-to-subprogram value, all 
precondition and postcondition checks performed are determined by the 
subprogram or entry denoted by the prefix of the Access attribute reference 
that produced the value. 
5  A precondition is checked just before 
the call. If another task can change any value that the precondition 
expression depends on, the precondition need not hold within the subprogram 
or entry body. 
 Ada 2005 and 2012 Editions sponsored in part by Ada-Europe
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe