From J.Reid@letterbox.rl.ac.uk Wed Mar  9 17:34:57 1994
Received: from ib.rl.ac.uk by dkuug.dk with SMTP id AA28087
  (5.65c8/IDA-1.4.4j for <SC22WG5@dkuug.dk>); Wed, 9 Mar 1994 18:36:51 +0100
Received: from letterbox.rl.ac.uk by ib.rl.ac.uk (IBM VM SMTP V2R1) with TCP;
   Wed, 09 Mar 94 17:36:55 GMT
Received: from jkr.cc.rl.ac.uk by letterbox.rl.ac.uk with SMTP (PP) 
          id <16208-0@letterbox.rl.ac.uk>; Wed, 9 Mar 1994 17:36:22 +0000
Received: by jkr.cc.rl.ac.uk (4.1/SMI-4.1) id AA00645;
          Wed, 9 Mar 94 17:34:57 GMT
Date: Wed, 9 Mar 94 17:34:57 GMT
From: jkr@letterbox.rl.ac.uk (John Reid)
Message-Id: <9403091734.AA00645@jkr.cc.rl.ac.uk>
To: jtm@llnl.gov
Subject: enable proposal
Cc: SC22WG5@dkuug.dk, wg2.5@letterbox.rl.ac.uk, delves@letterbox.rl.ac.uk,
        jeremy@vax.nag.co.uk, demmel@robalo.berkeley.edu
X-Charset: ASCII
X-Char-Esc: 29


Jeanne,
        Here is my paper, which I would appreciate your including in
the WG5 distribution that is about to happen.

Any comments would be most welcome, and from all the people to whom I am
copying this. I am pleased with it and think the input from X3J3 has led to
a great improvement on the previous version. I hope you think so too.

Best wishes,
John. 

..................................

To: WG5                                                         
From: John Reid
Subject: Enable proposal
Date: 9 March 1994


1. INTRODUCTION

The fundamental aim of condition handling is as follows. If an operator 
invokes a process (in hardware or in a procedure for a defined operator)
and hits a problem with which it cannot deal, such as overflow, it needs
to quit and ask the caller to do something else. A simple example of 
this proposal is

   ENABLE (OVERFLOW)
      :
      ... = X*Y ...
   HANDLE 
      :
   END ENABLE

If the multiply is intrinsic and an overflow occurs, a transfer of
control is made to the block of code following the HANDLE statement.
Similarly, if the multiply is a defined operator, it can be arranged
that the OVERFLOW signals in comparable circumstances. The handle block
will probably contain very carefully written code that is slow to
execute but circumvents the problem. It is felt by IFIP WG 2.5
(Numerical Software) to be essential for the construction of robust
software.

This proposal includes improvements suggested at the February meeting
of X3J3:

1. No requirement to process as a run-time exception any error found
   at compile time.

2. Add CHECK statement to enable body. This says go to handler now if
   any enabled condition is signaling. It acts as a barrier to code
   movement for optimization, but gives the user a handle to find out
   which statements have been executed without exceptions.

3. Add an implied CHECK statement ahead of each enable, rather than 
   storing and restoring condition values.

4. Replace the intrinsic CONDITION_SET by the SIGNAL statement.

5. Replace the intrinsic CONDITION_VALUE by a statement.

6. Add user names. These have global scope but may appear only in the new
   statements, so there is no 'name pollution'. Remove the GENERIC
   intrinsic condition.

6. If a condition that is not enabled signals, look all the way up the
   call chain for a handler.

Since the CHECK and SIGNAL statements cause transfers of control out of
enable blocks, I have removed the ban on other transfers of control out
of an enable block. I have not added a RESIGNAL statement, which was
part the paper X3J3/94-99 that I prepared during the meeting, because
the effect can be obtained by allowing the CHECK statement in a handle
block.

Mike Delves (Liverpool University) has sent me a long and thoughtful 
email message. Most of his wishes are covered by the changes agreed at 
the February meeting, but he does not like the signaling of conditions 
outside enable blocks being processor dependent. For certain
conditions, such as the I/O conditions, I can see no problem with
requiring signaling. I therefore now state for each whether signaling
outside enable blocks is required.

Included here is a technical specification (section 2) and a complete
set of edits to the standard (section 3). Since the edits mainly consist
of new sections for the standard, they are not too difficult to read. 
They provide a precise specification. Section 2 is essentially a
precis of section 3. For the definition of the intrinsic conditions, I
refer the reader to section 3 since they are described as a
self-contained new subsection for the standard. Similarly, I refer the
reader to the edits for more examples.


2. TECHNICAL SPECIFICATION

For dealing with exceptional events, this proposal involves the
addition of integer-valued conditions, a new construct, and some new
statements. The conditions may be user defined or intrinsic.  The
intrinsic values are all positive. For the definition of the intrinsic
conditions, see the proposed new section 15 at the end of this paper.
Also, there are more examples in the proposed new sub-section 8.1.5.6.

The enable construct has the general form
         enable statement
              enable block
         handle statement
              handle block
         end enable statement
Nesting of enable constructs is permitted. An enable or handle block
may itself contain an enable-construct. Also, nesting with other
constructs is permitted, subject to the usual rules for proper nesting
of constructs.

The enable statement lists the names of the conditions to be handled by
the construct. If any signals during the execution of the enable block,
control is transferred to the handle block. A simple example is the
following:
   ! Example 1
   ENABLE (OVERFLOW)
    ! First try a fast algorithm for inverting a matrix.
      :
   HANDLE 
    ! Fast algorithm failed; use slow one.
      :
   END ENABLE
Here, the code in the enable block takes no precautions against
overflow and will usually execute correctly. Should it fail with
overflow, the alternative algorithm is used instead.

The transfer to the handle block is imprecise in order to allow for
optimizations such as vectorization. Any variable whose value could
have been altered by execution of the enable block must be regarded as
undefined. In Example 1, a copy of the matrix itself would need to be
available for the slow algorithm.

The transfer may be made more precise by adding to the enable block a
check statement for a set of conditions. If any of them is signaling
when the statement is executed, control is transferred to the handle
block. This reduces the imprecision to the statements executed between
successive executions of a check statement for the condition. Adding
such a statement at the end of each major step of the code of Example 1
gives:
   ! Example 2
   ENABLE (OVERFLOW)
   ! First try a fast algorithm for inverting a matrix.
   :
   DO K = 1, N
      :
     CHECK(OVERFLOW)
   END DO
   :
   HANDLE 
   ! Alternative code which knows that K-1 steps have executed normally.
   :
   END ENABLE
Note that a check statement provides an effective barrier to code
migration by an optimizing compiler.

The enable statement is treated as if it were preceded by a check
statement for the same set of conditions. This ensures that all the
conditions are quiet on entering the enable block. Upon normal
completion of the handle block, any of the handled conditions that is
signaling is reset to quiet.

There is an option on the enable statement to specify that some of the
conditions enabled are 'immediate'. Any statement of the enable block
that might signal one of the immediate conditions is treated as if it
were followed by a check statement for the condition. An example of
such an enable statement is
   ENABLE, IMMEDIATE (OVERFLOW)

For a condition that may require additional code (for example,
BOUND_ERROR), the processor is required to signal the condition only
within the statements of the enable block. Whether such a condition
signals outside any enable block for the condition is processor
dependent. There is no requirement to signal such a condition in a
procedure that is called from within an enable block. When a condition
signals outside an enable block, a return occurs in a procedure or a
stop in a main program.

To handle conditions occurring prior to execution of the first
executable statement of a scoping unit, an enable block may consist of
the single statement
     SPECIFICATIONS
Such an enable construct must be the first executable construct of the
scoping unit or must immediately follow an ENTRY statement. For
example, it is possible to handle there being insufficient storage for
automatic arrays by calling an internal procedure that is less
demanding of memory. The concept of condition handling prior to
execution of the first executable statement of a scoping unit is a bit
awkward, but the standard already has the concept of evaluating array
bounds at entry to a procedure (see 45/31).

