CVS difference for ais/ai-00224.txt

Differences between 1.22 and version 1.23
Log of other versions for file ais/ai-00224.txt

--- ais/ai-00224.txt	2002/02/07 04:56:41	1.22
+++ ais/ai-00224.txt	2002/06/14 23:48:55	1.23
@@ -1,4 +1,4 @@
-!standard 11.5(1-8)                                  00-11-03  AI95-00224/04
+!standard 11.5(1-8)                                  02-06-13  AI95-00224/05
 !standard 11.5(27)
 !class amendment 99-11-19
 !status work item 99-11-19
@@ -73,31 +73,43 @@
 On parameter:
 A checking pragma applies to the named check in a specific region (see below),
-and applies to all entities in that region. A pragma Suppress applies from the
-place of the pragma to the end of the innermost enclosing declarative region. A
-pragma Unsuppress given in a declarative_part applies from the place of the
-pragma to the end of the innermost enclosing declarative region, but not in any
-subunits of that declarative_part. A pragma Unsuppress given in a
-package_specification from the place of the pragma to the end of the
-specification. The region to which a pragma Unsuppress given as a configuration
-pragma applies is implementation-defined.
+and applies to all entities in that region. A checking pragma given in a
+declarative_part or immediately within a package_specification applies from the
+place of the pragma to the end of the innermost enclosing declarative region.
+The region for a checking pragma given as a configuration pragma is the
+entire compilation unit to which it applies. It is implementation-defined
+if the pragma applies to compilation units other that those specified by
+the definition of configuration pragma (see 10.1.5).
+AARM Note: This means that a configuration checking pragma may automatically
+apply to bodies and subunits (as is true of other checking pragmas), but it
+does not have to.
 A pragma Suppress gives permission to an implementation to omit the named check
 for any entities to which it applies. A pragma Unsuppress revokes the permission
-to omit the named check for any entities to which it applies. If there is no
-such permission at the point of a pragma Unsuppress, then the pragma has no
-effect. If permission has been given to suppress a given check, the check is
-said to be suppressed.
+given by pragma Suppress to omit the named check for any entities to which it
+applies. If there is no such permission at the point of a pragma Unsuppress,
+then the pragma has no effect. If permission has been given to suppress a given
+check, the check is said to be suppressed.
+AARM Note: Unsuppress does not have an effect on the check suppression implicit
+in pragma Unchecked_Union. However, implementations should insure that it
+does apply to suppression which comes from compiler options (preferably by
+modeling them as pragma Suppress configuration pragmas).
 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 Unsuppress shall allow any
 check names supported by pragma Suppress. An implementation is allowed to add
-additional check names, with implementation-defined semantics.  When
+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.
+An implementation may support an additional parameter on pragma Unsuppress
+similar to the one allowed for pragma Suppress (see J.XX). The meaning of
+such a parameter is implementation-defined.
 Add an additional note after 11.5(29):
 It is possible to give both a pragma Suppress and Unsuppress for the same check
@@ -111,38 +123,42 @@
 J.XX Specific Suppression of Checks
-Checking pragmas can be used to suppress checks on specific entities.
+Pragma Suppress can be used to suppress checks on specific entities.
-The forms of specific checking pragmas are as follows:
+The form of a specific Suppress pragma is as follows:
      pragma Suppress(identifier, [On =>] name);
-     pragma Unsuppress(identifier, [On =>] name);
                                Legality Rules
 The identifier shall be the name of a check (see 11.5). The name shall
 statically denote some entity.
-For a specific checking pragma that is immediately within a
+For a specific Suppress pragma that is immediately within a
 package_specification, the name shall denote an entity (or several overloaded
 subprograms) declared immediately within the package_specification.
                               Static Semantics
-A specific checking pragma applies to the named check from the place of the
+A specific Suppress 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, to the end of the scope
 of the named entity. The pragma applies only to the named entity, or, for a
-subtype, on objects and values of its type. A specific pragma Suppress
+subtype, on objects and values of its type. A specific Suppress pragma
 suppresses the named check for any entities to which it applies (see 11.5).
-The meaning of a specific pragma Unsuppress is implementation-defined.
+Which checks are associated with a specific entity is not defined by this
                          Implementation Permissions
