CVS difference for ai12s/ai12-0319-1.txt

Differences between 1.1 and version 1.2
Log of other versions for file ai12s/ai12-0319-1.txt

--- ai12s/ai12-0319-1.txt	2019/02/23 02:06:48	1.1
+++ ai12s/ai12-0319-1.txt	2019/03/06 23:27:02	1.2
@@ -1,35 +1,189 @@
-!standard 13.11.2(3/5)                                  19-02-22  AI12-0319-1/01
+!standard 13.11.2(3/5)                                  19-03-06  AI12-0319-1/02
 !class Amendment 19-02-22
 !status work item 19-02-22
 !status received 19-02-22
 !priority Low
-!difficulty Easy
+!difficulty Medium
 !subject Nonblocking for Unchecked_Deallocation is wrong
-Correct the definition of Unchecked_Deallocation.
+Add the ability for the Nonblocking attribute to be used to specify whether 
+a type's initialization, finalization, and assignments allow blocking.
+Add the Nonblocking attribute for an object, so it can be used to describe
+the storage pool of an access type.
+Correct the definition of Unchecked_Deallocation using these new capabilities.
 Unchecked_Deallocation has Nonblocking => True. However, it can be
 instantiated with a type whose Finalize routine blocks. This allows
-blocking in a nonblocking subprogram.
+blocking in a nonblocking subprogram. Similarly, if the Deallocate
+routine for the storage pool of the access type blocks, we also
+would be allowing blocking in a nonblocking subprogram.
+The original problem led to determining that the definition of Nonblocking
+did not allow specifying whether object default initialization, 
+finalization, or assignment allows blocking, nor whether object allocation, 
+deallocation, and use of the Storage_Size attribute allow blocking.
+We therefore extend existing mechanisms (the Nonblocking attributes) to ensure 
+that we have sufficient contracts to describe those things in generic bodies
+with appropriate "assume-the-worst" rules.
+We also add a rule requiring that the language-defined primitive operations of 
+a controlled type and of a storage pool are nonblocking if the type is 
+We then use these new contracts to properly define Unchecked_Deallocation.
+In discussing this, we also noticed that we need requirements on the standard
+pool(s). Such pools should be nonblocking so that they can be used within
+protected types. It was not intended by Ada 95 for an allocator to be
+potentially blocking, and we don't want to implicitly make such a change now.
-(See Summary.)
+Much of this wording is modifying previously approved Ada 2020 wording;
+the paragraph numbers are as found in Draft 18 of the Standard.
+Modify 9.5(47/5): [Static Semantics, the definition of S'Nonblocking]
+Denotes whether {default initialization, finalization, assignment, }predefined 
+operators{, and} ([and] in the case of access-to-subprogram subtypes) a 
+subprogram designated by a value of 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. 
+Add after 9.5(47/5):
+For a prefix X that denotes an object:
+  Denotes whether the 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. 
+  AARM To Be Honest: In the case when the prefix represents the Storage_Pool 
+  of some type, this is the specific type of the associated pool object, 
+  if known.
+[Author's note: This is explaining how this works for S'Storage_Pool'Nonblocking.
+I don't think the type of the pool of an access type is well-defined; there's 
+no requirement (elsewhere) to keep the static type of the pool object along 
+with the access type. From the perspective of the access type, the pool object
+could be considered to be class-wide (Root_Storage_Pool'Class). It didn't seem
+worth spelling this out somewhere.]
+Add after 9.5(69/5): [Legality Rules]
+For a composite type that is nonblocking:
+    * All component subtypes shall be nonblocking;
+    * For a record type or extension, every call in each default 
+      initialization expression shall call an operation that is nonblocking;
+    * For a controlled type, the Initialize, Finalize, and Adjust (if any) 
+      subprograms shall be nonblocking.
+    AARM Ramification: Default initialization, finalization, and assignment 
+    of elementary types is always nonblocking, so we don't need any rules 
+    for those.
+Add after AARM 9.5(82.e/5): [About assume-the-worst checking in generic bodies]
+   AARM To Be Honest: For checking in P, default initialization, 
+   finalization, and assignment of a composite formal 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.
+   Similarly, for checking in P, the implicit calls associated with an 
+   allocator of an access type A or a use of attribute A'Storage_Size are 
+   considered to call subprograms that have the nonblocking aspect of 
+   A'Storage_Pool'Nonblocking, and this is checked for conformance against 
+   that of P as described above.
+   End To Be Honest.
+   [Author's note: We don't need to include instances of Unchecked_Deallocation
+   in the above note, because that is an actual explicit call with an
+   explicit Nonblocking aspect.]
+Add to 13.11(15):
+If the nominal subtype of the name specified for Storage_Pool is nonblocking, 
+then the primitive Allocate, Deallocate, and Storage_Size subprograms of that 
+type shall be nonblocking. Additionally, if the pool that supports subpools 
+(see 13.11.4), the primitive Default_Subpool_for_Pool, Allocate_From_Subpool,
+and Deallocate_Subpool subprogram shall be nonblocking.
+Add after 13.11(17):
+The type(s) of the standard pool(s), and the primitive Allocate, Deallocate, 
+and Storage_Size subprograms for the standard pool(s) are nonblocking.
+   AARM Reason: We need to specify that the type is nonblocking so that an 
+   instance of  Unchecked_Deallocation is nonblocking if the object type is 
+   nonblocking (as the type is used in the contract). Ada 95 did not declare 
+   standard allocation/deallocation as potentially blocking, so these things 
+   can be used in protected types, and we want that to remain true (with static 
+   checking).
+Add to the end of 13.11(18/4):
+The type of P, and the primitive Allocate, Deallocate, and Storage_Size 
+subprograms of P are nonblocking.
+[This is talking about the implementation-defined pool used when Storage_Size 
+is specified.]
 Replace 13.11.2(3/5) with:
    type Object(<>) is limited private;
    type Name   is access  Object;
 procedure Ada.Unchecked_Deallocation(X : in out Name)
-   with Preelaborate, Nonblocking => Object'Nonblocking, Convention => Intrinsic;
+   with Preelaborate, 
+        Nonblocking => Object'Nonblocking and Name'Storage_Pool'Nonblocking, 
+        Convention => Intrinsic;
+Note that Nonblocking is not used for elementary types. The finalization
+of elementary types has no effect; assignment of elementary types is trivial;
+and default initialization is always of a static value (if at all). Thus, 
+these things are always nonblocking for elementary types.
+We have to ignore Nonblocking for elementary subtypes as whether a subtype is 
+elementary is view-dependent (private type are always composite types); but
+the aspect Nonblocking is type-related (so the private view and full view have
+the same value).
+We only need new rules in the case of checking generic bodies. In all other
+cases, we have rules about including implicit calls when checking Nonblocking,
+and that makes the needed checks (for all of default initialization, 
+controlled finalization, and storage pool usage). In a generic specification, 
+those checks are made by the legality recheck that occurs on instantiation 
+based on the properties of the actual types.
+We make the check on the subprograms for a storage pool when the pool is
+used, so that we don't need to invent a special rule for storage pool type
+declarations that would only be enforced for such types.
+Note that the contract for Unchecked_Deallocate_Subpool always allows blocking.
+Unlike Unchecked_Deallocation, Unchecked_Deallocate_Subpool uses dispatching
+calls rather than generic parameters for deallocation, so neither the 
+designated type(s) nor the pool type are known when it is called. So those
+cannot be described in the contract.

Questions? Ask the ACAA Technical Agent