

                               5   Statements


1   A statement defines an action to be performed upon its execution.

2/3 This clause describes the general rules applicable to all statements. Some
statements are discussed in later clauses: Procedure_call_statements and
return statements are described in 6, "Subprograms". Entry_call_statements,
requeue_statements, delay_statements, accept_statements, select_statements,
and abort_statements are described in 9, "Tasks and Synchronization". Raise_-
statements are described in 11, "Exceptions", and code_statements in 13. The
remaining forms of statements are presented in this clause.


5.1 Simple and Compound Statements - Sequences of Statements


1/5 A statement is either simple or compound. A simple_statement encloses no
other statement. A compound_statement can enclose simple_statements and other
compound_statements. A parallel construct is a construct that introduces
additional logical threads of control (see clause 9) without creating a new
task. Parallel loops (see 5.5) and parallel_block_statements (see 5.6.1) are
parallel constructs.


                                   Syntax

2/3     sequence_of_statements ::= statement {statement} {label}

3       statement ::= 
           {label} simple_statement | {label} compound_statement

4/2     simple_statement ::= null_statement
           | assignment_statement            | exit_statement
           | goto_statement                  | procedure_call_statement
           | simple_return_statement         | entry_call_statement
           | requeue_statement               | delay_statement
           | abort_statement                 | raise_statement
           | code_statement

5/5     compound_statement ::= 
             if_statement                    | case_statement
           | loop_statement                  | block_statement
           | extended_return_statement
           | parallel_block_statement
           | accept_statement                | select_statement

6       null_statement ::= null;

7       label ::= <<label_statement_identifier>>

8       statement_identifier ::= direct_name

9       The direct_name of a statement_identifier shall be an identifier (not
        an operator_symbol).


                            Name Resolution Rules

10  The direct_name of a statement_identifier shall resolve to denote its
corresponding implicit declaration (see below).


                               Legality Rules

11  Distinct identifiers shall be used for all statement_identifiers that
appear in the same body, including inner block_statements but excluding inner
program units.


                              Static Semantics

12  For each statement_identifier, there is an implicit declaration (with the
specified identifier) at the end of the declarative_part of the innermost
block_statement or body that encloses the statement_identifier. The implicit
declarations occur in the same order as the statement_identifiers occur in the
source text. If a usage name denotes such an implicit declaration, the entity
it denotes is the label, loop_statement, or block_statement with the given
statement_identifier.

12.1/3 If one or more labels end a sequence_of_statements, an implicit
null_statement follows the labels before any following constructs.


                              Dynamic Semantics

13  The execution of a null_statement has no effect.

14/2 A transfer of control is the run-time action of an exit_statement, return
statement, goto_statement, or requeue_statement, selection of a
terminate_alternative, raising of an exception, or an abort, which causes the
next action performed to be one other than what would normally be expected
from the other rules of the language. As explained in 7.6.1, a transfer of
control can cause the execution of constructs to be completed and then left,
which may trigger finalization.

15  The execution of a sequence_of_statements consists of the execution of the
individual statements in succession until the sequence_ is completed.

16/5 Within a parallel construct, if a transfer of control out of the
construct is initiated by one of the logical threads of control, an attempt is
made to cancel all other logical threads of control initiated by the parallel
construct. Once all other logical threads of control of the construct either
complete or are canceled, the transfer of control occurs. If two or more
logical threads of control of the same construct initiate such a transfer of
control concurrently, one of them is chosen arbitrarily and the others are
canceled.

17/5 When a logical thread of control is canceled, the cancellation causes it
to complete as though it had performed a transfer of control to the point
where it would have finished its execution. Such a cancellation is deferred
while the logical thread of control is executing within an abort-deferred
operation (see 9.8), and may be deferred further, but not past a point where
the logical thread initiates a new nested parallel construct or reaches an
exception handler that is outside such an abort-deferred operation.


                          Bounded (Run-Time) Errors

18/5 During the execution of a parallel construct, it is a bounded error to
invoke an operation that is potentially blocking (see 9.5). Program_Error is
raised if the error is detected by the implementation; otherwise, the
execution of the potentially blocking operation might proceed normally, or it
might result in the indefinite blocking of some or all of the logical threads
of control making up the current task.

        NOTES

19      1  A statement_identifier that appears immediately within the
        declarative region of a named loop_statement or an accept_statement is
        nevertheless implicitly declared immediately within the declarative
        region of the innermost enclosing body or block_statement; in other
        words, the expanded name for a named statement is not affected by
        whether the statement occurs inside or outside a named loop or an
        accept_statement - only nesting within block_statements is relevant to
        the form of its expanded name.


                                  Examples

20  Examples of labeled statements:

21      <<Here>> <<Ici>> <<Aqui>> <<Hier>> null;

22      <<After>> X := 1;


5.2 Assignment Statements


1   An assignment_statement replaces the current value of a variable with the
result of evaluating an expression.


                                   Syntax

2       assignment_statement ::= 
           variable_name := expression;

3   The execution of an assignment_statement includes the evaluation of the
expression and the assignment of the value of the expression into the target.
An assignment operation (as opposed to an assignment_statement) is performed
in other contexts as well, including object initialization and by-copy
parameter passing. The target of an assignment operation is the view of the
object to which a value is being assigned; the target of an assignment_-
statement is the variable denoted by the variable_name.


                            Name Resolution Rules

4/2 The variable_name of an assignment_statement is expected to be of any
type. The expected type for the expression is the type of the target.


                               Legality Rules

5/2 The target denoted by the variable_name shall be a variable of a
nonlimited type.

6   If the target is of a tagged class-wide type T'Class, then the
expression shall either be dynamically tagged, or of type T and
tag-indeterminate (see 3.9.2).


                              Dynamic Semantics

7   For the execution of an assignment_statement, the variable_name and the
expression are first evaluated in an arbitrary order.

8   When the type of the target is class-wide:

9     * If the expression is tag-indeterminate (see 3.9.2), then the
        controlling tag value for the expression is the tag of the target;

10    * Otherwise (the expression is dynamically tagged), a check is made that
        the tag of the value of the expression is the same as that of the
        target; if this check fails, Constraint_Error is raised.

11  The value of the expression is converted to the subtype of the target. The
conversion might raise an exception (see 4.6).

12  In cases involving controlled types, the target is finalized, and an
anonymous object might be used as an intermediate in the assignment, as
described in 7.6.1, "Completion and Finalization". In any case, the converted
value of the expression is then assigned to the target, which consists of the
following two steps:

13    * The value of the target becomes the converted value.