+An implementation is allowed to place restrictions on specific Suppress pragmas.
-An implementation is allowed to place restrictions on specific checking pragmas.
+An implementation may support an entity parameter on pragma Unsuppress (see
@@ -197,7 +213,12 @@
 not fail. This is why the wording is expressed in terms of "revoking the
 permission to omit" rather than "requiring" checks.
+Pragma Unsuppress is defined to affect checks suppressed by a pragma Suppress.
+This is necessary to support pragma Unchecked_Union (which is defined in
+terms of suppressing checks, and these checks cannot be turned on as there
+is no discriminant value with which to make a check).
 This proposal allows nested suppression of checks. That is, checks can be
 "resuppressed" inside of a region where checks are "unsuppressed" (required).
 This is necessary to prevent problems with code where the correctness depends
@@ -217,26 +238,39 @@
 is OK, as the permission to suppress checks can always be ignored. However, the
 situation for Unsuppress is different. If it fails to inherit properly, checks
 might be suppressed that should not be. This could badly break programs.
+We considered eliminating inheritance from all of these programs, as it is
+preferable that a checking pragma be visible in any scope to which it applies.
+However, this is incompatible with both the existing language, and some
+existing implementation.
+We also considered having Unsuppress not inherit, while leaving Suppress alone.
+This has the unfortunate property of having too different models for the
+pragmas. This means that checking can change simply by moving code, as in the
+following example:
-It also is preferable that an Unsuppress pragma be visible in any scope to
-which it applies. This prevents surprises as to why a particular entity is not
-Thus, both to follow the principle of least surprise, and to avoid forcing
-implementations to implement inheritance of checking pragmas, we define
-pragma Unsuppress to not inherit into subunits or package bodies.
-Note that we also extent this to the use of Unsuppress as a configuration
-pragma. We leave the definition of the scope of such a pragma to
-implementations; this avoids perturbing implementations compilation strategies
-for a mostly useless pragma.
-We do have to define Unsuppress as a configuration pragma. Otherwise,
-implementations would be barred from supporting it that way (implementations
-cannot extend language-defined pragmas). But we do not want to force existing
-implementations to make these illegal, nor do we want to force a particular
-meaning on implementations. Thus, this usage is implementation-defined.
+package body P is
+   pragma Suppress (All_Checks);
+   pragma Unsuppress (Tag_Checks);
+   procedure Proc is separate;
+end P;
+In this model, Tag_Checks are suppressed in Proc depending on whether Proc
+is "inlined" into the package or separate.
+A third alternative is to simply define inheritance to be
+implementation-defined. This was rejected due to the lack of portability
+and that it leaves the language no safer than the existing inheritance model.
+Therefore, we have retained the inheritance model of Ada 95, and it applies
+to pragma Unsuppress as well as Suppress.
+We do make the units to which a checking pragma given as a configuration
+pragma applies implementation-defined. This allows an implementation to
+support inheritance for these without requiring it. These pragmas are rarely
+used explicitly; they primarily are a semantic description of compiler options
+for suppression. We do not want to force implementations to have options apply
+to other compilations (such as subunits).
 Restrictions can be placed on pragma Unsuppress. This is necessary to avoid
@@ -267,13 +301,14 @@
 example? A, B, or the type of A? The answer probably varies from implementation
 to implementation, and there is little value in defining it more tightly.
-Rather than making any effort here, the meaning of pragma Unsuppress with an
-On parameter is implementation-defined. This is done so that existing
-implementations supporting this form can continue to do so. But we expect most
-implementations to define that all such pragmas are ignored.
+We do want to allow implementations to support pragma Unsuppress with an
+On parameter if they support pragma Suppress with an On parameter. This
+requires a specific permission, as implementations are not allowed to extend
+language-defined pragmas.
 A benefit to making On parameters obsolescent is that this also signals
-implementors to spend little or no effort in this area.
+implementors to spend little or no effort in this area, and users to not
+expect vendor effort in this area.
 Implementations should not produce warnings for usages of pragma Unsuppress
@@ -4140,6 +4175,71 @@
+From the minutes of the Columbia ARG meeting (November 17-19, 2000):
+Randy summarized the changes since the April 2000 meeting:
+ Make the second parameter obsolescent because the semantics of this construct
+  is poorly defined and apparently rarely used (UK reports that in 4000
+  instances of the Suppress pragma in 700K lines of code, there were only five
+  uses of the second parameter). As an example of how poorly this feature is
+  currently defined, Randy points out that it is not clear that the need to
+  suppress the constraint check on the value of the expression to be assigned
+  to an object can be done with the syntax ON => object.   Furthermore, Randy
+  stated that under these circumstances Unsuppress (_, On => _) is impossible
+  to define.
+ Remove the symmetry between Suppress and Unsuppress with respect to
+  inheritance, namely, unlike Suppress, Unsuppress is not inherited in package
+  body or subunit.
+ Leave the meaning of Suppress and Unsuppress as configuration pragmas
+  implementation-defined.
+On point 1, it was recommended that there is no need to explicitly mention an
+obsolescence of the second parameter with the Unsuppress pragma in Annex J.
+Instead there should be an Implementation Permission that allows
+implementations to define and provide this feature. Also, a reference to the
+new alternative features in 11.5 should be made in the first paragraph of the
+addition to J.
+Tuck wanted an additional wording to say that the checks that are (un)suppressed are not defined by the standard.
+On point 2, it is very surprising that, without inheritance, in this example
+package body P is
+   pragma Suppress (all_checks);
+   pragma Unsuppress (tag_checks);
+   _
+   procedure blah is separate;_
+end P;
+tag_checks are suppressed in blah depending on whether blah is "inlined" into the package or separate.  One question is whether the pragmas' treatment of inheritance should be symmetric.  The second question is whether inheritance should be permitted at a
ll.  Arguments for safety state that there be no inheritance but many implementations do already implement Suppress inheritance.  Randy pointed out that implementations vary on how this is provided.
+Tuck presented the case for limiting inheritance by saying that a configuration pragma overrides an inherited pragma and that the configuration pragma is overridden when an explicit pragma is specified.  If a unit wants to ensure that it has the checks th
en the pragma Unsuppress must be explicitly specified and it won't be sabotaged by a configuration pragma.  This appears to safely introduce Unsuppress with no changes to implementation regarding inheritance.  While this appears to be a reasonable approach
, it wasn't selling at the meeting, because the rules seemed overly complicated and because of the example above.
+Tuck then tried a different approach, by starting with checking for possible agreement on any of the following points:
+ Unsuppress revokes Suppress permission, including inheritance, namely, revocation overrides inheritance.
+ Configuration pragmas override inheritance (of Suppress) pragma.
+ A (Un)Suppress pragma inside a compilation unit revokes the opposite effect by inheritance or configuration pragmas.
+ Drop inheritance requirement.
+There seemed to be agreement on point 1 and 3, less agreement on point 4 but no convergence on point 2.
+Erhard tried to sell the case for eliminating inheritance as the "safest" approach until a better one is proposed.  Unfortunately, this approach is not upward compatible.
+Tuck suggested four approaches to resolving this, as a way to get convergence:
+ Require inheritance with weak configuration pragma (which is upward compatible)
+ No inheritance, with configuration pragmas as starting point
+ Inheritance is implementation-defined and configuration pragmas override inheritance (which is upward compatible)
+ No configuration pragmas
+Unfortunately this did not produce convergence either and the issue was tabled to let everyone sleep on it.
+The next morning Tuck offered another view regarding the effect of inheritance and configuration with respect to these pragmas: Consider that Suppress pragma provides a set of permissions.  A configuration Suppress provides an initial set of permissions t
o be applied to a compilation unit.  The appearance of a Suppress pragma for a specific check in a compilation unit will add to the set of permissions for that compilation unit if the permission had not already been provided.  The appearance of a Unsuppres
s pragma for a specific check  in a compilation unit will revoke any permission to suppress that check for that compilation unit.  It appeared that this insight was quietly received.
+Randy will revise this AI accordingly.
 From: Randy Brukardt
 Sent: Wednesday, February  6, 2002 at  6:05 PM
@@ -4167,6 +4267,139 @@
 Humm, that probably works. (Assuming we can ever figure out what Suppress does
 - but let's not go there now. :-)
+[Editor's notes, June 13, 2002]
+Wording changes:
+-- Removed specific Unsuppress from Annex J; added an implementation
+   permission to allow supporting it.
+-- Added a note in Annex J pointing at the implementation permission.
+-- Added a sentence in Annex J to point out that the exact checks
+   suppressed by a specific Suppress pragma are not defined by the standard.
+   (That is, the language does not try to define whether the subtype check
+    on assignment to A in A := B belongs to A, to B, or to both.)
+-- Unsuppress now revokes the permissions to suppress given by a pragma
+   Suppress only. This change is necessary to allow Unchecked_Union to
+   use suppression semantics; Unsuppress must not have an effect on
+   Unchecked_Union.
+-- The region to which a configuration pragma Suppress applies is changed to
+   be implementation-defined, but it must at least include the units to
+   which it applies (by the rules of 10.1.5(8)).
+-- The region to which pragma Unsuppress applies is changed to be the same
+   as Suppress. (This means that Unsuppress inherits into bodies and subunits,
+   as Suppress already does).
+The discussion has been updated to reflect the above.
+The first three changes were requested at the November 2000 meeting.
+The fourth change is to reconcile with the "Suppress" semantics of
+Unchecked_Union. Unsuppress must not have an effect on that. This wording
+unfortunately suggests that explicit Unsuppresses should not override
+compiler options (which may not be modeled in terms of Suppress). But there
+doesn't seem to be a choice assuming the Unchecked_Union continues to use
+suppression semantics.
+The rest of the changes come from an analysis of the issues on which we were
+stuck at the November 2000 meeting. Here is the analysis.
+First, inheritance of pragmas inside of units (not configuration pragmas).
+There are three choices:
+1) Both Suppress and Unsuppress inherit into bodies and subunits.
+2) Suppress inherits, Unsuppress does not.
+3) Neither Suppress nor Unsuppress inherits.
+4) The region that Suppress and Unsuppress apply to is implementation-defined,
+   but it is at least the current declarative part or package specification.
+The main case for inheritance is that, in an example like:
+package body P is
+   pragma Suppress (All_Checks);
+   pragma Unsuppress (Tag_Checks);
+   procedure Blah is separate;
+end P;
+Tag_Checks are suppressed in Blah depending on whether Blah is "inlined" into
+the package or separate.
+This problem occurs for both (2) and (3) (in slightly different ways), a point
+for (1). We can't tell if the problem occurs for (4), as it depends on the
+implementation, so no point is awarded.
+On the other hand, safety suggests that Suppress and Unsuppress should be
+explicit. That suggests that there should be no inheritance, a point for (3).
+Again, no point for (4), since the language definition is not safe, although
+a particular implementation can be.
+Since Ada 83 and Ada 95 do have Suppress inheritance, (3) is incompatible with
+the current standard. That is a point for each of the others (one presumes that
+implementations would not change their implementations for (4)).
+However, many compilers do not inherit Suppress, but some do.
+(Note again that it is OK to ignore Suppress inheritance, because it is always
+OK to ignore the permission to omit a check; but it is not OK to ignore
+Unsuppress inheritance.) This could be considered a negative for (1), but
+remember that compilers that do inherit Suppress would have to change for (3).
+In addition, (2) would require two different mechanisms for the two pragmas.
+It is unlikely that any existing compiler supports both currently, so that
+is a negative for (2) as well. Moreover, this is a new feature, so some work
+in implementing it should be expected. Thus we award 1/2 point to
+(4) as it does not require changes in the existing Suppress implementation
+nor a new mechanism for Unsuppress.
+Totalling up the scores in the rather crazy assumption that these factors
+should be given equal weight, we see that (1) has two points, (2) and (2)
+have one point each, and (4) has one and 1/2 points. Therefore (1) is selected.
+(It is annoying that safety is the point that loses out here, but this seems to
+be the necessary conclusion, as it is true of the two highest scoring options.)
+Note that (1) has the additional advantage of having the simplest model (the
+same as the existing standard's model).
+Having selected full inheritance as the model, we now turn to configuration
+We have (at least) the following options:
+1) Checking pragmas as configuration pragmas are implementation-defined.
+2) Configuration pragmas inherit in the same way as pragmas inside a unit, and
+   are essentially equivalent to putting the pragma at the very beginning of
+   each unit to which it applies.
+3) Configuration pragmas never inherit, but otherwise are equivalent to putting
+   the pragma at the very beginning of each unit to which it applies.
+Other options are rendered moot by the adoption of inheritance everywhere for
+'regular' pragmas.
+For all of these options, the configuration pragma (and any inheritance) can
+be overridden by an explicit pragma inside the unit. This is clearly an
+important property.
+The definition of (3) seems too gruesome for words (or wording), as it involves
+different regions of effect for configuration and regular pragmas. It also may
+be hard for compilers to implement, especially those that currently do support
+Thus the choice boils down to whether it is important to specify the region of
+effect for configuration pragmas, or whether "implementation-defined" is good
+enough. It should be noted that the explicit use of pragma Suppress and
+Unsuppress as configuration pragmas is rare. Rather these pragmas as
+configuration pragmas are usually used as compiler options. Compiler options
+are implementation-defined, so it doesn't seem bad to make these pragmas
+implementation-defined also. In particular, in the example above, no one would
+be surprised if the checking in Blah differs from the checking in P if the
+compiler options were different. So forcing inheritance of pragmas seems to
+have much less value here than it does in the explicit pragma case. Indeed,
+users probably would be surprised if the compiler option from P did
+inherit into Blah.
+The author finds this argument compelling. He hopes that the full ARG agrees.

Questions? Ask the ACAA Technical Agent