3.2.6 Run-Time Checks

By default, the following checks are suppressed: integer overflow
checks, stack overflow checks, and checks for access before
elaboration on subprogram calls. All other checks, including range
checks and array bounds checks, are turned on by default. The
following gcc switches refine this default behavior.

-gnatp

This switch causes the unit to be compiled
as though pragma Suppress (All_checks)
had been present in the source. Validity checks are also eliminated (in
other words -gnatp also implies -gnatVn.
Use this switch to improve the performance
of the code at the expense of safety in the presence of invalid data or
program bugs.

Note that when checks are suppressed, the compiler is allowed, but not
required, to omit the checking code. If the run-time cost of the
checking code is zero or near-zero, the compiler will generate it even
if checks are suppressed. In particular, if the compiler can prove
that a certain check will necessarily fail, it will generate code to
do an unconditional “raise”, even if checks are suppressed. The
compiler warns in this case. Another case in which checks may not be
eliminated is when they are embedded in certain run time routines such
as math library routines.

Of course, run-time checks are omitted whenever the compiler can prove
that they will not fail, whether or not checks are suppressed.

Note that if you suppress a check that would have failed, program
execution is erroneous, which means the behavior is totally
unpredictable. The program might crash, or print wrong answers, or
do anything else. It might even do exactly what you wanted it to do
(and then it might start failing mysteriously next week or next
year). The compiler will generate code based on the assumption that
the condition being checked is true, which can result in disaster if
that assumption is wrong.

The -gnatp switch has no effect if a subsequent
-gnat-p switch appears.

-gnat-p

This switch cancels the effect of a previous gnatp switch.

-gnato??

This switch controls the mode used for computing intermediate
arithmetic integer operations, and also enables overflow checking.
For a full description of overflow mode and checking control, see
the “Overflow Check Handling in GNAT” appendix in this
User's Guide.

Overflow checks are always enabled by this switch. The argument
controls the mode, using the codes

1 = STRICT
In STRICT mode, intermediate operations are always done using the
base type, and overflow checking ensures that the result is within
the base type range.

2 = MINIMIZED
In MINIMIZED mode, overflows in intermediate operations are avoided
where possible by using a larger integer type for the computation
(typically Long_Long_Integer). Overflow checking ensures that
the result fits in this larger integer type.

3 = ELIMINATED
In ELIMINATED mode, overflows in intermediate operations are avoided
by using multi-precision arithmetic. In this case, overflow checking
has no effect on intermediate operations (since overflow is impossible).

If two digits are present after -gnato then the first digit
sets the mode for expressions outside assertions, and the second digit
sets the mode for expressions within assertions. Here assertions is used
in the technical sense (which includes for example precondition and
postcondition expressions).

If one digit is present, the corresponding mode is applicable to both
expressions within and outside assertion expressions.

If no digits are present, the default is to enable overflow checks
and set STRICT mode for both kinds of expressions. This is compatible
with the use of -gnato in previous versions of GNAT.

Note that the -gnato?? switch does not affect the code generated
for any floating-point operations; it applies only to integer
semantics.
For floating-point, GNAT has the Machine_Overflows
attribute set to False and the normal mode of operation is to
generate IEEE NaN and infinite values on overflow or invalid operations
(such as dividing 0.0 by 0.0).

The reason that we distinguish overflow checking from other kinds of
range constraint checking is that a failure of an overflow check, unlike
for example the failure of a range check, can result in an incorrect
value, but cannot cause random memory destruction (like an out of range
subscript), or a wild jump (from an out of range case value). Overflow
checking is also quite expensive in time and space, since in general it
requires the use of double length arithmetic.

Note again that the default is -gnato00, so overflow checking is
not performed in default mode. This means that out of the box, with the
default settings, GNAT does not do all the checks expected from the
language description in the Ada Reference Manual. If you want all constraint
checks to be performed, as described in this Manual, then you must
explicitly use the -gnato?? switch either on the gnatmake or
gcc command.

-gnatE

Enables dynamic checks for access-before-elaboration
on subprogram calls and generic instantiations.
Note that -gnatE is not necessary for safety, because in the
default mode, GNAT ensures statically that the checks would not fail.
For full details of the effect and use of this switch,
See Compiling Using gcc.

-fstack-check

Activates stack overflow checking. For full details of the effect and use of
this switch see Stack Overflow Checking.

The setting of these switches only controls the default setting of the
checks. You may modify them using either Suppress (to remove
checks) or Unsuppress (to add back suppressed checks) pragmas in
the program source.