14/3   * If any part of the target is controlled, its value is adjusted as
        explained in subclause 7.6.

        NOTES

15      2  The tag of an object never changes; in particular, an
        assignment_statement does not change the tag of the target.

16/2    This paragraph was deleted.


                                  Examples

17  Examples of assignment statements:

18      Value := Max_Value - 1;
        Shade := Blue;

19      Next_Frame(F)(M, N) := 2.5;        --  see 4.1.1
        U := Dot_Product(V, W);            --  see 6.3

20/4    Writer := (Status => Open, Unit => Printer, Line_Count => 60);  -- see 3.8.1
        Next.all := (72074, null, Head);   --  see 3.10.1

21  Examples involving scalar subtype conversions:

22      I, J : Integer range 1 .. 10 := 5;
        K    : Integer range 1 .. 20 := 15;
         ...

23      I := J;  --  identical ranges
        K := J;  --  compatible ranges
        J := K;  --  will raise Constraint_Error if K > 10

24  Examples involving array subtype conversions:

25      A : String(1 .. 31);
        B : String(3 .. 33);
         ...

26      A := B;  --  same number of components

27      A(1 .. 9)  := "tar sauce";
        A(4 .. 12) := A(1 .. 9);  --  A(1 .. 12) = "tartar sauce"

        NOTES

28      3  Notes on the examples: Assignment_statements are allowed even in
        the case of overlapping slices of the same array, because the
        variable_name and expression are both evaluated before copying the value into
        the variable. In the above example, an implementation yielding A(1 ..
        12) = "tartartartar" would be incorrect.


5.2.1 Target Name Symbols


1/5 @, known as the target name of an assignment statement, provides an
abbreviation to avoid repetition of potentially long names in assignment
statements.


                                   Syntax

2/5     target_name ::= @


                            Name Resolution Rules

3/5 If a target_name occurs in an assignment_statement A, the variable_name V
of A is a complete context. The target name is a constant view of V, having
the nominal subtype of V.


                               Legality Rules

4/5 A target_name shall appear only in the expression of an
assignment_statement.


                              Dynamic Semantics

5/5 For the execution of an assignment_statement with one or more
target_names appearing in its expression, the variable_name V of the
assignment_statement is evaluated first to determine the object denoted by V,
and then the expression of the assignment_statement is evaluated with the
evaluation of each target_name yielding a constant view of the the target
whose properties are otherwise identical to those of the view provided by V.
The remainder of the execution of the assignment_statement is as given in
subclause 5.2.


                                  Examples

6/5     Board(1, 1) := @ + 1.0;  -- An abbreviation for Board(1, 1) := Board(1, 1) + 1.0;
                               -- (Board is declared in 3.6.1).

7/5     My_Complex_Array : array (1 .. Max) of Complex; -- See 3.3.2, 3.8.
        ...
        -- Square the element in the Count (see 3.3.1) position:
        My_Complex_Array (Count) := (Re => @.Re**2 - @.Im**2,
                                     Im => 2.0 * @.Re * @.Im);
           -- A target_name can be used multiple times and as a prefix if needed.


5.3 If Statements


1   An if_statement selects for execution at most one of the enclosed
sequences_of_statements, depending on the (truth) value of one or more
corresponding conditions.


                                   Syntax

2       if_statement ::= 
            if condition then
              sequence_of_statements
           {elsif condition then
              sequence_of_statements}
           [else
              sequence_of_statements]
            end if;

Paragraphs 3 and 4 were deleted.


                              Dynamic Semantics

5/3 For the execution of an if_statement, the condition specified after if,
and any conditions specified after elsif, are evaluated in succession
(treating a final else as elsif True then), until one evaluates to True or all
conditions are evaluated and yield False. If a condition evaluates to True,
then the corresponding sequence_of_statements is executed; otherwise, none of
them is executed.


                                  Examples

6   Examples of if statements:

7       if Month = December and Day = 31 then
           Month := January;
           Day   := 1;
           Year  := Year + 1;
        end if;

8       if Line_Too_Short then
           raise Layout_Error;
        elsif Line_Full then
           New_Line;
           Put(Item);
        else
           Put(Item);
        end if;

9       if My_Car.Owner.Vehicle /= My_Car then            --  see 3.10.1
           Report ("Incorrect data");
        end if;


5.4 Case Statements


1   A case_statement selects for execution one of a number of alternative
sequences_of_statements; the chosen alternative is defined by the value of an
expression.


                                   Syntax

2/3     case_statement ::= 
           case selecting_expression is
               case_statement_alternative
              {case_statement_alternative}
           end case;

3       case_statement_alternative ::= 
           when discrete_choice_list =>
              sequence_of_statements


                            Name Resolution Rules

4/3 The selecting_expression is expected to be of any discrete type. The
expected type for each discrete_choice is the type of the
selecting_expression.


                               Legality Rules

5/3 The choice_expressions, subtype_indications, and ranges given as
discrete_choices of a case_statement shall be static. A discrete_choice
others, if present, shall appear alone and in the last discrete_choice_list.

6/3 The possible values of the selecting_expression shall be covered (see
3.8.1) as follows:

7/4   * If the selecting_expression is a name (including a type_conversion,
        qualified_expression, or function_call) having a static and
        constrained nominal subtype, then each non-others discrete_choice
        shall cover only values in that subtype that satisfy its predicates
        (see 3.2.4), and each value of that subtype that satisfies its
        predicates shall be covered by some discrete_choice (either explicitly
        or by others).

8/3   * If the type of the selecting_expression is root_integer,
        universal_integer, or a descendant of a formal scalar type, then the
        case_statement shall have an others discrete_choice.

9/3   * Otherwise, each value of the base range of the type of the
        selecting_expression shall be covered (either explicitly or by others).

10  Two distinct discrete_choices of a case_statement shall not cover the same
value.


                              Dynamic Semantics

11/3 For the execution of a case_statement, the selecting_expression is first
evaluated.

12/3 If the value of the selecting_expression is covered by the discrete_-
choice_list of some case_statement_alternative, then the
sequence_of_statements of the _alternative is executed.

13  Otherwise (the value is not covered by any discrete_choice_list, perhaps
due to being outside the base range), Constraint_Error is raised.

        NOTES

14      4  The execution of a case_statement chooses one and only one
        alternative. Qualification of the expression of a case_statement by a
        static subtype can often be used to limit the number of choices that
        need be given explicitly.


                                  Examples

15  Examples of case statements:

16      case Sensor is
           when Elevation         => Record_Elevation(Sensor_Value);
           when Azimuth           => Record_Azimuth  (Sensor_Value);
           when Distance          => Record_Distance (Sensor_Value);
           when others            => null;
        end case;

17      case Today is
           when Mon               => Compute_Initial_Balance;
           when Fri               => Compute_Closing_Balance;
           when Tue .. Thu        => Generate_Report(Today);
           when Sat .. Sun        => null;
        end case;

18      case Bin_Number(Count) is
           when 1          => Update_Bin(1);
           when 2          => Update_Bin(2);
           when 3 | 4      =>
              Empty_Bin(1);
              Empty_Bin(2);
           when others     => raise Error;
        end case;


5.5 Loop Statements


1/5 A loop_statement includes a sequence_of_statements that is to be executed
repeatedly, zero or more times with the iterations running sequentially or
concurrently with one another.


                                   Syntax

2       loop_statement ::= 
           [loop_statement_identifier:]
              [iteration_scheme] loop
                 sequence_of_statements
               end loop [loop_identifier];

3/5     iteration_scheme ::= while condition
           | for loop_parameter_specification
           | for iterator_specification
           | [parallel]
             for procedural_iterator
           | parallel [(chunk_specification)]
             for loop_parameter_specification
           | parallel [(chunk_specification)]
             for iterator_specification

3.1/5   chunk_specification ::= 
             integer_simple_expression
           | defining_identifier in discrete_subtype_definition

4/5     loop_parameter_specification ::= 
           defining_identifier in [reverse] discrete_subtype_definition
             [iterator_filter]

4.1/5   iterator_filter ::= when condition

5       If a loop_statement has a loop_statement_identifier, then the
        identifier shall be repeated after the end loop; otherwise, there
        shall not be an identifier after the end loop.

5.1/5   An iteration_scheme that begins with the reserved word parallel shall
        not have the reserved word reverse in its
        loop_parameter_specification.


                            Name Resolution Rules

5.2/5 In a chunk_specification that is an integer_simple_expression, the
integer_simple_expression is expected to be of any integer type.


                              Static Semantics

6/5 A loop_parameter_specification declares a loop parameter, which is an
object whose subtype (and nominal subtype) is that defined by the
discrete_subtype_definition.

6.1/5 In a chunk_specification that has a discrete_subtype_definition, the
chunk_specification declares a chunk parameter object whose subtype (and
nominal subtype) is that defined by the discrete_subtype_definition.


                              Dynamic Semantics

6.2/5 The filter of an iterator construct (a loop_parameter_specification,
iterator_specification, or procedural_iterator) is defined to be satisfied
when there is no iterator_filter for the iterator construct, or when the
condition of the iterator_filter evaluates to True for a given iteration of
the iterator construct.

6.3/5 If a sequence_of_statements of a loop_statement with an iterator
construct is said to be conditionally executed, then the statements are
executed only when the filter of the iterator construct is satisfied.

6.4/5 The loop iterators loop_parameter_specification and
iterator_specification can also be used in contexts other than
loop_statements (for example, see 4.3.5 and 4.5.8). In such a context, the
iterator conditionally produces values in the order specified for the
associated construct below or in 5.5.2. The values produced are the values
given to the loop parameter when the filter of the iterator construct is
satisfied for that value. No value is produced when the condition of an
iterator_filter evaluates to False.

7/5 For the execution of a loop_statement, the sequence_of_statements is
executed zero or more times, until the loop_statement is complete. The
loop_statement is complete when a transfer of control occurs that transfers
control out of the loop, or, in the case of an iteration_scheme, as specified
below.

8   For the execution of a loop_statement with a while iteration_scheme, the
condition is evaluated before each execution of the sequence_of_statements; if
the value of the condition is True, the sequence_of_statements is executed; if
False, the execution of the loop_statement is complete.

8.1/5 If the reserved word parallel is present in the iteration_scheme of a
loop_statement (a parallel loop), the iterations are partitioned into one or
more chunks, each with its own separate logical thread of control (see clause
9). If a chunk_specification is present in a parallel loop, it is elaborated
first, and the result of the elaboration determines the maximum number of
chunks used for the parallel loop. If the chunk_specification is an
integer_simple_expression, the elaboration evaluates the expression, and the value of
the expression determines the maximum number of chunks. If a
discrete_subtype_definition is present, the elaboration elaborates the
discrete_subtype_definition, which defines the subtype of the chunk parameter,
and the number of values in this subtype determines the maximum number of
chunks. After elaborating the chunk_specification, a check is made that the
determined maximum number of chunks is greater than zero. If this check fails,
Program_Error is raised.

9/5 For the execution of a loop_statement that has an iteration_scheme
including a loop_parameter_specification, after elaborating the
chunk_specification, if any, the loop_parameter_specification is elaborated.
This elaborates the discrete_subtype_definition, which defines the subtype of
the loop parameter. If the discrete_subtype_definition defines a subtype with
a null range, the execution of the loop_statement is complete. Otherwise, the
sequence_of_statements is conditionally executed once for each value of the
discrete subtype defined by the discrete_subtype_definition that satisfies the
predicates of the subtype (or until the loop is left as a consequence of a
transfer of control). Prior to each such iteration, the corresponding value of
the discrete subtype is assigned to the loop parameter associated with the
given iteration. If the loop is a parallel loop, each chunk has its own
logical thread of control with its own copy of the loop parameter; otherwise
(a sequential loop), a single logical thread of control performs the loop, and
there is a single copy of the loop parameter. Each logical thread of control
handles a distinct subrange of the values of the subtype of the loop parameter
such that all values are covered with no overlaps. Within each logical thread
of control, the values are assigned to the loop parameter in increasing order
unless the reserved word reverse is present, in which case the values are
assigned in decreasing order.

9.1/5 If a chunk_specification with a discrete_subtype_definition is present,
then the logical thread of control associated with a given chunk has its own
copy of the chunk parameter initialized with a distinct value from the
discrete subtype defined by the discrete_subtype_definition. The values of the
chunk parameters are assigned such that they increase with increasing values
of the ranges covered by the corresponding loop parameters.

9.2/5 Whether or not a chunk_specification is present in a parallel loop, the
total number of iterations of the loop represents an upper bound on the number
of logical threads of control devoted to the loop.

9.3/5 For details about the execution of a loop_statement with the
iteration_scheme including an iterator_specification, see 5.5.2. For details
relating to a procedural_iterator, see 5.5.3.

        NOTES

10/5    5  A loop parameter declared by a loop_parameter_specification is a
        constant; it cannot be updated within the sequence_of_statements of
        the loop (see 3.3).