There is a facility for making a specified condition signal with a
specified value. This is done with the SIGNAL statement. An example is
   SIGNAL(OVERFLOW, 3)
It causes a transfer to the handler if in an enable block for the
condition or a return (stop in a main program) otherwise. 

There is a facility for finding the value of a condition. This is done
with the CONDITION_VALUE statement. An example is
   CONDITION_VALUE(OVERFLOW, I)
which sets the value of the overflow condition in the variable I.

Each condition has a default integer value with global scope. There is no
possibility of name conflict with other entities since condition names
can occur only on ENABLE, CHECK, SIGNAL, and CONDITION_VALUE
statements. User names are permitted.

If a condition is still signaling when the program stops, the processor
must issue a warning on the default output unit.

Neither a handle statement nor an end-enable statement is permitted to
be a branch target. A handle-block is intended for execution only
following the signaling of a condition that it handles, and an
end-enable statement is not a sensible target because it would permit
skipping the handling of a condition.



3. EDITS TO THE STANDARD


6/18+. Add  
	      IEC 559:1989, <Binary floating-point arithmetic for
	      microprocessor systems> (also ANSI/IEEE 754-1985,
              IEEE standard for binary floating-point arithmetic).
.......................................................................

8/45+. Add  
              <<or>>  <enable-construct>
.......................................................................

10/4-24. Add to R216 (in alphabetic positions) the lines
              <<or>>  <check-stmt>
              <<or>>  <condition-value-stmt>
              <<or>>  <signal-stmt>
              <<or>>  <specifications-stmt>
.......................................................................

12/50. After 'CASE constructs,', add 'ENABLE constructs,'.
.......................................................................

12/53+. Add:
     (4) Execution of a check or signal statement (8.1.6.4)
         changes the execution sequence.
.......................................................................

15/33+ Add

<<2.4.8 Condition>>

A <<condition>> is a default integer flag associated with the
occurrence of an exceptional event. The value 0 corresponds to the
quiet state and this is its initial value. Nonzero values correspond to
signaling states.  Negative values can occur only through execution of
the SIGNAL statement.  There is one value for all scoping units and it
may be found by execution of a CONDITION_VALUE statement or altered by
execution of the SIGNAL statement.

[Footnote: The reason for specifying that conditions have integer
values is that this leaves open the possibility of providing detailed
information about the condition. This will be useful when a procedure
(for example, in a library) signals a condition so that it can indicate
the cause of the problem. The intrinsic values are forced to be
positive so that a negative value can be seen to be created by source
code and not by the system.]

[Footnote. Although multitasking is not part of Fortran 90, we have
considered the interaction of this proposal with multitasking
extensions. Our model is that each virtual processor has a flag for
each condition.]

........................................................................

22/23+ Add to the Blanks Optional column:
            END ENABLE
.......................................................................

67/39. After 'terminated', add 'unless the ALLOCATION_ERROR condition
       is enabled'.
.......................................................................

68/40. After 'terminated', add 'unless the DEALLOCATION_ERROR condition
       is enabled'.
.......................................................................

80/2. After 'program', add ', except in an enable block for a suitable
       condition'.
.......................................................................

95/10+ Add

         (4) ENABLE construct
.......................................................................

95/19. Delete 'three'.
........................................................................

107/0+. Add

<<8.1.5 Condition handling>>

A condition has a name with global scope and a default integer value.
The value zero corresponds to the normal or 'quiet' state and nonzero
values correspond to exceptional circumstances. All conditions have
initial value zero. A condition may be intrinsic (15). A condition that
is not intrinsic is user defined and can take nonzero values only
through execution of a SIGNAL statement.  The processor is required to
signal an intrinsic condition if the associated circumstance occurs
during execution of an intrinsic operation or an intrinsic procedure
call specified in the scope of an enable block for the condition. Some
conditions are also required to signal when the circumstance occurs
outside an enable block, but whether other conditions signal outside an
enable block is processor dependent. Which is which is specified in 15.
When an intrinsic signals, it has a positive value.

If the processor detects that every execution of a statement or evaluation
of an expression would signal an exception, it is permitted to provide a
warning instead.

[Footnote: There is no requirement for a condition that can be detected
at compile time to be handled at run time.]

[Footnote: The proposal allows the in-lining of procedures with no
change to the enable constructs. The effect is as if any condition
enabled in the calling procedure but not in the called procedure is
a condition that signals.]

[Footnote. On many processors, we expect that some conditions will
cause no alteration to the flow of control when they signal and that
they will be tested only when the enable block completes. Thus the
overheads of testing the condition are confined precisely to the places
where the programmer has requested a test. On other processors, this
may be very expensive. They may instead cause a transfer of control to
the handler (or a return) as soon as the condition signals or soon
thereafter.]

[Footnote: If additional code is needed (for example, for integer
overflow), this is required only within the scope of the enable block.]


<<8.1.5.1. The enable construct

The ENABLE construct specifies a set of conditions, an enable block,
and a handle block. The handle block is executed only if execution of the
enable block leads to the signaling of one or more of the conditions.

R835a <enable-construct>    <<is>> <enable-stmt>
                                      <enable-body>
                                   <handle-stmt>
                                      <handle-block>
                                   <end-enable-stmt>

R835b <enable-stmt>         <<is>> [<enable-construct-name>:]       #
                                   # ENABLE (<condition-name-list>) #
                                   # [,IMMEDIATE <condition-name-list>)]

R835c <enable-body>         <<is>> <enable-block>
                            <<or>> <specifications-stmt>

R835d <enable-block>        <<is>> <block>

R835e <specifications-stmt> <<is>> SPECIFICATIONS

R835f <handle-stmt>         <<is>> HANDLE [<enable-construct-name>]

R835g <handle-block>        <<is>> <block>

R835h <end-enable-stmt>     <<is>> END ENABLE [<enable-construct-name>]

Constraint: If the <enable-stmt> of an <enable-construct> is identified
	    by an <enable-construct-name>, the corresponding
	    <end-enable-stmt> must specify the same
	    <enable-construct-name>. If the <enable-stmt> of an
	    <enable-construct> is not identified by an
	    <enable-construct-name>, the corresponding
	    <end-enable-stmt> must not specify an
	    <enable-construct-name>. If the <handle-stmt> is identified
	    by an <enable-construct-name>, the corresponding
	    <enable-stmt> must specify the same <enable-construct-name>.

Constraint: A condition name must not appear more than once in an 
         <enable-stmt>. 

Constraint: An <enable-construct> containing a <specifications-stmt>
            must be the first <executable-construct> of the scoping unit
            or must immediately follow an ENTRY statement.

An <enable-stmt> may be a branch target statement (8.2).

[Footnote:  Neither a handle statement nor an end-enable statement is
permitted to be a branch target. A handle-block is intended for
execution only following the signaling of a condition that it handles,
and an end-enable statement is not a sensible target because it would
permit skipping the handling of a condition.]

[Footnote: Nesting of enable constructs is permitted. An enable or
handle block may itself contain an enable-construct. Also, nesting with
other constructs is permitted, subject to the usual rules for proper
nesting of constructs.]

Execution of an ENABLE statement causes a transfer of control if any of
the conditions specified is signaling. The transfer is to the handler
if the enable construct is nested in an enable block for the condition.
Otherwise, it is a return if in a subprogram, or a stop if in a main
program. The values of the conditions are not altered.

The value of each condition enabled by the construct is set to the
quiet value upon completion of execution of the <handle-block>. If a
transfer of control out of the <handle-block> occurs, the conditions
retain their values.


<<8.1.5.2 Enable construct containing an enable block>>

Execution of an <enable-construct> containing an <enable-block> begins
with the first executable construct of the <enable-block>, and
continues to the end of the block unless a branching statement is
executed or an enabled condition is signaled. If a condition enabled by
the construct is signaling on execution of a <check-stmt> for the
condition or on completion of execution of the <enable-block>, control
is transferred to the <handle-block>. Transfer of control to the
<handle-block> may also take place sooner after the signaling of the
condition. Any statement of the enable block that might signal one or
more of the conditions in the immediate list on the enable statement is
treated as if it were followed by a check statement for the condition.
Execution of the <handle-block> completes the execution of the
<enable-construct>.

[Footnote: The transfer to the handle block is imprecise in order to
allow for optimizations such as vectorization. Any variable whose value
could have been altered by execution of the enable block must be
regarded as undefined. In Example 3 of 8.1.5.6, a copy of the matrix
itself would need to be available for the slow algorithm.]

If no condition enabled by the construct is signaling on completion of
execution of the <enable-block>, the execution of the entire construct
is complete.


<<8.1.5.3 Enable construct containing a specifications statement>>

An <enable-construct> containing a <specifications-stmt> enables
condition handling prior to execution of the first executable statement
of a procedure or main program. If an enabled condition is signaled by
the processor, control is transferred to the <handle-block>. Any array
bound or character length that depends on a specification expression is
undefined.  No data object may be referenced or defined unless it has
the SAVE attribute, is accessed by use or host association, or is a
dummy argument that does not have an array bound or character length
depending on a specification expression. Execution of the
<handle-block> completes the execution of the <enable-construct>.

If no enabled condition is signaled, execution of the enable construct
completes as soon as it starts.

Subsequent execution of an <enable-construct> containing a
<specifications-stmt> has no effect.


<<8.1.5.4 Signaling conditions that are not enabled>>

A processor may signal a condition while executing a statement that is
not in an enable block for the condition or prior to execution of the
first executable statement of a procedure or main program without a
specifications enable construct for the condition. If in a subprogram,
a return is executed. If in a main program, a stop is executed and the
processor must issue a warning on the default output unit.


<<8.1.5.5 Check and signal statements>>

R835i <check-stmt> <<is>> CHECK (<condition-name-list>)

The CHECK statement causes a transfer of control if any of the
conditions specified is signaling. The transfer is to the handler if
the statement is in an enable block for the condition. Otherwise, it is
a return if in a subprogram, or a stop if in a main program. The values
of the conditions are not altered.

[Footnote: This reduces the imprecision of an interrupt to the
statements executed between successive executions of a check statement
for the condition.  Note that a check statement provides an effective
barrier to code migration by an optimizing compiler.]


R835j <signal-stmt> <<is>> SIGNAL (<condition-name>,<scalar-int-expr>)

Constraint: The condition name must not be DEFAULT, IO, FLOATING,
            INTEGER, or ALL.

The SIGNAL statement changes the value of the condition it names to
that of the expression it contains and causes a transfer of control.
The transfer is to the handler if the statement is in an enable block
for the condition. Otherwise, it is a return if in a subprogram, or a
stop if in a main program.


<<8.1.5.6 Examples of ENABLE constructs>>

Example 1:

   MODULE MATRIX
! Module for matrix multiplication of real arrays of rank 2.
      INTERFACE OPERATOR(*)
         MODULE PROCEDURE MULT
      END INTERFACE
   CONTAINS
      FUNCTION MULT(A,B)
         REAL, INTENT(IN) :: A(:,:),B(:,:)
         REAL  MULT(SIZE(A,1),SIZE(B,2))
         ENABLE (INSUFFICIENT_STORAGE)
            SPECIFICATIONS
         HANDLE
            SIGNAL(MULT, 1)
         END ENABLE
         ENABLE (INTRINSIC, OVERFLOW)
            MULT = MATMUL(A, B)
         HANDLE
            SIGNAL(MULT, 2)
         END ENABLE
      END FUNCTION MULT
   END MODULE MATRIX

This module provides matrix multiplication for real arrays of rank 2.
If there is insufficient storage for the necessary temporary array, it
signals the condition MULT with value 1. If an INTRINSIC or OVERFLOW
condition occurs, it signals the condition MULT with value 2.


Example 2:

IO_CHECK: ENABLE (IO_ERROR, END_OF_FILE)
             :
             READ (*, '(I5)') I
             READ (*, '(I5)', END = 90) J
             :
       90    J = 0
          HANDLE 
             CONDITION_VALUE(END_OF_FILE,K)
             IF (K/=0) THEN
                WRITE (*, *) 'Unexpected END-OF-FILE when reading ', & 
                             'the real data for a finite element'
             ELSE 
                CONDITION_VALUE(IO_ERROR,K)
                IF (K /= 0) THEN
                   WRITE (*, *) 'I/O error when reading ', & 
                             'the real data for a finite element'
                END IF
             END IF
             STOP
          END ENABLE IO_CHECK

In this example, if an input/output error occurs in either of the READ
statements or if an end-of-file is encountered in the first READ
statement, the appropriate condition will be signaled and the handler
will receive control, print a message, and terminate the program.
However, if an end-of-file is encountered in the second READ statement,
no condition will be signaled and control will be transferred to the
statement indicated in the END= specifier.


Example 3:

   ENABLE (DEFAULT)
    ! First try the "fast" algorithm for inverting a matrix:
      MATRIX1 = FAST_INV (MATRIX)
   HANDLE 
    ! "Fast" algorithm failed; try "slow" one:
      ENABLE (ALL)
         MATRIX1 = SLOW_INV (MATRIX)
      HANDLE 
         WRITE (*, *) 'Cannot invert matrix'
         STOP
      END ENABLE
   END ENABLE

In this example, the function FAST_INV may cause an condition to
signal. If it does, we try again with SLOW_INV. If this still fails,
we print a message and stop. Note the use of nested enable blocks.


Example 4:

   ENABLE (OVERFLOW)
   ! First try a fast algorithm for inverting a matrix.
   :
   DO K = 1, N
      :
     CHECK(OVERFLOW)
   END DO
   :
   HANDLE 
   ! Alternative code which knows that K-1 steps have executed normally.
   :
   END ENABLE

Here we have in-line code for matrix inversion, where the transfer is
made more precise by adding to the enable block a check statement at
the end of each major step.


Example 5:

The following subroutine finds a zero of <f(x)> on an interval
[<a,b>]. It is limited to take one second of real time as measured by the
system clock. If it fails to obtain the requested accuracy after this
time, the condition SOLVER signals with the value -1.

   SUBROUTINE ZERO_SOLVER (A, B, X, TOLERANCE, F)
      REAL A, B, X, TOLERANCE
      INTERFACE; REAL FUNCTION F(X); REAL X; END INTERFACE

      INTEGER  COUNT, RATE ! Local variables
      :
   ! The following code is executed every iteration
      CALL SYSTEM_CLOCK(COUNT, RATE)
   ! If time has run out, return, signaling condition SOLVER.
        IF (COUNT > RATE) THEN
           SIGNAL (SOLVER,-1)
         END IF
      END IF
      :
   END SUBROUTINE ZERO_SOLVER 



The application code handles the exception in a way that only it knows.
An example is:

   :
   ENABLE(SOLVER)
       CALL ZERO_SOLVER (A, B, X, TOLERANCE, F)
   HANDLE
   ! Exceeded the amount of time, TIME.  Fix up and go on.
      :
   END ENABLE 
   : 



Example 6:

      REAL FUNCTION CABS (Z)
        COMPLEX Z
! Calculate the complex absolute value, using a scaled algorithm if
!   the straightforward calculation underflows or overflows. Set the
!   overflow condition to the value -1 if the result is too large to
!   be representable.

        REAL S, ZI, ZR
        INTRINSIC REAL, AIMAG, SQRT, ABS, MAX

        ZR = REAL(Z)
        ZI = AIMAG(Z)

        ENABLE(OVERFLOW, UNDERFLOW)

!         This is the quick and usual calculation.
          CABS = SQRT(ZR**2 + ZI**2) 

        HANDLE

!         Will try again using a scaled equivalent method.
          S = MAX(ABS(ZR),ABS(ZI))
          ENABLE(OVERFLOW, UNDERFLOW)
            CABS = S*SQRT( (ZR/S)**2 + (ZI/S)**2 ) 
          HANDLE
            CONDITION_VALUE(OVERFLOW,K)
            IF (K/= 0) THEN
