3.2.4 Validity Checking
The Ada Reference Manual has specific requirements for checking
for invalid values. In particular, RM 13.9.1 requires that the
evaluation of invalid values (for example from unchecked conversions),
not result in erroneous execution. In GNAT, the result of such an
evaluation in normal default mode is to either use the value
unmodified, or to raise Constraint_Error in those cases where use
of the unmodified value would cause erroneous execution. The cases
where unmodified values might lead to erroneous execution are case
statements (where a wild jump might result from an invalid value),
and subscripts on the left hand side (where memory corruption could
occur as a result of an invalid value).
The -gnatVx switch allows more control over the validity
x argument is a string of letters that
indicate validity checks that are performed or not performed in addition
to the default checks described above.
- All validity checks.
All validity checks are turned on.
That is, -gnatVa is
equivalent to gnatVcdfimorst.
- Validity checks for copies.
The right hand side of assignments, and the initializing values of
object declarations are validity checked.
- Default (RM) validity checks.
Some validity checks are done by default following normal Ada semantics
(RM 13.9.1 (9-11)).
A check is done in case statements that the expression is within the range
of the subtype. If it is not, Constraint_Error is raised.
For assignments to array components, a check is done that the expression used
as index is within the range. If it is not, Constraint_Error is raised.
Both these validity checks may be turned off using switch -gnatVD.
They are turned on by default. If -gnatVD is specified, a subsequent
switch -gnatVd will leave the checks turned on.
Switch -gnatVD should be used only if you are sure that all such
expressions have valid values. If you use this switch and invalid values
are present, then the program is erroneous, and wild jumps or memory
overwriting may occur.
- Validity checks for elementary components.
In the absence of this switch, assignments to record or array components are
not validity checked, even if validity checks for assignments generally
(-gnatVc) are turned on. In Ada, assignment of composite values do not
require valid data, but assignment of individual components does. So for
example, there is a difference between copying the elements of an array with a
slice assignment, compared to assigning element by element in a loop. This
switch allows you to turn off validity checking for components, even when they
are assigned component by component.
- Validity checks for floating-point values.
In the absence of this switch, validity checking occurs only for discrete
values. If -gnatVf is specified, then validity checking also applies
for floating-point values, and NaNs and infinities are considered invalid,
as well as out of range values for constrained types. Note that this means
that standard IEEE infinity mode is not allowed. The exact contexts
in which floating-point values are checked depends on the setting of other
options. For example,
(the order does not matter) specifies that floating-point parameters of mode
in should be validity checked.
- Validity checks for
in mode parameters
Arguments for parameters of mode
in are validity checked in function
and procedure calls at the point of call.
- Validity checks for
in out mode parameters.
Arguments for parameters of mode
in out are validity checked in
procedure calls at the point of call. The
'm' here stands for
modify, since this concerns parameters that can be modified by the call.
Note that there is no specific option to test
but any reference within the subprogram will be tested in the usual
manner, and if an invalid value is copied back, any reference to it
will be subject to validity checking.
- No validity checks.
This switch turns off all validity checking, including the default checking
for case statements and left hand side subscripts. Note that the use of
the switch -gnatp suppresses all run-time checks, including
validity checks, and thus implies -gnatVn. When this switch
is used, it cancels any other -gnatV previously issued.
- Validity checks for operator and attribute operands.
Arguments for predefined operators and attributes are validity checked.
This includes all operators in package
the shift operators defined as intrinsic in package
and operands for attributes such as
Pos. Checks are also made
on individual component values for composite comparisons, and on the
expressions in type conversions and qualified expressions. Checks are
also made on explicit ranges using `..' (e.g. slices, loops etc).
- Validity checks for parameters.
This controls the treatment of parameters within a subprogram (as opposed
to -gnatVi and -gnatVm which control validity testing
of parameters on a call. If either of these call options is used, then
normally an assumption is made within a subprogram that the input arguments
have been validity checking at the point of call, and do not need checking
again within a subprogram). If -gnatVp is set, then this assumption
is not made, and parameters are not assumed to be valid, so their validity
will be checked (or rechecked) within the subprogram.
- Validity checks for function returns.
The expression in
return statements in functions is validity
- Validity checks for subscripts.
All subscripts expressions are checked for validity, whether they appear
on the right side or left side (in default mode only left side subscripts
are validity checked).
- Validity checks for tests.
Expressions used as conditions in
statements are checked, as well as guard expressions in entry calls.
The -gnatV switch may be followed by
a string of letters
to turn on a series of validity checking options.
specifies that in addition to the default validity checking, copies and
function return expressions are to be validity checked.
In order to make it easier
to specify the desired combination of effects,
the upper case letters
be used to turn off the corresponding lower case option.
turns on all validity checking options except for
checking of in out procedure arguments.
The specification of additional validity checking generates extra code (and
in the case of -gnatVa the code expansion can be substantial).
However, these additional checks can be very useful in detecting
uninitialized variables, incorrect use of unchecked conversion, and other
errors leading to invalid values. The use of pragma
is useful in conjunction with the extra validity checking, since this
ensures that wherever possible uninitialized variables have invalid values.
See also the pragma
Validity_Checks which allows modification of
the validity checking mode at the program source level, and also allows for
temporary disabling of validity checks.