11.5 Suppressing Checks
Checking pragmas give
instructions to an implementation on handling language-defined checks.
A
pragma Suppress
gives permission to an implementation to omit certain language-defined
checks, while a
pragma
Unsuppress revokes the permission to omit checks.
A
language-defined check (or simply, a “check”) is one
of the situations defined by this document that requires a check to be
made at run time to determine whether some condition is true.
A
check
fails when the condition being checked is False, causing
an exception to be raised.
Syntax
The forms of checking
pragmas are as follows:
Legality Rules
This paragraph was
deleted.
Static Semantics
A checking pragma applies to the named check in
a specific region, and applies to all entities in that region. A checking
pragma given in a
declarative_part
or immediately within a
package_specification
applies from the place of the
pragma
to the end of the innermost enclosing declarative region. The region
for a checking pragma given as a configuration pragma is the declarative
region for the entire compilation unit (or units) to which it applies.
If a checking pragma applies to a
generic_instantiation,
then the checking pragma also applies to the entire instance.
A
pragma
Suppress gives permission to an implementation to omit the named check
(or every check in the case of All_Checks) for any entities to which
it applies.
If permission has been given to suppress
a given check, the check is said to be
suppressed.
A
pragma
Unsuppress revokes the permission to omit the named check (or every check
in the case of All_Checks) given by any
pragma
Suppress that applies at the point of the
pragma
Unsuppress. The permission is revoked for the region to which the
pragma
Unsuppress applies. If there is no such permission at the point of a
pragma Unsuppress,
then the
pragma
has no effect. A later
pragma
Suppress can renew the permission.
The following are the
language-defined checks:
The following checks correspond
to situations in which the exception Constraint_Error is raised upon
failure of a language-defined check.
When evaluating a dereference (explicit or implicit), check that the
value of the
name
is not
null. When converting to a subtype that excludes null,
check that the converted value is not
null.
Check that the discriminants of a composite value have the values imposed
by a discriminant constraint. Also, when accessing a record component,
check that it exists for the current discriminant values.
Check that the second operand is not zero for the operations /, rem
and mod.
Check that the bounds of an array value are equal to the corresponding
bounds of an index constraint. Also, when accessing a component of an
array object, check for each dimension that the given index value belongs
to the range defined by the bounds of the array object. Also, when accessing
a slice of an array object, check that the given discrete range is compatible
with the range defined by the bounds of the array object.
Check that two arrays have matching components, in the case of array
subtype conversions, and logical operators for arrays of boolean components.
Check that a scalar value is within the base range of its type, in cases
where the implementation chooses to raise an exception instead of returning
the correct mathematical result.
Check that a scalar value satisfies a range constraint. Also, for the
elaboration of a
subtype_indication,
check that the
constraint
(if present) is compatible with the subtype denoted by the
subtype_mark.
Also, for an
aggregate,
check that an index or discriminant value belongs to the corresponding
subtype. Also, check that when the result of an operation yields an array,
the value of each component belongs to the component subtype. Also, for
the attributes Value, Wide_Value, and Wide_Wide_Value, check that the
given string has the appropriate syntax and value for the base subtype
of the
prefix
of the
attribute_reference.
Check that operand tags in a dispatching call are all equal. Check for
the correct tag on tagged type conversions, for an
assignment_statement,
and when returning a tagged limited object from a function.
The following checks correspond
to situations in which the exception Program_Error is raised upon failure
of a language-defined check.
Check the accessibility level of an entity or view.
For an
allocator,
check that the master of any tasks to be created by the
allocator
is not yet completed or some dependents have not yet terminated, and
that the finalization of the collection has not started.
When a subprogram or protected entry is called, a task activation is
accomplished, or a generic instantiation is elaborated, check that the
body of the corresponding unit has already been elaborated.
Other language-defined checks that raise Program_Error: that subtypes
with predicates are not used to index an array in a generic unit; that
the maximum number of chunks is greater than zero; that the default value
of an out parameter is convertible; that there is no misuse of functions
in a generic with a class-wide actual type; that there are not colliding
External_Tag values; that there is no misuse of operations of unchecked
union types.
The following check
corresponds to situations in which the exception Storage_Error is raised
upon failure of a language-defined check.
Check that evaluation of an
allocator
does not require more space than is available for a storage pool. Check
that the space available for a task or subprogram has not been exceeded.
The following check
corresponds to situations in which the exception Tasking_Error is raised
upon failure of a language-defined check.
Check that all tasks activated successfully. Check that a called task
has not yet terminated.
The following checks
correspond to situations in which the exception Assertion_Error is raised
upon failure of a language-defined check.
For a language-defined
unit
U associated with one of these checks in the list below,
the check refers to performance of checks associated with the Pre, Static_Predicate,
and Dynamic_Predicate aspects associated with any entity declared in
a descendant of
U, or in an instance of a generic unit which is,
or is declared in, a descendant of
U. Each check is associated
with one or more units:
Calendar.
Characters_Assertion_Check
Characters, Wide_Characters, and Wide_Wide_Characters.
Containers_Assertion_Check
Containers.
Interfaces_Assertion_Check
Interfaces.
Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, Storage_IO,
Streams.Stream_IO, and Directories.
Numerics.
Strings.
System.
The following check
corresponds to all situations in which any predefined exception is raised
upon failure of a check.
Represents the union of all checks; suppressing All_Checks suppresses
all checks other than those associated with assertions. In addition,
an implementation is allowed (but not required) to behave as if a pragma
Assertion_Policy(Ignore) applies to any region to which pragma Suppress(All_Checks)
applies.
Erroneous Execution
If a given check has been suppressed,
and the corresponding error situation occurs, the execution of the program
is erroneous. Similarly, if a precondition check has been suppressed
and the evaluation of the precondition would have raised an exception,
execution is erroneous.
Implementation Permissions
An implementation is allowed to place restrictions
on checking pragmas, subject only to the requirement that
pragma
Unsuppress shall allow any check names supported by
pragma
Suppress. An implementation is allowed to add additional check names,
with implementation-defined semantics.
When Overflow_Check
has been suppressed, an implementation may also suppress an unspecified
subset of the Range_Checks.
An implementation may support an additional parameter
on
pragma
Unsuppress similar to the one allowed for
pragma
Suppress (see
J.10). The meaning of such a
parameter is implementation-defined.
Implementation Advice
The implementation should minimize the code executed
for checks that have been suppressed.
NOTE 1
There
is no guarantee that a suppressed check is actually removed; hence a
pragma Suppress
is useful only to improve efficiency.
NOTE 2 It is possible to give both
a
pragma Suppress
and Unsuppress for the same check immediately within the same
declarative_part.
In that case, the last
pragma
given determines whether or not the check is suppressed. Similarly, it
is possible to resuppress a check which has been unsuppressed by giving
a
pragma Suppress
in an inner declarative region.
Examples
Examples of suppressing
and unsuppressing checks:
pragma Suppress(Index_Check);
pragma Unsuppress(Overflow_Check);
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe