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.
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 checks subject to suppression include all the checks defined by
the Ada standard, the additional implementation defined checks
Alignment_Check
, Atomic_Synchronization
, and
Validity_Check
, as well as any checks introduced using
pragma Check_Name
.
The -gnatp switch has no effect if a subsequent
-gnat-p switch appears.
Overflow checks are always enabled by this switch. The argument controls the mode, using the codes
Long_Long_Integer
). Overflow checking ensures that
the result fits in this larger integer type.
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.
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.