!             The result is too large to be representable.
              SIGNAL(OVERFLOW, -1)
            ELSE 
              CONDITION_VALUE(UNDERFLOW,K)
              IF (K/= 0) THEN
                CABS = S
              END IF
            END IF
          END ENABLE 
  
        END ENABLE

      END FUNCTION CABS

This illustrates the setting of a special condition value when the
problem really has a result that overflows.  


Example 7:

      MODULE LIBRARY
      ...
      CONTAINS
         SUBROUTINE B
            ...
            X = Y*Z(I) ! No condition enabled.
            IF(X>10.)SIGNAL(LIBRARY_ERROR)
            ...
         END SUBROUTINE B
      END MODULE LIBRARY

      SUBROUTINE A
         USE LIBRARY
         ENABLE (OVERFLOW, LIBRARY_ERROR)
            CALL B
         HANDLE
            ...
         END ENABLE
      END SUBROUTINE A

This illustrates the use of a library module that may signal the
condition LIBRARY_ERROR. The signal statement causes a transfer to the
handler in the calling subroutine A.

We also illustrate the effect of an intrinsic condition that is not
enabled.  An overflow in Y*Z(I) would cause  OVERFLOW to signal and
hence a transfer to the handler in the calling subroutine A. An
out-of-range subscript value I might or might not signal BOUND_ERROR.
.......................................................................

107/5. After '<end-do-stmt,>' add 'an <enable-stmt>,'.
.......................................................................

122/17-18. Replace sentence by 
   If an error condition (9.4.3) occurs during execution of an
   input/output statement that lies in an enable block for the IO_ERROR
   condition or contains an ERR= specifier:
.......................................................................

122/25. After 'continues with' add 'the handle block or'
.......................................................................

122/27-28. Replace sentence by 
   If an end-of-file condition (9.4.3) occurs and no error condition
   (9.4.3) occurs during execution of an input/output statement that
   lies in an enable block for the END_OF_FILE condition or contains an
   END= specifier:
.......................................................................

122/34. After 'continues with' add 'the handle block or'
.......................................................................

122/37-38. Replace sentence by 
   If an end-of-record condition (9.4.3) occurs and no error condition
   (9.4.3) occurs during execution of an input/output statement that
   lies in an enable block for the END_OF_RECORD condition or contains an
   EOR= specifier:
.......................................................................

123/6. After 'continues with' add 'the handle block or'
........................................................................

125/10. Before 'contains' add 'is not in a enable block for the IO_ERROR
        condition and '.
........................................................................

125/11. Before 'contains' add 'is not in a enable block for the 
        END_OF_FILE condition and '.
........................................................................

125/13. Before 'contains' add 'is not in a enable block for the
        END_OF_RECORD condition and '.
........................................................................

<<15. CONDITIONS>>

In this section, the conditions supported by the standard and a
statement for obtaining the value of a condition are specified.


The CONDITION_VALUE statement returns the value of a condition.

