Version 1.4 of ai12s/ai12-0374-1.txt

Unformatted version of ai12s/ai12-0374-1.txt version 1.4
Other versions for file ai12s/ai12-0374-1.txt

!standard 9.5(24/5)          20-06-01 AI12-0374-1/03
!standard 9.5(27/5)
!standard 9.5(34/5)
!standard 9.5(36/5)
!standard 9.5(47/5)
!standard 9.5(49/5)
!standard 9.5(65/5)
!standard 9.5(68/5)
!standard 13.1.1(18.1/4)
!status Amendment 1-2012 20-05-08
!class Amendment 20-03-22
!status work item 20-03-22
!status received 20-03-22
!priority Medium
!difficulty Medium
!subject Fixes for Nonblocking
!summary
[Editor's note: Although not approved, this AI is included in the draft 25 RM in order that review of Nonblocking be simplified.]
(1) Generic units that are declared Nonblocking use the "and" of all of the formal parameters as their nonblocking expression.
(2) Subprograms that make dispatching calls may define their Nonblocking aspects in terms of their own references and calls on potentially blocking operations, combined with the Nonblocking aspects of the particular dispatching operations they invoke on particular class-wide parameters or globals.
(3) The Nonblocking aspect may be specified for nonfirst subtypes, and referenced via the corresponding attribute. If not specified, the aspects are inherited from the subtype on which the subtype is based.
The Nonblocking aspect of a subprogram must account for any potentially blocking operations involved in evaluating assertion expressions (including preconditions, postconditions, predicates, and type invariants) that would apply to a call on that subprogram.
The Nonblocking aspect for a private type or a private extension must account for evaluation of assertion expressions that might occur as part of default initialization, finalization, adjustment if nonlimited, and conversion/membership in the case of a private extension.
!problem
(1) AI12-0079-3 has redesigned Global to be more automatic for generic declarations. Something similar should be done for Nonblocking for generic units.
(2) Stream attributes internally make dispatching calls on the stream read/write routines, which can be user written. In general for a subprogram that internally makes dispatching calls, we probably need a way to specify its Nonblocking aspect in terms of the Nonblocking aspects of the dispatching calls performed on a given classwide object, in combination with the nonblocking of the subprogram as a whole.
(3) A predicate expression can potentially block. However, there is currently no way to indicate that the predicate of a type has blocking behavior. This means that a nonblocking type used in a supposedly nonblocking subprogram can in fact block if the predicate blocks.
As part of a call on a subprogram, we might need to evaluate various assertion expressions in the form of preconditions, predicates, postconditions, and/or type invariants, and these might invoke a potentially blocking operation.
!proposal
(See Summary.)
!wording
(1) Add after 9.5(27/5):
For a generic unit G, if the aspect Nonblocking is statically true for G (by inheritance or specification), then the nonblocking expression for G is the and of the nonblocking attribute for each formal parameter of G.
AARM Reason: This means that an instance of this generic will be nonblocking only if all of the formal parameters are nonblocking (see below). This is the most usable definition. If one wants a generic whose instantiations will always be nonblocking, Nonblocking can be specified on the formal parameters.
(2) Add after 9.5(49/5):
For a prefix X denoting an object of a class-wide type T'Class, the following attribute is defined:
X'Nonblocking(dispatching_operation_set)
X'Nonblocking(dispatching_operation_set) represents the AND of the Nonblocking aspect of the tagged type T1 identified by the tag of X, and the Nonblocking aspects of the dispatching operations of T1 corresponding to the specified dispatching operations of T (or all dispatching operations of T if the set is the reserved word ALL). If a /dispatching_/selector_name within the set denotes multiple dispatching operations of T, the Nonblocking aspects of all of the corresponding dispatching operations of T1 are ANDed together.
[Editor's note: This also reflects a minor change for (3).]
(3) Modify 9.5(24/5):
For a program unit, task entry, formal package, formal subprogram, formal object of an anonymous access-to-subprogram type, enumeration literal, and for a {sub}type (including a formal {sub}type), the following language-defined operational aspect is defined:
Replace 9.5(34/5):
For a full type declaration that has a partial view, the aspect is the same as that of the partial view.
with:
For the base type of a scalar (sub)type, the Nonblocking aspect is the Boolean literal True.
AARM Reason: The first subtype of a scalar type can allow
blocking (which can be useful so a predicate can allow blocking), but the base type is always Nonblocking. We need this so the Nonblocking value is well-defined for any subtype that is built from the base type (T'Base). T'Base of any scalar type, including a generic formal type, is always nonblocking.
Modify 9.5(36/5):
Unless directly specified, for a formal {sub}type, formal package, or formal subprogram, the Nonblocking aspect is that of the actual {sub}type, package, or subprogram.
Modify 9.5(47/5):
S'Nonblocking
Denotes whether default initialization, finalization, assignment, predefined operators, and (in the case of access-to-subprogram subtypes) a subprogram designated by a value of {sub}type S are considered nonblocking; the type of this attribute is the predefined type Boolean. S'Nonblocking represents the nonblocking expression of S; evaluation of S'Nonblocking evaluates that expression.
Modify 9.5(49/5):
X'Nonblocking
Denotes whether the {sub}type of X is considered nonblocking; the type of this attribute is the predefined type Boolean. X'Nonblocking represents the nonblocking expression of X; evaluation of X'Nonblocking evaluates that expression. [S'Nonblocking represents the nonblocking expression of S; evaluation of S'Nonblocking evaluates that expression.]
Add after 9.5(65/5):
For a subtype for which aspect Nonblocking is True, any predicate expression that applies to the subtype shall only contain constructs that are allowed immediately within a nonblocking program unit.
Modify 9.5(68/5):
Aspect Nonblocking shall be specified for {the first subtype of} a derived type only if it fully conforms to the nonblocking expression of the ancestor {sub}type or if it is specified to have the Boolean literal True. {Aspect Nonblocking shall be specified for a nonfirst subtype S only if it fully conforms to the nonblocking expression of the subtype identified in the subtype_indication defining S or if it is specified to have the Boolean literal True. Aspect Nonblocking shall be specified for a first subtype S that completes an incomplete or partial view P only if it fully conforms to the nonblocking expression of the subtype P or if it is specified to have the Boolean literal True.}
Modify AARM 9.5(88.f/5):
for checking in P, default initialization, finalization, [or] assignment{, or conversion to} [of] a [composite] formal {sub}type F is considered to call subprograms that have the nonblocking aspect of F'Nonblocking, and this is checked for conformance against that of P as described above. [These operations of an elementary formal type are considered nonblocking, and thus require no checks.]
Modify 13.1.1(18.1/4):
If an aspect of a derived type {(or its first subtype)} is inherited from an ancestor {(sub)}type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type {(or its first subtype)}, unless otherwise specified in this International Standard. {If an aspect of a nonfirst subtype is inherited from the subtype in the subtype_indication that defines it, and has the value True, the inherited value shall not be overridden to have the value False for the nonfirst subtype, unless otherwise specified in this International Standard.}
!discussion
(1) We make the setting of a generic unit to be Nonblocking (implicitly or explicitly) to be the trigger for the special rules. This provides the maximum functionality, as even a nonblocking generic can be instantiated with actuals that are blocking (in that case, the instance will allow blocking; that can be detected by declaring the instance nonblocking if that is required).
It does mean that making a generic so that any instance is always nonblocking is more difficult: each formal that has a nonblocking aspect will have to be declared with a Nonblocking aspect. This seems to be a rare case, however, we want the usual case to be easy.
If the generic unit allows blocking (implicitly or explicitly), the nonblocking of the formals do not matter. This is the default for library units, as any other setting would be very incompatible.
This definition has the pleasant effect of by default allowing the use of the formal entities within the generic unit regardless of their nonblocking state. The assume-the-worst rules only come into play when the default nonblocking expression is replaced by a more restrictive expression.
(2) For a subprogram that internally performs dispatching calls on an object of whose tag is determined at the call site, it is essentially impossible to describe the Nonblocking behavior independently of that caller-determined tag. Therefore, we propose to allow a subprogram to indicate what dispatching operations it performs on a given object known to the caller, and then have the caller determine what are the implications with respect to Nonblocking.
(3) In this AI we define 'Nonblocking as attributes on subtypes rather than types, and we allow specifying the corresponding aspects. The alternative of forcing the type Nonblocking aspect specifications to cover all possible subtypes that might ever be declared seemed quite limiting, as far as interesting predicates. It seems clear that some predicates may want to use a blocking operation. [Editor's note: This seems less clear than it does for Global. A blocking predicate is pretty weird.] Forcing the type declaration to worry about this seems painful.
An example of the problem in a predicate could be:
Lock : Some_Protected_Lock_Type;
function Seize return Boolean with Nonblocking => False, Global => synchronized in out Lock is begin Lock.Seize; -- Entry call. return True; end Seize;
function Release return Boolean with Nonblocking => False, Global => synchronized in out Lock is begin Lock.Release; -- Entry call. return True; end Release;
type Wild is range 0 .. 255 with Nonblocking, Global => null, Dynamic_Predicate => (if Wild > 200 then Seize else Release); -- Illegal by this AI.
procedure P with Nonblocking, Global => null is Local : Wild := 255; -- Seizes the global lock. Prior to this AI, -- would be legal since scalar -- types didn't block nor access globals. begin Local := 0; -- Releases the global lock. Also was legal. end P;
If the declaration of Wild wasn't illegal, then P would be legal even though the predicate would potentially block.
We require that non-first subtypes and first-subtypes that are completions have a confirming or True Nonblocking aspect so that a non-first or completing subtype never allows blocking when the original first subtype does not allow it. (This is necessary so that the programmer can be assured that any subtype of a nonblocking first subtype is nonblocking. This is critical in generic units as objects of unknown subtypes could be passed to the unit. If whether assignment is blocking depended upon the subtype, one could never assume any formal type assignment was nonblocking, even when the type is explicitly declared to be nonblocking.)
As part of this change, we have to define the nonblocking value for scalar base types, as these can be used to define subtypes. As there is no reason for a scalar base type to allow blocking (no predicate is possible), we say that the base type is always nonblocking.
=========
The alternative approach of enforcing the nonblocking rules when a predicate is evaluated doesn't work for generic formal types, where the details of any predicate that might apply are unknown.
!corrigendum 9.5(17/3)
Insert after the paragraph:
In addition to the places where Legality Rules normally apply (see 12.3), these rules also apply in the private part of an instance of a generic unit.
the new paragraphs:
Just to force a conflict; the updated text will be found in the conflict file.
!corrigendum 13.1.1(18.1/4)
Replace the paragraph:
If an aspect of a derived type is inherited from an ancestor type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type, unless otherwise specified in this International Standard.
by:
If an aspect of a derived type (or its first subtype) is inherited from an ancestor (sub)type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type (or its first subtype), unless otherwise specified in this International Standard. If an aspect of a nonfirst subtype is inherited from the subtype in the subtype_indication that defines it, and has the value True, the inherited value shall not be overridden to have the value False for the nonfirst subtype, unless otherwise specified in this International Standard.
!ASIS
No ASIS change needed.
!ACATS test
ACATS B- and C-Tests are needed to check that the new rules and capabilities are supported.
!appendix

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


Questions? Ask the ACAA Technical Agent