11      6  An object_declaration should not be given for a loop parameter,
        since the loop parameter is automatically declared by the
        loop_parameter_specification. The scope of a loop parameter extends
        from the loop_parameter_specification to the end of the
        loop_statement, and the visibility rules are such that a loop
        parameter is only visible within the sequence_of_statements of the
        loop.

12      7  The discrete_subtype_definition of a for loop is elaborated just
        once. Use of the reserved word reverse does not alter the discrete
        subtype defined, so that the following iteration_schemes are not
        equivalent; the first has a null range.

13          for J in reverse 1 .. 0
            for J in 0 .. 1


                                  Examples

14  Example of a loop statement without an iteration scheme:

15      loop
           Get(Current_Character);
           exit when Current_Character = '*';
        end loop;

16  Example of a loop statement with a while iteration scheme:

17      while Bid(N).Price < Cut_Off.Price loop
           Record_Bid(Bid(N).Price);
           N := N + 1;
        end loop;

18  Example of a loop statement with a for iteration scheme:

19      for J in Buffer'Range loop     --  works even with a null range
           if Buffer(J) /= Space then
              Put(Buffer(J));
           end if;
        end loop;

20  Example of a loop statement with a name:

21      Summation:
           while Next /= Head loop       -- see 3.10.1
              Sum  := Sum + Next.Value;
              Next := Next.Succ;
           end loop Summation;

22/5 Example of a simple parallel loop:

23/5    -- see 3.6
        parallel
        for I in Grid'Range(1) loop
           Grid(I, 1) := (for all J in Grid'Range(2) => Grid(I,J) = True);
        end loop;

24/5 Example of a parallel loop with a chunk specification:

25/5    declare
           subtype Chunk_Number is Natural range 1 .. 8;

26/5       Partial_Sum,
           Partial_Max : array (Chunk_Number) of Natural := (others => 0);
           Partial_Min : array (Chunk_Number) of Natural := (others => Natural'Last);

27/5    begin
           parallel (Chunk in Chunk_Number)
           for I in Grid'Range(1) loop
              declare
                 True_Count : constant Natural :=
                   [for J in Grid'Range(2) => (if Grid (I, J) then 1 else 0)]'Reduce("+",0);
              begin
                 Partial_Sum (Chunk) := @ + True_Count;
                 Partial_Min (Chunk) := Natural'Min(@, True_Count);
                 Partial_Max (Chunk) := Natural'Max(@, True_Count);
              end;
           end loop;

28/5       Put_Line("Total=" & Partial_Sum'Reduce("+", 0) &
                    ", Min=" & Partial_Min'Reduce(Natural'Min, Natural'Last) &
                    ", Max=" & Partial_Max'Reduce(Natural'Max, 0));
        end;

29/5 For an example of an iterator_filter, see 4.5.8.


5.5.1 User-Defined Iterator Types



                              Static Semantics

1/3 The following language-defined generic library package exists:

2/5     generic
           type Cursor;
           with function Has_Element (Position : Cursor) return Boolean;
        package Ada.Iterator_Interfaces
           with Pure, Nonblocking => False is

3/3        type Forward_Iterator is limited interface;
           function First
         (Object : Forward_Iterator) return Cursor is abstract;
           function Next (Object : Forward_Iterator; Position : Cursor)
              return Cursor is abstract;

4/3        type Reversible_Iterator is limited interface and Forward_Iterator;
           function Last
         (Object : Reversible_Iterator) return Cursor is abstract;
           function Previous (Object : Reversible_Iterator; Position : Cursor)
              return Cursor is abstract;

4.1/5      type Parallel_Iterator is limited interface and Forward_Iterator;

4.2/5      subtype Chunk_Index is Positive;

4.3/5      function Is_Split (Object : Parallel_Iterator)
              return Boolean is abstract;

4.4/5      procedure Split_Into_Chunks (Object     : in out Parallel_Iterator;
                                        Max_Chunks : in     Chunk_Index) is abstract
              with Pre'Class   => not Object.Is_Split or else raise Program_Error,
                   Post'Class  => Object.Is_Split and then
                                  Object.Chunk_Count <= Max_Chunks;

4.5/5      function Chunk_Count (Object : Parallel_Iterator)
              return Chunk_Index is abstract
              with Pre'Class   => Object.Is_Split or else raise Program_Error;

4.6/5      function First (Object : Parallel_Iterator;
                           Chunk  : Chunk_Index) return Cursor is abstract
              with Pre'Class   => (Object.Is_Split and then
                                      Chunk <= Object.Chunk_Count)
                                   or else raise Program_Error;

4.7/5      function Next (Object   : Parallel_Iterator;
                          Position : Cursor;
                          Chunk    : Chunk_Index) return Cursor is abstract
              with Pre'Class   => (Object.Is_Split and then
                                      Chunk <= Object.Chunk_Count)
                                   or else raise Program_Error;

4.8/5      type Parallel_Reversible_Iterator is limited interface
              and Parallel_Iterator and Reversible_Iterator;

5/3     end Ada.Iterator_Interfaces;

6/5 An iterator type is a type descended from the Forward_Iterator interface
from some instance of Ada.Iterator_Interfaces. A reversible iterator type is a
type descended from the Reversible_Iterator interface from some instance of
Ada.Iterator_Interfaces. A parallel iterator type is a type descended from the
Parallel_Iterator interface from some instance of Ada.Iterator_Interfaces. A
type descended from the Parallel_Reversible_Iterator interface from some
instance of Ada.Iterator_Interfaces is both a parallel iterator type and a
reversible iterator type. An iterator object is an object of an iterator type.
A reversible iterator object is an object of a reversible iterator type. A
parallel iterator object is an object of a parallel iterator type. The formal
subtype Cursor from the associated instance of Ada.Iterator_Interfaces is the
iteration cursor subtype for the iterator type.

7/3 The following type-related operational aspects may be specified for an
indexable container type T (see 4.1.6):

8/5 Default_Iterator
                This aspect is specified by a name that denotes exactly one
                function declared immediately within the same declaration list
                in which T is declared, whose first parameter is of type T or
                T'Class or an access parameter whose designated type is type T
                or T'Class, whose other parameters, if any, have default
                expressions, and whose result type is an iterator type. This
                function is the default iterator function for T. Its result
                subtype is the default iterator subtype for T. The iteration
                cursor subtype for the default iterator subtype is the default
                cursor subtype for T. This aspect is inherited by descendants
                of type T (including T'Class).

9/5 Iterator_Element
                This aspect is specified by a name that denotes a subtype.
                This is the default element subtype for T. This aspect is
                inherited by descendants of type T (including T'Class).

9.1/5 Iterator_View
                This aspect is specified by a name that denotes a type T2 with
                the following properties:

9.2/5             * T2 is declared in the same compilation unit as T;

9.3/5             * T2 is an iterable container type;

9.4/5             * T2 has a single discriminant which is an access
                    discriminant designating T; and

9.5/5             * The default iterator subtypes for T and T2 statically
                    match.

9.6/5           This aspect is never inherited, even by T'Class.

10/5 This paragraph was deleted.

11/5 An iterable container type is an indexable container type with specified
Default_Iterator and Iterator_Element aspects. A reversible iterable container
type is an iterable container type with the default iterator type being a
reversible iterator type. A parallel iterable container type is an iterable
container type with the default iterator type being a parallel iterator type.
An iterable container object is an object of an iterable container type. A
reversible iterable container object is an object of a reversible iterable
container type. A parallel iterable container object is an object of a
parallel iterable container type.

11.1/4 The Default_Iterator and Iterator_Element aspects are nonoverridable
(see 13.1.1).


                               Legality Rules

12/3 The Constant_Indexing aspect (if any) of an iterable container type T
shall denote exactly one function with the following properties:

13/3   * the result type of the function is covered by the default element
        type of T or is a reference type (see 4.1.5) with an access
        discriminant designating a type covered by the default element type of
        T;

14/3   * the type of the second parameter of the function covers the default
        cursor type for T;

15/3   * if there are more than two parameters, the additional parameters all
        have default expressions.

16/3 This function (if any) is the default constant indexing function for T.

17/3 The Variable_Indexing aspect (if any) of an iterable container type T
shall denote exactly one function with the following properties:

18/3   * the result type of the function is a reference type (see 4.1.5) with
        an access discriminant designating a type covered by the default
        element type of T;

19/3   * the type of the second parameter of the function covers the default
        cursor type for T;

20/3   * if there are more than two parameters, the additional parameters all
        have default expressions.

21/3 This function (if any) is the default variable indexing function for T.


5.5.2 Generalized Loop Iteration


1/3 Generalized forms of loop iteration are provided by an
iterator_specification.


                                   Syntax

2/5     iterator_specification ::= 
            defining_identifier [: loop_parameter_subtype_indication
        ] in [reverse] iterator_name
              [iterator_filter]
          | defining_identifier [: loop_parameter_subtype_indication
        ] of [reverse] iterable_name
              [iterator_filter]

2.1/5   loop_parameter_subtype_indication ::= subtype_indication
         | access_definition

2.2/5   If an iterator_specification is for a parallel construct, the reserved
        word reverse shall not appear in the iterator_specification.


                            Name Resolution Rules

3/3 For the first form of iterator_specification, called a generalized
iterator, the expected type for the iterator_name is any iterator type. For
the second form of iterator_specification, the expected type for the
iterable_name is any array or iterable container type. If the iterable_name denotes an
array object, the iterator_specification is called an array component
iterator; otherwise it is called a container element iterator.


                               Legality Rules

4/5 If the reserved word reverse appears, the iterator_specification is a
reverse iterator. If the iterator_specification is for a parallel construct,
the iterator_specification is a parallel iterator. Otherwise, it is a forward
iterator. Forward and reverse iterators are collectively called sequential
iterators. In a reverse generalized iterator, the iterator_name shall be of a
reversible iterator type. In a parallel generalized iterator, the
iterator_name shall be of a parallel iterator type. In a reverse container element
iterator, the default iterator type for the type of the iterable_name shall be
a reversible iterator type. In a parallel container element iterator, the
default iterator type for the type of the iterable_name shall be of a parallel
iterator type.

5/5 The subtype defined by the loop_parameter_subtype_indication, if any, of a
generalized iterator shall statically match the iteration cursor subtype. The
subtype defined by the loop_parameter_subtype_indication, if any, of an array
component iterator shall statically match the component subtype of the type of
the iterable_name. The subtype defined by the
loop_parameter_subtype_indication, if any, of a container element iterator
shall statically match the default element subtype for the type of the
iterable_name.

6/3 In a container element iterator whose iterable_name has type T, if the
iterable_name denotes a constant or the Variable_Indexing aspect is not
specified for T, then the Constant_Indexing aspect shall be specified for T.

6.1/4 The iterator_name or iterable_name of an iterator_specification shall
not denote a subcomponent that depends on discriminants of an object whose
nominal subtype is unconstrained, unless the object is known to be constrained.

6.2/4 A container element iterator is illegal if the call of the default
iterator function that creates the loop iterator (see below) is illegal.

6.3/4 A generalized iterator is illegal if the iteration cursor subtype of the
iterator_name is a limited type at the point of the generalized iterator. A
container element iterator is illegal if the default cursor subtype of the
type of the iterable_name is a limited type at the point of the container
element iterator.


                              Static Semantics

7/5 An iterator_specification declares a loop parameter. In a generalized
iterator, an array component iterator, or a container element iterator, if a
loop_parameter_subtype_indication is present, it determines the nominal
subtype of the loop parameter. In a generalized iterator, if a
loop_parameter_subtype_indication is not present, the nominal subtype of the
loop parameter is the iteration cursor subtype. In an array component
iterator, if a loop_parameter_subtype_indication is not present, the nominal
subtype of the loop parameter is the component subtype of the type of the
iterable_name. In a container element iterator, if a
loop_parameter_subtype_indication is not present, the nominal subtype of the
loop parameter is the default element subtype for the type of the
iterable_name.

8/3 In a generalized iterator, the loop parameter is a constant. In an array
component iterator, the loop parameter is a constant if the iterable_name
denotes a constant; otherwise it denotes a variable. In a container element
iterator, the loop parameter is a constant if the iterable_name denotes a
constant, or if the Variable_Indexing aspect is not specified for the type of
the iterable_name; otherwise it is a variable.


                              Dynamic Semantics

9/3 For the execution of a loop_statement with an iterator_specification, the
iterator_specification is first elaborated. This elaboration elaborates the
subtype_indication, if any.

10/5 For a sequential generalized iterator, the loop parameter is created, the
iterator_name is evaluated, and the denoted iterator object becomes the loop
iterator. In a forward generalized iterator, the operation First of the
iterator type is called on the loop iterator, to produce the initial value for
the loop parameter. If the result of calling Has_Element on the initial value
is False, then the execution of the loop_statement is complete. Otherwise, the
sequence_of_statements is conditionally executed and then the Next operation
of the iterator type is called with the loop iterator and the current value of
the loop parameter to produce the next value to be assigned to the loop
parameter. This repeats until the result of calling Has_Element on the loop
parameter is False, or the loop is left as a consequence of a transfer of
control. For a reverse generalized iterator, the operations Last and Previous
are called rather than First and Next.

10.1/5 For a parallel generalized iterator, the chunk_specification, if any,
of the associated parallel construct, is first elaborated, to determine the
maximum number of chunks (see 5.5), and then the operation Split_Into_Chunks
of the iterator type is called, with the determined maximum passed as the
Max_Chunks parameter, specifying the upper bound for the number of loop
parameter objects (and the number of logical threads of control) to be
associated with the iterator. In the absence of a chunk_specification, the
maximum number of chunks is determined in an implementation-defined manner.

10.2/5 Upon return from Split_Into_Chunks, the actual number of chunks for the
loop is determined by calling the Chunk_Count operation of the iterator, at
which point one logical thread of control is initiated for each chunk, with an
associated chunk index in the range from one to the actual number of chunks.
Within each logical thread of control, a loop parameter is created. If a
chunk_specification with a discrete_subtype_definition is present in the
associated parallel construct, then a chunk parameter is created, and
initialized with a value from the discrete subtype defined by the
discrete_subtype_definition, so that the order of the chosen chunk parameter
values correspond to the order of the chunk indices associated with the
logical threads of control. The operation First of the iterator type having a
Chunk parameter is called on the loop iterator, with Chunk initialized from
the corresponding chunk index, to produce the initial value for the loop
parameter. If the result of calling Has_Element on this initial value is
False, then the execution of the logical thread of control is complete.
Otherwise, the sequence_of_statements is conditionally executed and then the
Next operation of the iterator type having a Chunk parameter is called, with
the loop iterator, the current value of the loop parameter, and the
corresponding chunk index, to produce the next value to be assigned to the
loop parameter. This repeats until the result of calling Has_Element on the
loop parameter is False, or the associated parallel construct is left as a
consequence of a transfer of control. In the absence of a transfer of control,
the associated parallel construct of a parallel generalized iterator is
complete when all of its logical threads of control are complete.

11/5 For an array component iterator, the chunk_specification of the
associated parallel construct, if any, is first elaborated to determine the
maximum number of chunks (see 5.5), and then the iterable_name is evaluated
and the denoted array object becomes the array for the loop. If the array for
the loop is a null array, then the execution of the loop_statement is
complete. Otherwise, the sequence_of_statements is conditionally executed with
the loop parameter denoting each component of the array for the loop, using a
canonical order of components, which is last dimension varying fastest (unless
the array has convention Fortran, in which case it is first dimension varying
fastest). For a forward array component iterator, the iteration starts with
the component whose index values are each the first in their index range, and
continues in the canonical order. For a reverse array component iterator, the
iteration starts with the component whose index values are each the last in
their index range, and continues in the reverse of the canonical order. For a
parallel array component iterator, the iteration is broken up into contiguous
chunks of the canonical order, such that all components are covered with no
overlaps; each chunk has its own logical thread of control with its own loop
parameter and iteration within each chunk is in the canonical order. The
number of chunks is implementation defined, but is limited in the presence of
a chunk_specification to the determined maximum. The loop iteration proceeds
until the sequence_of_statements has been conditionally executed for each
component of the array for the loop, or until the loop is left as a
consequence of a transfer of control.

11.1/5 If a chunk_specification with a discrete_subtype_definition is present
in the associated parallel construct, then the logical thread of control
associated with a given chunk has a chunk parameter initialized with a
distinct value from the discrete subtype defined by the
discrete_subtype_definition. The values of the chunk parameters are assigned
such that they increase in the canonical order of the starting array
components for the chunks.

12/5 For a container element iterator, the chunk_specification of the
associated parallel construct, if any, is first elaborated to determine the
maximum number of chunks (see 5.5), and then the iterable_name is evaluated.
If the container type has Iterator_View specified, an object of the
Iterator_View type is created with the discriminant referencing the iterable
container object denoted by the iterable_name. This is the iterable container
object for the loop. Otherwise, the iterable container object denoted by the
iterable_name becomes the iterable container object for the loop. The default
iterator function for the type of the iterable container object for the loop
is called on the iterable container object and the result is the loop
iterator. For a sequential container element iterator, an object of the
default cursor subtype is created (the loop cursor). For a parallel container
element iterator, each chunk of iterations will have its own loop cursor,
again of the default cursor subtype.

13/5 A container element iterator then proceeds as described above for a
generalized iterator, except that each reference to a loop parameter is
replaced by a reference to the corresponding loop cursor. For a container
element iterator, the loop parameter for each iteration instead denotes an
indexing (see 4.1.6) into the iterable container object for the loop, with the
only parameter to the indexing being the value of the loop cursor for the
given iteration. If the loop parameter is a constant (see above), then the
indexing uses the default constant indexing function for the type of the
iterable container object for the loop; otherwise it uses the default variable
indexing function.

14/4 Any exception propagated by the execution of a generalized iterator or
container element iterator is propagated by the immediately enclosing loop
statement.


                                  Examples

15/5    -- Array component iterator example:
        parallel
        for Element of Board loop  -- See 3.6.1.
           Element := Element * 2.0; -- Double each element of Board, a two-dimensional array.
        end loop;

16/3 For examples of use of generalized iterators, see A.18.33 and the
corresponding container packages in A.18.2 and A.18.3.


5.5.3 Procedural Iterators


1/5 A procedural_iterator invokes a user-defined procedure, passing in the
body of the enclosing loop_statement as a parameter of an anonymous
access-to-procedure type, to allow the loop body to be executed repeatedly as
part of the invocation of the user-defined procedure.


                                   Syntax

2/5     procedural_iterator ::= 
             iterator_parameter_specification of iterator_procedure_call
               [iterator_filter]

3/5     iterator_parameter_specification ::= 
             formal_part
           | (defining_identifier{, defining_identifier})

4/5     iterator_procedure_call ::= 
             procedure_name
           | procedure_prefix iterator_actual_parameter_part

5/5     iterator_actual_parameter_part ::= 
             (iterator_parameter_association
         {, iterator_parameter_association})

6/5     iterator_parameter_association ::= 
             parameter_association
           | parameter_association_with_box

7/5     parameter_association_with_box ::= 
           [ formal_parameter_selector_name => ] <>

8/5     At most one iterator_parameter_association within an
        iterator_actual_parameter_part shall be a
        parameter_association_with_box.


                            Name Resolution Rules

9/5 The name or prefix given in an iterator_procedure_call shall resolve to
denote a callable entity C (the iterating procedure) that is a procedure, or
an entry renamed as (viewed as) a procedure. When there is an
iterator_actual_parameter_part, the prefix can be an implicit_dereference of
an access-to-subprogram value.

10/5 An iterator_procedure_call without a parameter_association_with_box is
equivalent to one with an iterator_actual_parameter_part with an additional
parameter_association_with_box at the end, with the
formal_parameter_selector_name identifying the last formal parameter of the callable entity
denoted by the name or prefix.

11/5 An iterator_procedure_call shall contain at most one
iterator_parameter_association for each formal parameter of the callable
entity C. Each formal parameter without an iterator_parameter_association
shall have a default_expression (in the profile of the view of C denoted by
the name or prefix).]

12/5 The formal parameter of the callable entity C associated with the
parameter_association_with_box shall be of an anonymous access-to-procedure
type A.


                               Legality Rules

13/5 The anonymous access-to-procedure type A shall have at least one formal
parameter in its parameter profile. If the iterator_parameter_specification is
a formal_part, then this formal_part shall be mode conformant with that of A.
If the iterator_parameter_specification is a list of defining_identifiers, the
number of formal parameters of A shall be the same as the length of this list.

14/5 If the name or prefix given in an iterator_procedure_call denotes an
abstract subprogram, the subprogram shall be a dispatching subprogram.


                              Static Semantics

15/5 A loop_statement with an iteration_scheme that has a
procedural_iterator is equivalent to a local declaration of a procedure P
followed by a procedure_call_statement that is formed from the
iterator_procedure_call by replacing the <> of the
parameter_association_with_box with P'Access. The formal_part of the locally
declared procedure P is formed from the formal_part of the anonymous
access-to-procedure type A, by replacing the identifier of each formal
parameter of this formal_part with the identifier of the corresponding formal
parameter or element of the list of defining_identifiers given in the
iterator_parameter_specification. The body of P consists of the conditionally
executed sequence_of_statements. The procedure P is called the loop body
procedure.

16/5 The following aspects may be specified for a callable entity S that has
at least one formal parameter of an anonymous access-to-subprogram type:

17/5 Allows_Exit
                The Allows_Exit aspect is of type Boolean. The specified value
                shall be static. The Allows_Exit aspect of an inherited
                primitive subprogram is True if Allows_Exit is True either for
                the corresponding subprogram of the progenitor type or for any
                other inherited subprogram that it overrides. If not specified
                or inherited as True, the Allows_Exit aspect of a callable
                entity is False. For an entry, only a confirming specification
                of False is permitted for the Allows_Exit aspect.

18/5            Specifying the Allows_Exit aspect to be True for a subprogram
                indicates that the subprogram allows exit, meaning that it is
                prepared to be completed by arbitrary transfers of control
                from the loop body procedure, including propagation of
                exceptions. A subprogram for which Allows_Exit is True should
                use finalization as appropriate rather than exception handling
                to recover resources and make any necessary final updates to
                data structures.

19/5 Parallel_Iterator
                The Parallel_Iterator aspect is of type Boolean. The specified
                value shall be static. The Parallel_Iterator aspect of an
                inherited primitive subprogram is True if Parallel_Iterator is
                True either for the corresponding subprogram of the progenitor
                type or for any other inherited subprogram that it overrides.
                If not specified or inherited as True, the Parallel_Iterator
                aspect of a callable entity is False.

20/5            Specifying the Parallel_Iterator aspect to be True for a
                callable entity indicates that the entity might invoke the
                loop body procedure from multiple distinct logical threads of
                control. The Parallel_Iterator aspect for a subprogram shall
                be statically False if the subprogram allows exit.


                               Legality Rules

21/5 If a callable entity overrides an inherited dispatching subprogram that
allows exit, the overriding callable entity also shall allow exit. If a
callable entity overrides an inherited dispatching subprogram that has a True
Parallel_Iterator aspect, the overriding callable entity also shall have a
True Parallel_Iterator aspect.

22/5 A loop_statement with a procedural_iterator as its iteration_scheme shall
begin with the reserved word parallel if and only if the callable entity
identified in the iterator_procedure_call has a Parallel_iterator aspect of
True.

23/5 The sequence_of_statements of a loop_statement with a
procedural_iterator as its iteration_scheme shall contain an exit_statement,
return statement, goto_statement, or requeue_statement that leaves the loop
only if the callable entity associated with the procedural_iterator allows
exit.

24/5 The sequence_of_statements of a loop_statement with a
procedural_iterator as its iteration_scheme shall not contain an
accept_statement whose entry_declaration occurs outside the loop_statement.


                              Dynamic Semantics

25/5 For the execution of a loop_statement with an iteration_scheme that has a
procedural_iterator, the procedure denoted by the name or prefix of the
iterator_procedure_call (the iterating procedure) is invoked, passing an
access value designating the loop body procedure as a parameter. The iterating
procedure then calls the loop body procedure zero or more times and returns,
whereupon the loop_statement is complete. If the parallel reserved word is
present, the iterating procedure might invoke the loop body procedure from
multiple distinct logical threads of control.


                          Bounded (Run-Time) Errors

26/5 If the callable entity identified in the iterator_procedure_call allows
exit, then it is a bounded error for a call of the loop body procedure to be
performed from within an abort-deferred operation (see 9.8), unless the entire
loop_statement was within the same abort-deferred operation. If detected,
Program_Error is raised at the point of the call; otherwise, a transfer of
control from the sequence_of_statements of the loop_statement might not
terminate the loop_statement, and the loop body procedure might be called
again.

27/5 If a loop_statement with the procedural_iterator as its
iteration_scheme (see 5.5) does not begin with the reserved word parallel, it
is a bounded error if the loop body procedure is invoked from a different
logical thread of control than the one that initiates the loop_statement. If
detected, Program_Error is raised; otherwise, conflicts associated with
concurrent executions of the loop body procedure can occur without being
detected by the applicable conflict check policy (see 9.10.1). Furthermore,
propagating an exception or making an attempt to exit in the presence of
multiple threads of control might not terminate the loop_statement, deadlock
might occur, or the loop body procedure might be called again.


                                  Examples

28/5 Example of iterating over a map from My_Key_Type to My_Element_Type (see
A.18.4):

29/5    for (C : Cursor) of My_Map.Iterate loop
           Put_Line (My_Key_Type'Image (Key (C)) & " => " &
              My_Element_Type'Image (Element (C)));
        end loop;

30/5    -- The above is equivalent to:

31/5    declare
           procedure P (C : Cursor) is
           begin
              Put_Line (My_Key_Type'Image (Key (c)) & " => " &
                 My_Element_Type'Image (Element (C)));
           end P;
        begin
           My_Map.Iterate (P'Access);
        end;

32/5 Example of iterating over the environment variables (see A.17):

33/5    for (Name, Val) of Ada.Environment_Variables.Iterate(<>) loop
           --  "(<>)" is optional because it is the last parameter
           Put_Line (Name & " => " & Val);
        end loop;

34/5    -- The above is equivalent to:

35/5    declare
           procedure P (Name : String; Val : String) is
           begin
              Put_Line (Name & " => " & Val);
           end P;
        begin
           Ada.Environment_Variables.Iterate (P'Access);
        end;


5.6 Block Statements


1   A block_statement encloses a handled_sequence_of_statements optionally
preceded by a declarative_part.


                                   Syntax

2       block_statement ::= 
           [block_statement_identifier:]
               [declare
                    declarative_part]
                begin
                    handled_sequence_of_statements
                end [block_identifier];

3       If a block_statement has a block_statement_identifier, then the
        identifier shall be repeated after the end; otherwise, there shall not
        be an identifier after the end.


                              Static Semantics

4   A block_statement that has no explicit declarative_part has an implicit
empty declarative_part.


                              Dynamic Semantics

5   The execution of a block_statement consists of the elaboration of its
declarative_part followed by the execution of its
handled_sequence_of_statements.


                                  Examples

6   Example of a block statement with a local variable:

7       Swap:
           declare
              Temp : Integer;
           begin
              Temp := V; V := U; U := Temp;
           end Swap;


5.6.1 Parallel Block Statements


1/5 A parallel_block_statement comprises two or more
handled_sequence_of_statements separated by and where each represents an
independent activity that is intended to proceed concurrently with the others.


                                   Syntax

2/5     parallel_block_statement ::= 
            parallel do
               handled_sequence_of_statements
            and
               handled_sequence_of_statements
           {and
               handled_sequence_of_statements}
            end do;


                              Static Semantics

3/5 Each handled_sequence_of_statements represents a separate logical thread
of control that proceeds independently and concurrently. The
parallel_block_statement is complete once every one of the
handled_sequence_of_statements has completed, either by reaching the end of
its execution, or due to a transfer of control out of the construct by one of
the handled_sequence_of_statements (see 5.1).


                                  Examples

4/5     procedure Traverse (T : Expr_Ptr) is -- see 3.9
        begin
           if T /= null and then
              T.all in Binary_Operation'Class -- see 3.9.1
           then -- recurse down the binary tree
              parallel do
                 Traverse (T.Left);
              and
                 Traverse (T.Right);
              and
                 Ada.Text_IO.Put_Line
                    ("Processing " & Ada.Tags.Expanded_Name (T'Tag));
              end do;
           end if;
        end Traverse;

5/5     function Search (S : String; Char : Character) return Boolean is
        begin
           if S'Length <= 1000 then
               -- Sequential scan
               return (for some C of S => C = Char);
           else
               -- Parallel divide and conquer
               declare
                  Mid : constant Positive := S'First + S'Length/2 - 1;
               begin
                  parallel do
                     for C of S(S'First .. Mid) loop
                        if C = Char then
                           return True;  -- Terminates enclosing do
                        end if;
                     end loop;
                  and
                     for C of S(Mid + 1 .. S'Last) loop
                        if C = Char then
                           return True;  -- Terminates enclosing do
                        end if;
                     end loop;
                  end do;
                  -- Not found
                  return False;
               end;
           end if;
        end Search;


5.7 Exit Statements


1   An exit_statement is used to complete the execution of an enclosing
loop_statement; the completion is conditional if the exit_statement includes a
condition.


                                   Syntax

2       exit_statement ::= 
           exit [loop_name] [when condition];


                            Name Resolution Rules

3   The loop_name, if any, in an exit_statement shall resolve to denote a
loop_statement.


                               Legality Rules

4   Each exit_statement applies to a loop_statement; this is the
loop_statement being exited. An exit_statement with a name is only allowed
within the loop_statement denoted by the name, and applies to that loop_-
statement. An exit_statement without a name is only allowed within a loop_-
statement, and applies to the innermost enclosing one. An exit_statement that
applies to a given loop_statement shall not appear within a body or accept_-
statement, if this construct is itself enclosed by the given loop_statement.


                              Dynamic Semantics

5   For the execution of an exit_statement, the condition, if present, is
first evaluated. If the value of the condition is True, or if there is no
condition, a transfer of control is done to complete the loop_statement. If
the value of the condition is False, no transfer of control takes place.

        NOTES

6       8  Several nested loops can be exited by an exit_statement that names
        the outer loop.


                                  Examples

7   Examples of loops with exit statements:

8       for N in 1 .. Max_Num_Items loop
           Get_New_Item(New_Item);
           Merge_Item(New_Item, Storage_File);
           exit when New_Item = Terminal_Item;
        end loop;

9       Main_Cycle:
           loop
              --  initial statements
              exit Main_Cycle when Found;
              --  final statements
           end loop Main_Cycle;


5.8 Goto Statements


1   A goto_statement specifies an explicit transfer of control from this
statement to a target statement with a given label.


                                   Syntax

2       goto_statement ::= goto label_name;


                            Name Resolution Rules

3   The label_name shall resolve to denote a label; the statement with that
label is the target statement.


                               Legality Rules

4   The innermost sequence_of_statements that encloses the target statement
shall also enclose the goto_statement. Furthermore, if a goto_statement is
enclosed by an accept_statement or a body, then the target statement shall not
be outside this enclosing construct.


                              Dynamic Semantics

5   The execution of a goto_statement transfers control to the target
statement, completing the execution of any compound_statement that encloses
the goto_statement but does not enclose the target.

        NOTES

6       9  The above rules allow transfer of control to a statement of an
        enclosing sequence_of_statements but not the reverse. Similarly, they
        prohibit transfers of control such as between alternatives of a
        case_statement, if_statement, or select_statement; between
        exception_handlers; or from an exception_handler of a
        handled_sequence_of_statements back to its sequence_of_statements.


                                  Examples

7   Example of a loop containing a goto statement:

8       <<Sort>>
        for I in 1 .. N-1 loop
           if A(I) > A(I+1) then
              Exchange(A(I), A(I+1));
              goto Sort;
           end if;
        end loop;

