Contents Index Previous Next
11.5 Suppressing Checks
1
A pragma
Suppress gives permission to an implementation to omit certain language-defined
checks.
2
{language-defined check}
{check (language-defined)}
{run-time check: See language-defined
check} {run-time error}
{error (run-time)} A
language-defined check (or simply, a ``check'') is one of the
situations defined by this International Standard that requires a check
to be made at run time to determine whether some condition is true.
{failure
(of a language-defined check)} A check
fails when the condition being checked is false, causing an exception
to be raised.
2.a
Discussion: All such checks
are defined under ``Dynamic Semantics'' in clauses and subclauses throughout
the standard.
Syntax
3
The form of
a pragma Suppress is as follows:
4
pragma Suppress(
identifier
[, [On =>]
name]);
5
{configuration pragma (Suppress)
[partial]} {pragma, configuration
(Suppress) [partial]} A
pragma
Suppress is allowed only immediately within a
declarative_part,
immediately within a
package_specification,
or as a configuration pragma.
Legality Rules
6
The identifier
shall be the name of a check. The name
(if present) shall statically denote some entity.
7
For a pragma
Suppress that is immediately within a package_specification
and includes a name, the name
shall denote an entity (or several overloaded subprograms) declared immediately
within the package_specification.
Static Semantics
8
A
pragma
Suppress gives permission to an implementation to omit the named check
from the place of the
pragma to
the end of the innermost enclosing declarative region, or, if the
pragma
is given in a
package_specification
and includes a
name, to the end
of the scope of the named entity. If the
pragma
includes a
name, the permission
applies only to checks performed on the named entity, or, for a subtype,
on objects and values of its type. Otherwise, the permission applies
to all entities.
{suppressed check} If
permission has been given to suppress a given check, the check is said
to be
suppressed.
8.a
Ramification: A check is
suppressed even if the implementation chooses not to actually generate
better code. {Program_Error (raised by failure of run-time check)}
This allows the implementation to raise Program_Error,
for example, if the erroneousness is detected.
9
The following are
the language-defined checks:
10
- {Constraint_Error (raised by failure of
run-time check)} [The following checks
correspond to situations in which the exception Constraint_Error is raised
upon failure.]
11/1
- {8652/0036} {Access_Check
[distributed]} Access_Check
-
[When evaluating a dereference (explicit or implicit), check that the
value of the name is not null.
When passing an actual parameter to a formal access parameter, check
that the value of the actual parameter is not null. When evaluating
a discriminant_association for an
access discriminant, check that the value of the discriminant is not
null.]
12
- {Discriminant_Check [distributed]} Discriminant_Check
-
[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.]
13
- {Division_Check [distributed]} Division_Check
-
[Check that the second operand is not zero for the operations /, rem
and mod.]
14
- {Index_Check [distributed]} Index_Check
-
[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.]
15
- {Length_Check [distributed]} Length_Check
-
[Check that two arrays have matching components, in the case of array
subtype conversions, and logical operators for arrays of boolean components.]
16
- {Overflow_Check [distributed]} Overflow_Check
-
[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.]
17
- {Range_Check [distributed]} Range_Check
-
[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.]
18
- {Tag_Check [distributed]} Tag_Check
-
[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.]
19
- {Program_Error (raised by failure of run-time
check)} [The following checks correspond
to situations in which the exception Program_Error is raised upon failure.]
20
- {Elaboration_Check [distributed]} Elaboration_Check
-
[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.]
21
- {Accessibility_Check [distributed]} Accessibility_Check
-
[Check the accessibility level of an entity or view.]
22
- [The following check corresponds to situations in which
the exception Storage_Error is raised upon failure.]
23
- {Storage_Check [distributed]} {Storage_Error
(raised by failure of run-time check)} Storage_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.]
23.a
Reason: We considered splitting
this out into three categories: Pool_Check (for allocators),
Stack_Check (for stack usage), and Heap_Check (for implicit use of the
heap -- use of the heap other than through an allocator).
Storage_Check would then represent the union of these three. However,
there seems to be no compelling reason to do this, given that it is not
feasible to split Storage_Error.
24
- [The following check corresponds to all situations in which
any predefined exception is raised.]
25
- {All_Checks [distributed]} All_Checks
-
Represents the union of all checks; [suppressing All_Checks suppresses
all checks.]
25.a
Ramification: All_Checks
includes both language-defined and implementation-defined checks.
Erroneous Execution
26
{erroneous execution (cause)
[partial]} If a given check has been suppressed,
and the corresponding error situation occurs, the execution of the program
is erroneous.
Implementation Permissions
27
An implementation is allowed to place restrictions
on Suppress
pragmas. An implementation
is allowed to add additional check names, with implementation-defined
semantics.
{unspecified [partial]} When
Overflow_Check has been suppressed, an implementation may also suppress
an unspecified subset of the Range_Checks.
27.a
Reason: The permission
to restrict is given so the implementation can give an error message
when the requested suppression is nonsense, such as suppressing a Range_Check
on a task type. It would be verbose and pointless to list all the cases
of nonsensical language-defined checks in the standard, and since the
list of checks is open-ended, we can't list the restrictions for implementation-defined
checks anyway.
27.b
Implementation defined: Implementation-defined
check names.
27.c
Discussion: For Overflow_Check,
the intention is that the implementation will suppress any Range_Checks
that are implemented in the same manner as Overflow_Checks (unless they
are free).
Implementation Advice
28
The implementation should minimize the code executed
for checks that have been suppressed.
28.a
Implementation Note: However,
if a given check comes for free (for example, the hardware automatically
performs the check in parallel with doing useful work) or nearly free
(for example, the check is a tiny portion of an expensive run-time system
call), the implementation should not bother to suppress the check. Similarly,
if the implementation detects the failure at compile time and provides
a warning message, there is no need to actually suppress the check.
29
2 {optimization}
{efficiency} There
is no guarantee that a suppressed check is actually removed; hence a
pragma Suppress should be used only
for efficiency reasons.
Examples
30
Examples of
suppressing checks:
31
pragma Suppress(Range_Check);
pragma Suppress(Index_Check, On => Table);
Extensions to Ada 83
31.a
{extensions to Ada 83}
A pragma Suppress
is allowed as a configuration pragma. A pragma
Suppress without a name is allowed
in a package_specification.
31.b
Additional check names are added.
We allow implementations to define their own checks.
Wording Changes from Ada 83
31.c
We define the checks in a distributed
manner. Therefore, the long list of what checks apply to what is merely
a NOTE.
31.d
We have removed the detailed rules
about what is allowed in a pragma
Suppress, and allow implementations to invent their own. The RM83 rules
weren't quite right, and such a change is necessary anyway in the presence
of implementation-defined checks.
31.e
We make it clear that the difference
between a Range_Check and an Overflow_Check is fuzzy. This was true in
Ada 83, given RM83-11.6, but it was not clear. We considered removing
Overflow_Check from the language or making it obsolescent, just as we
did for Numeric_Error. However, we kept it for upward compatibility,
and because it may be useful on machines where range checking costs more
than overflow checking, but overflow checking still costs something.
Different compilers will suppress different checks when asked to suppress
Overflow_Check -- the non-uniformity in this case is not harmful, and
removing it would have a serious impact on optimizers.
31.f
Under Access_Check, dereferences
cover the cases of selected_component,
indexed_component, slice,
and attribute that are listed in
RM83, as well as the new explicit_dereference,
which was included in selected_component
in RM83.
Contents Index Previous Next Legal