R835k <condition-value-stmt> <<is>> CONDITION_VALUE (<condition-name>, #
                                    # [STAT=]<scalar-default-int-variable>)

Constraint: The condition name must not be DEFAULT, IO, FLOATING,
            INTEGER, or ALL.

The STAT= variable is given the value 0 if the condition is quiet and a
nonzero value otherwise. Negative values can occur only following
execution of a SIGNAL statement.

<<15.1 User condition>>

If a condition is not intrinsic, it is a user condition. Such a
condition can be set only by a SIGNAL statement.


<<15.2 Storage and addressing conditions>>

ALLOCATION_ERROR
This occurs when the processor is unable to perform an allocation
requested by an ALLOCATE statement (6.3.1) containing no STAT=
specifier. It is not signaled by an ALLOCATE statement containing a
STAT= specifier. It signals outside enable blocks.

DEALLOCATION_ERROR
This occurs when the processor detects an error when executing a
DEALLOCATE statement (6.3.1) containing no STAT= specifier. It is not
signaled when executing a DEALLOCATE statement containing a STAT=
specifier. It signals outside enable blocks.

INSUFFICIENT_STORAGE
This occurs when the processor is unable to find sufficient storage to
continue execution.  It is may occur prior to the execution of the 
first executable statement of a main program or procedure and it may 
occur during the execution of an executable statement. It signals
outside enable blocks.

BOUND_ERROR
This occurs when an array subscript, array section subscript, or
substring range violates its bounds.  This does not include violations
of the requirements derived from the size of an assumed-size array.
Whether it signals outside enable blocks is processor dependent.

ARRAY_ERROR
This occurs when an array operation or assignment does not conform in
shape or when a many-one array section (6.2.2.3.2) appears on the left
of the equals in an assignment statement or as an input item in a READ
statement. Whether it signals outside enable blocks is processor
dependent.


UNDEFINED
This occurs when a value that is required for an operation is detected
by the processor to be undefined. Whether it signals outside enable
blocks is processor dependent.



<<15.3 Input/output conditions>>

IO_ERROR
This occurs when an input/output error (9.4.3) is encountered in an
input/output statement containing no IOSTAT= or ERR= specifier. It is
not signaled when executing an input/output statement containing an
IOSTAT= or ERR= specifier. It signals outside enable blocks.

END_OF_FILE
This occurs when an end-of-file condition (9.4.3) is encountered in an
input statement containing no IOSTAT= or END= specifier. It is
not signaled when executing an input statement containing an
IOSTAT= or ERR= specifier. It signals outside enable blocks.


END_OF_RECORD
This occurs when an end-of-record condition (9.4.3) is encountered in
an input statement containing no IOSTAT= or EOR= specifier. It is
not signaled when executing an input statement containing an
IOSTAT= or ERR= specifier. It signals outside enable blocks.




<<15.4 Floating-point conditions>>

OVERFLOW
This condition occurs when the result for an intrinsic real or complex
operation has a very large absolute value. It signals outside enable blocks.

UNDERFLOW
This condition occurs when the result for an intrinsic real or complex
operation has a very small absolute value. A processor that does not
conform to IEC 559:1989 is required to set this condition when
requested to do so by a SIGNAL statement, but is not required to set it
otherwise. Whether it signals outside enable blocks is processor dependent.


DIVIDE_BY_ZERO
This condition occurs when a real or complex division has a zero
denominator. It signals outside enable blocks.

INEXACT
This condition occurs when the result of a real or complex operation is
not exact. A processor that does not conform to IEC 559:1989 is
required to set this condition when requested to do so by a SIGNAL
statement, but is not required to set it otherwise. Whether it signals
outside enable blocks is processor dependent.


INVALID
This condition occurs when a real or complex operation is invalid. A
processor that does not conform to IEC 559:1989 is required to set this
condition when requested to do so by a SIGNAL statement, but is not
required to set it otherwise. Whether it signals outside enable blocks
is processor dependent.


<<15.5 Integer conditions>>

INTEGER_OVERFLOW
This condition occurs when the result for an intrinsic integer
operation has a very large absolute value. Whether it signals outside
enable blocks is processor dependent.



INTEGER_DIVIDE_BY_ZERO
This condition occurs when an integer division has a zero denominator.
It signals outside enable blocks.

<<15.6 Intrinsic procedure condition>>

INTRINSIC
This condition occurs when an intrinsic procedure is unsuccessful.
It signals outside enable blocks.

<<15.7 Combination conditions>>

Each of the following conditions may be specified on an enable statement
or a check statement and is equivalent to specifying a list of 
conditions. 

DEFAULT
This condition is equivalent to the list: GENERIC, ALLOCATION_ERROR,
DEALLOCATION_ERROR, INSUFFICIENT_STORAGE, IO_ERROR, END_OF_FILE,
END_OF_RECORD, OVERFLOW, DIVIDE_BY_ZERO, INTRINSIC.

IO
This condition is equivalent to listing all the input/output conditions.

FLOATING
This condition is equivalent to listing all the floating-point conditions.

INTEGER
This condition is equivalent to listing the two integer conditions.

ALL
This condition is equivalent to listing all the conditions.

