!standard A.4.7(28) 10-10-21 AI05-0224-1/00 !standard A.4.8(28/2) !class binding interpretation 10-10-21 !status work item 10-10-21 !status received 10-06-07 !priority Low !difficulty Medium !qualifier Error !subject No_Task_Allocators and classwide returns !summary !question How does the No_Task_Allocators restriction interact with a function that returns Some_Limited_Type'Class, as in type Ref is access Some_Limited_Type'Class; type T is new Some_Limited_Type with record Tsk : Some_Task_Type; end record; function F return Some_Limited_Type'Class is begin return X : T; end F; Ptr : Ref := new Some_Limited_Type'Class'(F); !wording !discussion !ACATS Test !appendix From: Steve Baird Sent: Monday, June 7, 2010 2:20 PM How does the No_Task_Allocators restriction interact with a function that returns Some_Limited_Type'Class, as in type Ref is access Some_Limited_Type'Class; type T is new Some_Limited_Type with record Tsk : Some_Task_Type; end record; function F return Some_Limited_Type'Class is begin return X : T; end F; Ptr : Ref := new Some_Limited_Type'Class'(F); Does this restriction need a dynamic rule to deal with the cases like this? **************************************************************** From: Randy Brukardt Sent: Monday, June 7, 2010 2:34 PM I don't think it *has* to have a dynamic rule, since this clearly (!) can be checked at link-time, and restrictions are technically post-compilation checks anyway. The better question in my view is whether we intend implementations to do the link-time handstands this requires (and if so, why). (You need to do the check at link-time as the body of F probably is separately compiled from the allocator, and you need to know about both in order to show a problem.) **************************************************************** From: Gary Dismukes Sent: Monday, June 7, 2010 3:13 PM > I don't think it *has* to have a dynamic rule, since this clearly (!) > can be checked at link-time, and restrictions are technically > post-compilation checks anyway. But there are cases that might not be checkable at link time, such as when the function has multiple returns, only some of which have task parts. **************************************************************** From: Randy Brukardt Sent: Monday, June 7, 2010 3:30 PM > But there are cases that might not be checkable at link time, such as > when the function has multiple returns, only some of which have task > parts. I don't think that people who want to enforce this particular restriction (which is intended to simplify the runtime system) care whether there is *actually* a task allocator; I think they only care that there *might be* a task allocator. After all, you could put if False then around the allocator itself -- but that would still violate the restriction. So it makes sense to me that any possibility of returning a task from the function would be flagged if the function is subsequently used in an allocator. Specifically, I don't see much difference between: if False then Ptr := new Some_Type_Containing_a_Task; end if; and Ptr := new Root'Class (F); function F return Root'Class is begin if False then return Obj:T; else return Obj2:S; end if; end F; (where type T has a task and type S does not). And the point that I recalled above (that the restriction is intended to simplify the runtime system) implies that a runtime check is inappropriate. A more interesting question is what do implementations currently do in this case? We ought to follow practice if there is in fact any to follow. **************************************************************** From: Steve Baird Sent: Monday, June 7, 2010 3:34 PM > But there are cases that might not be checkable at link time, such as > when the function has multiple returns, only some of which have task parts. Right. Other cases include dispatching calls and calls through access-to-function values. This is not, in general, checkable at link time. **************************************************************** From: Steve Baird Sent: Monday, June 7, 2010 3:39 PM I think that if you want to check this restriction completely without runtime checks, then you would have to be conservative and reject some allocators (e.g., the one in my example) on the grounds that the type of the allocated object *might* have a task part. **************************************************************** From: Randy Brukardt Sent: Monday, June 7, 2010 6:51 PM Right. The current check is conservative anyway: there is no guarantee that the allocator of a task will be executed, but the program is rejected simply by its existence. The only question I would have is "how conservative"? I would think that banning allocators of all limited class-wide types would be going too far, so some sort of post-compilation check would be needed. Perhaps simply banning allocators of a limited class-wide type where any extension has a task component would be adequate (that would be somewhat easier to implement than trying to figure out for every function whether it could return a task). In any case, I think we'll need some additional wording for this rule (whatever we decide). ****************************************************************