* Default_Storage_Pool
@ 2018-02-21 2:00 sbelmont700
2018-02-22 1:13 ` Default_Storage_Pool Randy Brukardt
0 siblings, 1 reply; 4+ messages in thread
From: sbelmont700 @ 2018-02-21 2:00 UTC (permalink / raw)
Can anyone offer insight into what exactly should happen when Default_Storage_Pool is explicitly set within an extended return statement to a pool within the return object? In particular, consider these shenanigans:
package O is
pool_1 : My_Fancy_Pool
pragma Default_Storage_Pool(pool_1);
type T is limited
record
pool_2 : My_Fancy_Pool
p1 : access Integer;
end record;
function F return T;
end O;
package body O is
function F return T is
begin
return Result : T do
declare
pragma Default_Storage_Pool(Result.pool_2); -- legal?
p2 : access Integer;
begin
p2 := new integer'(42);
Result.p1 := new integer'(43);
end;
end return;
end F;
end O;
GNAT happily accepts this, but based on print lines, it allocates Result.p1 from pool_1 and p2 from some unspecified default pool (i.e. neither pool_1 or pool_2). I wasn't sure what I was expecting; I assumed an error message, but failing that, both to go into result.pool_2, and was surprised to get neither.
Any clarifications are appreciated.
-sb
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Default_Storage_Pool
2018-02-21 2:00 Default_Storage_Pool sbelmont700
@ 2018-02-22 1:13 ` Randy Brukardt
2018-02-22 13:02 ` Default_Storage_Pool sbelmont700
0 siblings, 1 reply; 4+ messages in thread
From: Randy Brukardt @ 2018-02-22 1:13 UTC (permalink / raw)
Default_Storage_Pool only has an effect when an access type is declared (not
when it is used). Thus the allocators for the component of type T should use
Pool_1 regardless of what the Default_Storage_Pool is when the allocator is
written.
But I'd expect the local anonymous access allocator to use Pool_2. I don't
see any reason to use some other pool in this case - 13.11.3(6-6.3/4) is
pretty clear about this, and the rules specifically were designed so that it
would apply to anonymous access types.
Thus, this appears to be a bug, but I also fail to see any use for it (the
anonymous access type having to disappear long before anyone can used the
return value), so I would probably not give it much priority if it was
reported to me. (Of course, a fuller example could cause me to change my
mind on that.)
Randy.
<sbelmont700@gmail.com> wrote in message
news:74cfbf22-7082-4a43-aef9-6a55a049fe61@googlegroups.com...
Can anyone offer insight into what exactly should happen when
Default_Storage_Pool is explicitly set within an extended return statement
to a pool within the return object? In particular, consider these
shenanigans:
package O is
pool_1 : My_Fancy_Pool
pragma Default_Storage_Pool(pool_1);
type T is limited
record
pool_2 : My_Fancy_Pool
p1 : access Integer;
end record;
function F return T;
end O;
package body O is
function F return T is
begin
return Result : T do
declare
pragma Default_Storage_Pool(Result.pool_2); -- legal?
p2 : access Integer;
begin
p2 := new integer'(42);
Result.p1 := new integer'(43);
end;
end return;
end F;
end O;
GNAT happily accepts this, but based on print lines, it allocates Result.p1
from pool_1 and p2 from some unspecified default pool (i.e. neither pool_1
or pool_2). I wasn't sure what I was expecting; I assumed an error message,
but failing that, both to go into result.pool_2, and was surprised to get
neither.
Any clarifications are appreciated.
-sb
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Default_Storage_Pool
2018-02-22 1:13 ` Default_Storage_Pool Randy Brukardt
@ 2018-02-22 13:02 ` sbelmont700
2018-02-23 0:06 ` Default_Storage_Pool Randy Brukardt
0 siblings, 1 reply; 4+ messages in thread
From: sbelmont700 @ 2018-02-22 13:02 UTC (permalink / raw)
On Wednesday, February 21, 2018 at 8:14:03 PM UTC-5, Randy Brukardt wrote:
> Default_Storage_Pool only has an effect when an access type is declared (not
> when it is used). Thus the allocators for the component of type T should use
> Pool_1 regardless of what the Default_Storage_Pool is when the allocator is
> written.
>
> But I'd expect the local anonymous access allocator to use Pool_2. I don't
> see any reason to use some other pool in this case - 13.11.3(6-6.3/4) is
> pretty clear about this, and the rules specifically were designed so that it
> would apply to anonymous access types.
>
> Thus, this appears to be a bug, but I also fail to see any use for it (the
> anonymous access type having to disappear long before anyone can used the
> return value), so I would probably not give it much priority if it was
> reported to me. (Of course, a fuller example could cause me to change my
> mind on that.)
>
> Randy.
Thank you, that was what I thought it should do. I had no legitimate use case, I was just trying to tease out counter-examples to confirm my understanding.
I claim no in-depth comprehension, but because of either subsequent bugs or perhaps 2012 changes to AATs (or perhaps legitimately), GNAT also takes this:
package body O is
janky : access Integer;
function F return T is
begin
return Result : T do
declare
pragma Default_Storage_Pool(Result.pool_2);
p2 : access Integer;
begin
p2 := new integer'(42);
janky := p2; --legal?
end;
end return;
end F;
end;
When does janky become a dangling pointer? Surely if the default pool is local to F (because the entire pool goes away after F ends), never if the default pool is pool_1 (since it has the same lifetime as janky), and 'possibly' if it's contained within Result.pool_2 (since it depends on where the client has creates the result). GNAT accepts all three variations (well, subject to the aforementioned bug presumably making case 3 the same as 1) and raises no exceptions for any of them.
Thank you for the continued explanations
-sb
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Default_Storage_Pool
2018-02-22 13:02 ` Default_Storage_Pool sbelmont700
@ 2018-02-23 0:06 ` Randy Brukardt
0 siblings, 0 replies; 4+ messages in thread
From: Randy Brukardt @ 2018-02-23 0:06 UTC (permalink / raw)
I think the assignment to Janky should raise Program_Error, as it can take
an object of any lifetime that is *longer* than itself.
RM 3.10.2(13.3/4) says this explicitly "...; accessibility checks ensure
that this is never deeper than that of the declaration of the stand-alone
object".
Trying to figure out precisely what check this is talking about is hard,
however (the AARM is supposed to explain that part as it is claimed to
follow from other rules -- but it doesn't). I'm not going to try to work
that out in detail (it's also possible that it is supposed to be illegal).
Randy.
<sbelmont700@gmail.com> wrote in message
news:86a8a87c-72ca-4718-a2a1-11ee07d66fa8@googlegroups.com...
On Wednesday, February 21, 2018 at 8:14:03 PM UTC-5, Randy Brukardt wrote:
> Default_Storage_Pool only has an effect when an access type is declared
> (not
> when it is used). Thus the allocators for the component of type T should
> use
> Pool_1 regardless of what the Default_Storage_Pool is when the allocator
> is
> written.
>
> But I'd expect the local anonymous access allocator to use Pool_2. I don't
> see any reason to use some other pool in this case - 13.11.3(6-6.3/4) is
> pretty clear about this, and the rules specifically were designed so that
> it
> would apply to anonymous access types.
>
> Thus, this appears to be a bug, but I also fail to see any use for it (the
> anonymous access type having to disappear long before anyone can used the
> return value), so I would probably not give it much priority if it was
> reported to me. (Of course, a fuller example could cause me to change my
> mind on that.)
>
> Randy.
Thank you, that was what I thought it should do. I had no legitimate use
case, I was just trying to tease out counter-examples to confirm my
understanding.
I claim no in-depth comprehension, but because of either subsequent bugs or
perhaps 2012 changes to AATs (or perhaps legitimately), GNAT also takes
this:
package body O is
janky : access Integer;
function F return T is
begin
return Result : T do
declare
pragma Default_Storage_Pool(Result.pool_2);
p2 : access Integer;
begin
p2 := new integer'(42);
janky := p2; --legal?
end;
end return;
end F;
end;
When does janky become a dangling pointer? Surely if the default pool is
local to F (because the entire pool goes away after F ends), never if the
default pool is pool_1 (since it has the same lifetime as janky), and
'possibly' if it's contained within Result.pool_2 (since it depends on where
the client has creates the result). GNAT accepts all three variations (well,
subject to the aforementioned bug presumably making case 3 the same as 1)
and raises no exceptions for any of them.
Thank you for the continued explanations
-sb
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-02-23 0:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-21 2:00 Default_Storage_Pool sbelmont700
2018-02-22 1:13 ` Default_Storage_Pool Randy Brukardt
2018-02-22 13:02 ` Default_Storage_Pool sbelmont700
2018-02-23 0:06 ` Default_Storage_Pool Randy Brukardt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox