!standard 13.11.2(3/5) 19-02-22 AI12-0319-1/01 !class Amendment 19-02-22 !status work item 19-02-22 !status received 19-02-22 !priority Low !difficulty Easy !subject Nonblocking for Unchecked_Deallocation is wrong !summary Correct the definition of Unchecked_Deallocation. !problem Unchecked_Deallocation has Nonblocking => True. However, it can be instantiated with a type whose Finalize routine blocks. This allows blocking in a nonblocking subprogram. !proposal (See Summary.) !wording Replace 13.11.2(3/5) with: generic 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; !discussion !ASIS [Not sure. It seems like some new capabilities might be needed, but I didn't check - Editor.] !ACATS test ACATS B- and C-Tests are needed to check that the new capabilities are supported. !appendix From: Randy Brukardt Sent: Friday, February 22, 2019 8:06 PM > The automatic rule only applies to *non-generic* Pure > packages. I forget precisely why, ... I remember now: the Nonblocking has to depend on the generic formals (if any), lest we introduce an incompatibility. But that's not an issue for some formals (elementary types, in particular, which are always nonblocking). Unchecked_Conversion is a special case, in that the nonblocking of the actuals doesn't matter as the (virtual) body won't execute any of the operations that would require them to be followed. Anyway, as with a lot of these things, it's more complex than it appears on the surface. All of this is discussed (somewhat in code) in the !discussion of AI12-0241-1: Non-generic units that are pure are automatically nonblocking as specified in 9.5 (these are noted below). Other units should explicitly have aspect Nonblocking specified if nonblocking is desired. And Unchecked_Deallocation is wrong: if the type Object allows blocking, then Unchecked_Deallocation should, too. Thus, it should be: generic 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; That's because Unchecked_Deallocation finalizes an object, and if the Finalize routine is blocking, then the previous definition would have allowed a blocking operation in a nonblocking subprogram. (Which obviously would be silly.) Moreover, the *body* of Unchecked_Deallocation would be illegal if written in Ada, and since that probably isn't in Ada anyway, probably no one would have noticed it. But allowing blocking in a nonblocking subprogram is bad in any case. Must fix. ****************************************************************