Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

11.5 Suppressing Checks

{AI95-00224-01} 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..
{AI05-0264-1} 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. A check fails when the condition being checked is False, causing an exception to be raised. 
Discussion: All such checks are defined under “Dynamic Semantics” in clauses and subclauses throughout the standard. 


{AI95-00224-01} The forms of checking pragmas are as follows: 
{AI95-00224-01}   pragma Suppress(identifier);
{AI95-00224-01}   pragma Unsuppress(identifier);
{AI95-00224-01} A checking pragma is allowed only immediately within a declarative_part, immediately within a package_specification, or as a configuration pragma. 

Legality Rules

{AI95-00224-01} The identifier shall be the name of a check. 
This paragraph was deleted.{AI95-00224-01}

Static Semantics

  {AI95-00224-01} 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.
  {AI95-00224-01} {AI05-0229-1} {AI05-0290-1} If a checking pragma applies to a generic_instantiation, then the checking pragma also applies to the entire instance. 
Ramification: {AI05-0290-1} This means that a Suppress pragma that occurs in a scope enclosing the declaration of a generic unit but not also enclosing the declaration of a given instance of that generic unit will not apply to constructs within the given instance. 
{AI95-00224-01} 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
Ramification: A check is suppressed even if the implementation chooses not to actually generate better code. This allows the implementation to raise Program_Error, for example, if the erroneousness is detected. 
  {AI95-00224-01} 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.]
{8652/0036} {AI95-00176-01} {AI95-00231-01} Access_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.]
{AI95-00434-01} Division_Check 

[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.]

[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.]
{AI95-00280} Accessibility_Check 

[Check the accessibility level of an entity or view.]
{AI95-00280} Allocation_Check 

[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.]
This paragraph was deleted.{AI95-00280}
[The following check corresponds to situations in which the exception Storage_Error is raised upon failure.] 

[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.]
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. 
[The following check corresponds to all situations in which any predefined exception is raised.]
{AI05-0290-1} All_Checks 

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.
Ramification: All_Checks includes both language-defined and implementation-defined checks. 
To be honest: {AI05-0005-1} There are additional checks defined in various Specialized Needs Annexes that are not listed here. Nevertheless, they are included in All_Checks and named in a Suppress pragma on implementations that support the relevant annex. Look up “check, language-defined” in the index to find the complete list. 
Discussion: {AI05-0290-1} We don't want to say that assertions are suppressed, because we don't want the potential failure of an assertion to cause erroneous execution (see below). Thus they are excluded from the suppression part of the above rule and then handled with an implicit Ignore policy. 

Erroneous Execution

If a given check has been suppressed, and the corresponding error situation occurs, the execution of the program is erroneous. 

Implementation Permissions

 {AI95-00224-01} 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. 
This paragraph was deleted.{AI95-00224-01}
Implementation defined: Implementation-defined check names.
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). 
   {AI95-00224-01} 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 defined: Existence and meaning of second parameter of pragma Unsuppress.

Implementation Advice

The implementation should minimize the code executed for checks that have been suppressed. 
Implementation Advice: Code executed for checks that have been suppressed should be minimized.
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. 
4  There is no guarantee that a suppressed check is actually removed; hence a pragma Suppress should be used only for efficiency reasons.
5  {AI95-00224-01} 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. 


 {AI95-00224-01} Examples of suppressing and unsuppressing checks: 
{AI95-00224-01} pragma Suppress(Index_Check);
pragma Unsuppress(Overflow_Check);

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.
Additional check names are added. We allow implementations to define their own checks. 

Wording Changes from Ada 83

We define the checks in a distributed manner. Therefore, the long list of what checks apply to what is merely a NOTE.
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.
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 nonuniformity in this case is not harmful, and removing it would have a serious impact on optimizers.
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. 

Extensions to Ada 95

{AI95-00224-01} Pragma Unsuppress is new.
{AI95-00280-01} Allocation_Check was added to support suppressing the new check on allocators (see 4.8). 

Wording Changes from Ada 95

{8652/0036} {AI95-00176-01} {AI95-00224-01} The description of Access_Check was corrected by the Corrigendum to include the discriminant case. This change was then replaced by the more general notion of checking conversions to subtypes that exclude null in Ada 2005.
{AI95-00224-01} The On parameter of pragma Suppress was moved to Annex J (see J.10). This feature's effect is inherently nonportable, depending on the implementation's model of computation. Compiler surveys demonstrated this, showing that implementations vary widely in the interpretation of these parameters, even on the same target. While this is relatively harmless for Suppress (which is never required to do anything), it would be a significant problem for Unsuppress (we want the checks to be made for all implementations). By moving it, we avoid needing to define the meaning of Unsuppress with an On parameter.
{AI95-00280-01} The order of the Program_Error checks was corrected to be alphabetical.

Wording Changes from Ada 2005

{AI05-0290-1} {AI12-0005-1} The effect of a checking pragma no longer applies inside an inlined subprogram body. While this could change the behavior of a program that depends on a check being suppressed in an inlined body, such a program is erroneous and thus no behavior can be depended upon anyway. It's also likely to be very rare. We make this change so that inlining has no effect on the meaning of the subprogram body (since inlining is never required requiring, this is necessary in order to be able to reason about the body), and so that assertion policies and suppress work the same way for inlining.

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe