dwww Home | Show directory contents | Find package


                               11   Exceptions


1/3 This clause defines the facilities for dealing with errors or other
exceptional situations that arise during program execution. An exception
represents a kind of exceptional situation; an occurrence of such a situation
(at run time) is called an exception occurrence. To raise an exception is to
abandon normal program execution so as to draw attention to the fact that the
corresponding situation has arisen. Performing some actions in response to the
arising of an exception is called handling the exception.

2/3 An exception_declaration declares a name for an exception. An exception
can be raised explicitly (for example, by a raise_statement) or implicitly
(for example, by the failure of a language-defined check). When an exception
arises, control can be transferred to a user-provided exception_handler at the
end of a handled_sequence_of_statements, or it can be propagated to a
dynamically enclosing execution.


11.1 Exception Declarations


1   An exception_declaration declares a name for an exception.


                                   Syntax

2/3     exception_declaration ::= defining_identifier_list : exception
           [aspect_specification];


                              Static Semantics

3   Each single exception_declaration declares a name for a different
exception. If a generic unit includes an exception_declaration, the
exception_declarations implicitly generated by different instantiations of the
generic unit refer to distinct exceptions (but all have the same
defining_identifier). The particular exception denoted by an exception name is
determined at compilation time and is the same regardless of how many times
the exception_declaration is elaborated.

4   The predefined exceptions are the ones declared in the declaration of
package Standard: Constraint_Error, Program_Error, Storage_Error, and
Tasking_Error; one of them is raised when a language-defined check fails.


                              Dynamic Semantics

5   The elaboration of an exception_declaration has no effect.

6   The execution of any construct raises Storage_Error if there is
insufficient storage for that execution. The amount of storage needed for the
execution of constructs is unspecified.


                                  Examples

7   Examples of user-defined exception declarations:

8       Singular : exception;
        Error    : exception;
        Overflow, Underflow : exception;


11.2 Exception Handlers


1   The response to one or more exceptions is specified by an
exception_handler.


                                   Syntax

2       handled_sequence_of_statements ::= 
             sequence_of_statements
          [exception
             exception_handler
            {exception_handler}]

3       exception_handler ::= 
          when [choice_parameter_specification:] exception_choice
         {| exception_choice} =>
             sequence_of_statements

4       choice_parameter_specification ::= defining_identifier

5       exception_choice ::= exception_name | others


                               Legality Rules

5.1/4 An exception_name of an exception_choice shall denote an exception.

6   A choice with an exception_name covers the named exception. A choice with
others covers all exceptions not named by previous choices of the same handled_-
sequence_of_statements. Two choices in different exception_handlers of the
same handled_sequence_of_statements shall not cover the same exception.

7   A choice with others is allowed only for the last handler of a
handled_sequence_of_statements and as the only choice of that handler.

8   An exception_name of a choice shall not denote an exception declared in a
generic formal package.


                              Static Semantics

9   A choice_parameter_specification declares a choice parameter, which is a
constant object of type Exception_Occurrence (see 11.4.1). During the handling
of an exception occurrence, the choice parameter, if any, of the handler
represents the exception occurrence that is being handled.


                              Dynamic Semantics

10  The execution of a handled_sequence_of_statements consists of the
execution of the sequence_of_statements. The optional handlers are used to
handle any exceptions that are propagated by the sequence_of_statements.


                                  Examples

11  Example of an exception handler:

12      begin
           Open(File, In_File, "input.txt");   -- see A.8.2
        exception
           when E : Name_Error =>
              Put("Cannot open input file : ");
              Put_Line(Exception_Message(E));  -- see 11.4.1
              raise;
        end;


11.3 Raise Statements and Raise Expressions


1   A raise_statement raises an exception.


                                   Syntax

2/2     raise_statement ::= raise;
              | raise exception_name [with string_expression];

2.1/4   raise_expression ::= raise exception_name
         [with string_simple_expression]

2.2/4   If a raise_expression appears within the expression of one of the
        following contexts, the raise_expression shall appear within a pair of
        parentheses within the expression:

2.3/4     * object_declaration;

2.4/4     * modular_type_definition;

2.5/4     * floating_point_definition;

2.6/4     * ordinary_fixed_point_definition;

2.7/4     * decimal_fixed_point_definition;

2.8/4     * default_expression;

2.9/4     * ancestor_part.


                               Legality Rules

3/4 The exception_name, if any, of a raise_statement or raise_expression shall
denote an exception. A raise_statement with no exception_name (that is, a
re-raise statement) shall be within a handler, but not within a body enclosed
by that handler.


                            Name Resolution Rules

3.1/4 The string_expression or string_simple_expression, if any, of a
raise_statement or raise_expression is expected to be of type String.

3.2/4 The expected type for a raise_expression shall be any single type.


                              Dynamic Semantics

4/4 To raise an exception is to raise a new occurrence of that exception, as
explained in 11.4. For the execution of a raise_statement with an
exception_name, the named exception is raised. Similarly, for the evaluation of a
raise_expression, the named exception is raised. In both of these cases, if a
string_expression or string_simple_expression is present, the expression is
evaluated and its value is associated with the exception occurrence. For the
execution of a re-raise statement, the exception occurrence that caused
transfer of control to the innermost enclosing handler is raised again.

        NOTES

4.1/4   1  If the evaluation of a string_expression or
        string_simple_expression raises an exception, that exception is propagated
        instead of the one denoted by the exception_name of the
        raise_statement or raise_expression.


                                  Examples

5   Examples of raise statements:

6/2     raise Ada.IO_Exceptions.Name_Error;   -- see A.13
        raise Queue_Error with "Buffer Full"; -- see 9.11

7       raise;                                -- re-raise the current exception


11.4 Exception Handling


1   When an exception occurrence is raised, normal program execution is
abandoned and control is transferred to an applicable exception_handler, if
any. To handle an exception occurrence is to respond to the exceptional event.
To propagate an exception occurrence is to raise it again in another context;
that is, to fail to respond to the exceptional event in the present context.


                              Dynamic Semantics

2   Within a given task, if the execution of construct a is defined by this
International Standard to consist (in part) of the execution of construct b,
then while b is executing, the execution of a is said to dynamically enclose
the execution of b. The innermost dynamically enclosing execution of a given
execution is the dynamically enclosing execution that started most recently.

3   When an exception occurrence is raised by the execution of a given
construct, the rest of the execution of that construct is abandoned; that is,
any portions of the execution that have not yet taken place are not performed.
The construct is first completed, and then left, as explained in 7.6.1. Then:

4     * If the construct is a task_body, the exception does not propagate
        further;

5     * If the construct is the sequence_of_statements of a
        handled_sequence_of_statements that has a handler with a choice
        covering the exception, the occurrence is handled by that handler;

6     * Otherwise, the occurrence is propagated to the innermost dynamically
        enclosing execution, which means that the occurrence is raised again
        in that context.

7   When an occurrence is handled by a given handler, the
choice_parameter_specification, if any, is first elaborated, which creates the
choice parameter and initializes it to the occurrence. Then, the
sequence_of_statements of the handler is executed; this execution replaces the
abandoned portion of the execution of the sequence_of_statements.

        NOTES

8       2  Note that exceptions raised in a declarative_part of a body are not
        handled by the handlers of the handled_sequence_of_statements of that
        body.


11.4.1 The Package Exceptions



                              Static Semantics

1   The following language-defined library package exists:

2/2     with Ada.Streams;
        package Ada.Exceptions is
            pragma Preelaborate(Exceptions);
            type Exception_Id is private;
            pragma Preelaborable_Initialization(Exception_Id);
            Null_Id : constant Exception_Id;
            function Exception_Name(Id : Exception_Id) return String;
            function Wide_Exception_Name
        (Id : Exception_Id) return Wide_String;
            function Wide_Wide_Exception_Name(Id : Exception_Id)
                return Wide_Wide_String;

3/2         type Exception_Occurrence is limited private;
            pragma Preelaborable_Initialization(Exception_Occurrence);
            type Exception_Occurrence_Access
         is access all Exception_Occurrence;
            Null_Occurrence : constant Exception_Occurrence;

4/3         procedure Raise_Exception(E : in Exception_Id;
                                      Message : in String := "")
                with No_Return;
            function Exception_Message
        (X : Exception_Occurrence) return String;
            procedure Reraise_Occurrence(X : in Exception_Occurrence);

5/2         function Exception_Identity(X : Exception_Occurrence)
                                        return Exception_Id;
            function Exception_Name(X : Exception_Occurrence) return String;
                -- Same as Exception_Name(Exception_Identity(X)).
            function Wide_Exception_Name(X : Exception_Occurrence)
                return Wide_String;
                -- Same as Wide_Exception_Name(Exception_Identity(X)).
            function Wide_Wide_Exception_Name(X : Exception_Occurrence)
                return Wide_Wide_String;
                -- Same as Wide_Wide_Exception_Name(Exception_Identity(X)).
            function Exception_Information
        (X : Exception_Occurrence) return String;

6/2         procedure Save_Occurrence(Target : out Exception_Occurrence;
                                      Source : in Exception_Occurrence);
            function Save_Occurrence(Source : Exception_Occurrence)
                                     return Exception_Occurrence_Access;

6.1/2       procedure Read_Exception_Occurrence
               (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                Item   : out Exception_Occurrence);
            procedure Write_Exception_Occurrence
               (Stream : not null access Ada.Streams.Root_Stream_Type'Class;
                Item   : in Exception_Occurrence);

6.2/2       for Exception_Occurrence'Read use Read_Exception_Occurrence;
            for Exception_Occurrence'Write use Write_Exception_Occurrence;

6.3/2   private
           ... -- not specified by the language
        end Ada.Exceptions;

7   Each distinct exception is represented by a distinct value of type
Exception_Id. Null_Id does not represent any exception, and is the default
initial value of type Exception_Id. Each occurrence of an exception is
represented by a value of type Exception_Occurrence. Null_Occurrence does not
represent any exception occurrence, and is the default initial value of type
Exception_Occurrence.

8/1 For a prefix E that denotes an exception, the following attribute is
defined:

9   E'Identity  E'Identity returns the unique identity of the exception. The
                type of this attribute is Exception_Id.

10/2 Raise_Exception raises a new occurrence of the identified exception.

10.1/4 Exception_Message returns the message associated with the given
Exception_Occurrence. For an occurrence raised by a call to Raise_Exception,
the message is the Message parameter passed to Raise_Exception. For the
occurrence raised by a raise_statement or raise_expression with an
exception_name and a string_expression or string_simple_expression, the message is the
string_expression or string_simple_expression. For the occurrence raised by a
raise_statement or raise_expression with an exception_name but without a
string_expression or string_simple_expression, the message is a string giving
implementation-defined information about the exception occurrence. For an
occurrence originally raised in some other manner (including by the failure of
a language-defined check), the message is an unspecified string. In all cases,
Exception_Message returns a string with lower bound 1.

10.2/2 Reraise_Occurrence reraises the specified exception occurrence.

11  Exception_Identity returns the identity of the exception of the occurrence.

12/2 The Wide_Wide_Exception_Name functions return the full expanded name of
the exception, in upper case, starting with a root library unit. For an
exception declared immediately within package Standard, the
defining_identifier is returned. The result is implementation defined if the
exception is declared within an unnamed block_statement.

12.1/2 The Exception_Name functions (respectively, Wide_Exception_Name) return
the same sequence of graphic characters as that defined for
Wide_Wide_Exception_Name, if all the graphic characters are defined in
Character (respectively, Wide_Character); otherwise, the sequence of
characters is implementation defined, but no shorter than that returned by
Wide_Wide_Exception_Name for the same value of the argument.

12.2/2 The string returned by the Exception_Name, Wide_Exception_Name, and
Wide_Wide_Exception_Name functions has lower bound 1.

13/2 Exception_Information returns implementation-defined information about
the exception occurrence. The returned string has lower bound 1.

14/2 Reraise_Occurrence has no effect in the case of Null_Occurrence.
Raise_Exception and Exception_Name raise Constraint_Error for a Null_Id.
Exception_Message, Exception_Name, and Exception_Information raise
Constraint_Error for a Null_Occurrence. Exception_Identity applied to
Null_Occurrence returns Null_Id.

15  The Save_Occurrence procedure copies the Source to the Target. The
Save_Occurrence function uses an allocator of type Exception_Occurrence_Access
to create a new object, copies the Source to this new object, and returns an
access value designating this new object; the result may be deallocated using
an instance of Unchecked_Deallocation.

15.1/2 Write_Exception_Occurrence writes a representation of an exception
occurrence to a stream; Read_Exception_Occurrence reconstructs an exception
occurrence from a stream (including one written in a different partition).

Paragraph 16 was deleted.


                         Implementation Permissions

17  An implementation of Exception_Name in a space-constrained environment may
return the defining_identifier instead of the full expanded name.

18  The string returned by Exception_Message may be truncated (to no less than
200 characters) by the Save_Occurrence procedure (not the function), the
Reraise_Occurrence procedure, and the re-raise statement.


                            Implementation Advice

19  Exception_Message (by default) and Exception_Information should produce
information useful for debugging. Exception_Message should be short (about one
line), whereas Exception_Information can be long. Exception_Message should not
include the Exception_Name. Exception_Information should include both the
Exception_Name and the Exception_Message.


11.4.2 Pragmas Assert and Assertion_Policy


1/3 Pragma Assert is used to assert the truth of a boolean expression at a
point within a sequence of declarations or statements.

1.1/3 Assert pragmas, subtype predicates (see 3.2.4), preconditions and
postconditions (see 6.1.1), and type invariants (see 7.3.2) are collectively
referred to as assertions; their boolean expressions are referred to as
assertion expressions.

1.2/3 Pragma Assertion_Policy is used to control whether assertions are to be
ignored by the implementation, checked at run time, or handled in some
implementation-defined manner.


                                   Syntax

2/2     The form of a pragma Assert is as follows:

3/2       pragma Assert([Check =>] boolean_expression[, [Message =>]
        string_expression]);

4/2     A pragma Assert is allowed at the place where a declarative_item or a
        statement is allowed.

5/2     The form of a pragma Assertion_Policy is as follows:

6/2       pragma Assertion_Policy(policy_identifier);

6.1/3     pragma Assertion_Policy(
                 assertion_aspect_mark => policy_identifier
             {, assertion_aspect_mark => policy_identifier});

7/3     A pragma Assertion_Policy is allowed only immediately within a
        declarative_part, immediately within a package_specification, or as a
        configuration pragma.


                            Name Resolution Rules

8/2 The expected type for the boolean_expression of a pragma Assert is any
boolean type. The expected type for the string_expression of a pragma Assert
is type String.


                               Legality Rules

9/3 The assertion_aspect_mark of a pragma Assertion_Policy shall be one of
Assert, Static_Predicate, Dynamic_Predicate, Pre, Pre'Class, Post, Post'Class,
Type_Invariant, Type_Invariant'Class, or some implementation defined
aspect_mark. The policy_identifier shall be either Check, Ignore, or some
implementation-defined identifier.


                              Static Semantics

10/3 A pragma Assertion_Policy determines for each assertion aspect named in
the pragma_argument_associations whether assertions of the given aspect are to
be enforced by a run-time check. The policy_identifier Check requires that
assertion expressions of the given aspect be checked that they evaluate to
True at the points specified for the given aspect; the policy_identifier
Ignore requires that the assertion expression not be evaluated at these
points, and the run-time checks not be performed. Note that for subtype
predicate aspects (see 3.2.4), even when the applicable Assertion_Policy is
Ignore, the predicate will still be evaluated as part of membership tests and
Valid attribute_references, and if static, will still have an effect on loop
iteration over the subtype, and the selection of case_statement_alternatives
and variants.

10.1/3 If no assertion_aspect_marks are specified in the pragma, the specified
policy applies to all assertion aspects.

10.2/3 A pragma Assertion_Policy applies to the named assertion aspects in a
specific region, and applies to all assertion expressions specified in that
region. A pragma Assertion_Policy 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 pragma
Assertion_Policy given as a configuration pragma is the declarative region for
the entire compilation unit (or units) to which it applies.

10.3/3 If a pragma Assertion_Policy applies to a generic_instantiation, then
the pragma Assertion_Policy applies to the entire instance.

10.4/3 If multiple Assertion_Policy pragmas apply to a given construct for a
given assertion aspect, the assertion policy is determined by the one in the
innermost enclosing region of a pragma Assertion_Policy specifying a policy
for the assertion aspect. If no such Assertion_Policy pragma exists, the
policy is implementation defined.

11/2 The following language-defined library package exists:

12/2    package Ada.Assertions is
           pragma Pure(Assertions);

13/2       Assertion_Error : exception;

14/2       procedure Assert(Check : in Boolean);
           procedure Assert(Check : in Boolean; Message : in String);

15/2    end Ada.Assertions;

16/3 A compilation unit containing a check for an assertion (including a
pragma Assert) has a semantic dependence on the Assertions library unit.

17/3 This paragraph was deleted.


                              Dynamic Semantics

18/3 If performing checks is required by the Assert assertion policy in effect
at the place of a pragma Assert, the elaboration of the pragma consists of
evaluating the boolean expression, and if the result is False, evaluating the
Message argument, if any, and raising the exception
Assertions.Assertion_Error, with a message if the Message argument is provided.

19/2 Calling the procedure Assertions.Assert without a Message parameter is
equivalent to:

20/2    if Check = False then
           raise Ada.Assertions.Assertion_Error;
        end if;

21/2 Calling the procedure Assertions.Assert with a Message parameter is
equivalent to:

22/2    if Check = False then
           raise Ada.Assertions.Assertion_Error with Message;
        end if;

23/2 The procedures Assertions.Assert have these effects independently of the
assertion policy in effect.


                          Bounded (Run-Time) Errors

23.1/3 It is a bounded error to invoke a potentially blocking operation (see
9.5.1) during the evaluation of an assertion expression associated with a call
on, or return from, a protected operation. If the bounded error is detected,
Program_Error is raised. If not detected, execution proceeds normally, but if
it is invoked within a protected action, it might result in deadlock or a
(nested) protected action.


                         Implementation Permissions

24/2 Assertion_Error may be declared by renaming an implementation-defined
exception from another package.

25/2 Implementations may define their own assertion policies.

26/3 If the result of a function call in an assertion is not needed to
determine the value of the assertion expression, an implementation is
permitted to omit the function call. This permission applies even if the
function has side effects.

27/3 An implementation need not allow the specification of an assertion
expression if the evaluation of the expression has a side effect such that an
immediate reevaluation of the expression could produce a different value.
Similarly, an implementation need not allow the specification of an assertion
expression that is checked as part of a call on or return from a callable
entity C, if the evaluation of the expression has a side effect such that the
evaluation of some other assertion expression associated with the same call of
(or return from) C could produce a different value than it would if the first
expression had not been evaluated.

        NOTES

28/2    3  Normally, the boolean expression in a pragma Assert should not call
        functions that have significant side effects when the result of the
        expression is True, so that the particular assertion policy in effect
        will not affect normal operation of the program.


11.4.3 Example of Exception Handling



                                  Examples

1   Exception handling may be used to separate the detection of an error from
the response to that error:

2/2     package File_System is
            type File_Handle is limited private;

3           File_Not_Found : exception;
            procedure Open(F : in out File_Handle; Name : String);
                -- raises File_Not_Found if named file does not exist

4           End_Of_File : exception;
            procedure Read(F : in out File_Handle; Data : out Data_Type);
                -- raises End_Of_File if the file is not open

5           ...
        end File_System;

6/2     package body File_System is
            procedure Open(F : in out File_Handle; Name : String) is
            begin
                if File_Exists(Name) then
                    ...
                else
                    raise File_Not_Found with "File not found: " & Name & ".";
                end if;
            end Open;

7           procedure Read(F : in out File_Handle; Data : out Data_Type) is
            begin
                if F.Current_Position <= F.Last_Position then
                    ...
                else
                    raise End_Of_File;
                end if;
            end Read;

8           ...

9       end File_System;

10      with Ada.Text_IO;
        with Ada.Exceptions;
        with File_System; use File_System;
        use Ada;
        procedure Main is
        begin
            ... -- call operations in File_System
        exception
            when End_Of_File =>
                Close(Some_File);
            when Not_Found_Error : File_Not_Found =>
                Text_IO.Put_Line(Exceptions.Exception_Message(Not_Found_Error));
            when The_Error : others =>
                Text_IO.Put_Line("Unknown error:");
                if Verbosity_Desired then
                    Text_IO.Put_Line(Exceptions.Exception_Information(The_Error));
                else
                    Text_IO.Put_Line(Exceptions.Exception_Name(The_Error));
                    Text_IO.Put_Line(Exceptions.Exception_Message(The_Error));
                end if;
                raise;
        end Main;

11  In the above example, the File_System package contains information about
detecting certain exceptional situations, but it does not specify how to
handle those situations. Procedure Main specifies how to handle them; other
clients of File_System might have different handlers, even though the
exceptional situations arise from the same basic causes.


11.5 Suppressing Checks


1/2 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..

2/3 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.


                                   Syntax

3/2     The forms of checking pragmas are as follows:

4/2       pragma Suppress(identifier);

4.1/2     pragma Unsuppress(identifier);

5/2     A checking pragma is allowed only immediately within a
        declarative_part, immediately within a package_specification, or as a
        configuration pragma.


                               Legality Rules

6/2 The identifier shall be the name of a check.

7/2 This paragraph was deleted.


                              Static Semantics

7.1/2 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.

7.2/3 If a checking pragma applies to a generic_instantiation, then the
checking pragma also applies to the entire instance.

8/2 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.

8.1/2 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.

9   The following are the language-defined checks:

10    * The following checks correspond to situations in which the exception
        Constraint_Error is raised upon failure.

11/2    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.

12      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/2    Division_Check
                Check that the second operand is not zero for the operations
                /, rem and mod.

14      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
                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
                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
                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
                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    * The following checks correspond to situations in which the exception
        Program_Error is raised upon failure.

19.1/2  Accessibility_Check
                Check the accessibility level of an entity or view.

19.2/2  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.

20      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/2            This paragraph was deleted.

22    * The following check corresponds to situations in which the exception
        Storage_Error is raised upon failure.

23      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.

24    * The following check corresponds to all situations in which any
        predefined exception is raised.

25/3    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.


                             Erroneous Execution

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


                         Implementation Permissions

27/2 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.

27.1/2 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

28  The implementation should minimize the code executed for checks that have
been suppressed.

        NOTES

29      4  There is no guarantee that a suppressed check is actually removed;
        hence a pragma Suppress should be used only for efficiency reasons.

29.1/2  5  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

30/2 Examples of suppressing and unsuppressing checks:

31/2    pragma Suppress(Index_Check);
        pragma Unsuppress(Overflow_Check);


11.6 Exceptions and Optimization


1/3 This subclause gives permission to the implementation to perform certain
"optimizations" that do not necessarily preserve the canonical semantics.


                              Dynamic Semantics

2/3 The rest of this International Standard (outside this subclause) defines
the canonical semantics of the language. The canonical semantics of a given
(legal) program determines a set of possible external effects that can result
from the execution of the program with given inputs.

3/3 As explained in 1.1.3, "
Conformity of an Implementation with the Standard", the external effect of a
program is defined in terms of its interactions with its external environment.
Hence, the implementation can perform any internal actions whatsoever, in any
order or in parallel, so long as the external effect of the execution of the
program is one that is allowed by the canonical semantics, or by the rules of
this subclause.


                         Implementation Permissions

4   The following additional permissions are granted to the implementation:

5     * An implementation need not always raise an exception when a
        language-defined check fails. Instead, the operation that failed the
        check can simply yield an undefined result. The exception need be
        raised by the implementation only if, in the absence of raising it,
        the value of this undefined result would have some effect on the
        external interactions of the program. In determining this, the
        implementation shall not presume that an undefined result has a value
        that belongs to its subtype, nor even to the base range of its type,
        if scalar. Having removed the raise of the exception, the canonical
        semantics will in general allow the implementation to omit the code
        for the check, and some or all of the operation itself.

6/3   * If an exception is raised due to the failure of a language-defined
        check, then upon reaching the corresponding exception_handler (or the
        termination of the task, if none), the external interactions that have
        occurred need reflect only that the exception was raised somewhere
        within the execution of the sequence_of_statements with the handler
        (or the task_body), possibly earlier (or later if the interactions are
        independent of the result of the checked operation) than that defined
        by the canonical semantics, but not within the execution of some
        abort-deferred operation or independent subprogram that does not
        dynamically enclose the execution of the construct whose check failed.
        An independent subprogram is one that is defined outside the library
        unit containing the construct whose check failed, and for which the
        Inline aspect is False. Any assignment that occurred outside of such
        abort-deferred operations or independent subprograms can be disrupted
        by the raising of the exception, causing the object or its parts to
        become abnormal, and certain subsequent uses of the object to be
        erroneous, as explained in 13.9.1.

        NOTES

7/3     6  The permissions granted by this subclause can have an effect on the
        semantics of a program only if the program fails a language-defined
        check.

Generated by dwww version 1.15 on Tue Jun 25 08:58:05 CEST 2024.