Version 1.1 of ais/ai-00224.txt

Unformatted version of ais/ai-00224.txt version 1.1
Other versions for file ais/ai-00224.txt

!standard 11.5(1-8)          99-11-19 AI95-00224/01
!standard 11.5(27)
!class amendment 99-11-19
!status work item 99-11-19
!status received 99-11-19
!priority Medium
!difficulty Medium
!subject pragma Require
!summary
A pragma is introduced to require checking in a declarative region, irrespective of the use of pragma Suppress.
!problem
Ada code sometimes depends on the canonical checking semantics of the language. Consider, for instance, an integer saturation arithmetic package. The multiply operation might look like:
function "*" (Left, Right : Saturation_Type) return Saturation_Type is begin
return Integer(Left) * Integer(Right);
exception
when Constraint_Error =>
return Saturation_Type'Last;
end "*";
This function will not work properly without overflow checking. Ada 95 does not provide a way to indicate this to the compiler and programmers.
!proposal
A new pragma Require is defined.
pragma Require (identifier [, [On =>] name]);
The arguments of Require are the same as Suppress. Require can be used in the same places as Suppress, with the same scoping rules.
Pragma Require means that the given check must be performed.
!wording
Define "Checking pragmas" and add pragma Require to 11.5(1) ("Checking pragmas" is in italics):
Checking pragmas give an implementation instructions on handling language-defined checks. A pragma Suppress gives permission to an implementation to omit certain language-defined checks, while A pragma Require requires an implementation to make certain language-defined checks.
Add pragma Require to 11.5(3-4):
The forms of checking pragmas are as follows:
pragma Require(identifier [, [On =>] name]); pragma Suppress(identifier [, [On =>] name]);
Change 11.5(5) to apply to checking pragmas:
A checking pragma is allowed only immediately within a declarative_part, immediately within a package_specification, or as a configuration pragma.
Change 11.5(7) to apply to checking pragmas:
For a checking pragma that is immediately within a package_specification and includes a name, the name shall denote an entity (or several overloaded subprograms) declared immediately within the package_specification.
Change 11.5(8) to define the meaning of pragma Require:
A checking pragma applies to the named check from the place of the pragma to the end of the innermost enclosing declarative region, or, if the pragma is given in a package_specification and includes a name, to the end of the scope of the named entity. If the pragma includes a name, the pragma applies only to the named entity, or, for a subtype, on objects and values of its type. Otherwise, the pragma applies to all entities. A pragma Suppress gives permission to an implementation to omit the named check for any entities to which it applies, but not for any entity to which a pragma Require applies. If permission has been given to suppress a given check, the check is said to be suppressed.
Change 11.5(27) to apply to checking pragmas:
An implementation is allowed to place restrictions on checking pragmas, subject only to the requirement that pragma Require shall allow any arguments supported by pragma Suppress. An implementation is allowed to add additional check names, with implementation-defined semantics. When Overflow_Check has been suppressed, an implementation may also suppress an unspecified subset of the Range_Checks.
!example
We can use pragma Require to insure that checking occurs in the saturation multiply function given earlier:
function "*" (Left, Right : Saturation_Type) return Saturation_Type is
pragma Require (Overflow_Check);
begin return Integer(Left) * Integer(Right); exception when Constraint_Error => return Saturation_Type'Last; end "*";
!discussion
Ada 95 provides an easy way to suppress checking over large areas of program text. Pragma Suppress can be used in a package specification to apply to an entire package, or even as a configuration pragma to apply to the entire program.
It is common for production versions of applications to be delivered with checking suppressed (perhaps for better performance or smaller code size). If pragma Suppress is applied to an entire package or program, code that requires checking will start to fail. Ada code that depends on the canonical checking semantics is not common, but it occurs frequently enough that most Ada programmers have been bitten by this problem at one time or another.
The problem is made worse by the fact that Ada 95 does not provide any way to turn off pragma Suppress over a smaller, inner region of the program. Therefore, fixing the problem requires moving the pragma Suppresses to individual packages and/or subprograms, which is clearly error-prone.
The pragma proposed here can be used both as a preventative measure (to insure that the code continues to work if a later programmer applies Suppress to the unit) and as a repair when checks are suppressed where they are required.
Note that the pragma Suppress that causes problems may not be explicit; many compilers include an option switch that effectively adds pragma Suppress to the start of each compilation unit.
The presence of pragma Require has no effect on compiler optimization of checks. A compiler is still allowed to remove checks that it can prove will not fail.
An early proposal called this pragma "Unsuppress". This name has two problems. First, it is a dubious English word; Ada pragmas are usually English words or phrases. Secondly, the preventative use of this pragma is very important, but "Unsuppress" appears to denote something that can only be used when checks actually are suppressed. This would likely lead to the under-use of the pragma as a preventative.
This proposal does not allow suppressing checks inside of a checking required region. Such "resuppression" of checks could be supported, but does not seem important and would add implementation complexity (an implementation would need a stack of suppress and require pragmas). While it is possible for a programmer to require checks over an entire program, this is not the intended use of pragma Require. It is intended to be used in subprograms and blocks where checking is required.
An implementation ought to display a warning if an attempt to give a pragma Suppress occurs in a region governed by a pragma Require for the same check, as the Suppress can have no effect.
Restrictions can be placed on pragma Require. This is necessary to avoid burdening implementations. For instance, some implementations cannot support fine-grained suppression of single objects, and we don't want to start requiring that. We do require that anything supported for Suppress is also supported for Require, because it is important to be able to "unsuppress" checks suppressed over a larger area. Note that the reverse is not true; implementations can support more of Require than of Suppress if they desire.
!appendix

*************************************************************

From: Randy Brukardt
Sent: Friday, November 19, 1999 7:34 PM

I've created this AI based on the discussion at the last ARG meeting.

I made one major change: based on the problem statement, the name "Unsuppress"
is the wrong name. In its intended use, we do not necessarily know that a
pragma Suppress has been applied to a region. Therefore, I renamed the pragma
to the more meaningful name "Require". I expect to catch some flak for this.

I find the preventative use of Require quite important, and quite in keeping
with the philosophy of Ada (make sure problems don't happen in the first
place).

It seems wrong to use a hypothetical pragma Unsuppress as a preventative: it
isn't undoing anything! Indeed, Ada users could imagine that it isn't allowed
unless there is a Suppress pragma to undo, and in that case, they would not
use it as a preventative.

I wonder if this entire clause shouldn't be renamed; it now is more about
controlling checks than about suppressing them.

One interesting issue: should pragma Require be allowed as a configuration
pragma? I have left it in, as that would allow effectively preventing the
adding of any pragma Suppresses to a program. That might be useful to some
paranoid organization. It also takes more words to disallow it than to allow
it.

Another interesting issue: should we allow "resuppression" of checks? I don't
feel strongly either way, but selected the current write-up because it was
more natural for pragma Require. The only way I see to support "resuppression"
is to write paragraph 8 in terms of "revoking the permission" to suppress
checks, which would complicate the description and would fit a pragma named
Unsuppress much better. It would also mean that a pragma Require would be
meaningless as a configuration pragma, as it would have no effect.

Having the pragma have no effect in some circumstances might be a impediment
to using it as a preventive, as a naive implementation of Ada might spew out
a warning everytime such a pragma occurs. I don't think we can say "don't warn
about this" in the reference manual, but without some guideance in this area,
I can see implementors going through the RM and implementing each pragma in
the "obvious" way [Janus/Ada, for instance, warns on any pragma that has no
effect], which would be the wrong thing to do in this case.

                        Randy.

*************************************************************


Questions? Ask the ACAA Technical Agent