* Potential Coextension Bug in GNAT
@ 2018-12-20 15:59 Jere
2018-12-20 16:02 ` Jere
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Jere @ 2018-12-20 15:59 UTC (permalink / raw)
I was messing around and trying to learn coextensions and
I came across some counter intuitive functionality. If I
directly initialize one via an aggregate, it works fine.
However, if I initialize through a constructing function,
it seems to treat the access discriminant as a normal access
type and finalizes it at the end of the program instead of
when the object leaves scope. I don't fully understand them
yet and there isn't much on them listed in the RM but one
section (at least according to the index)[1]. That one
section does indicate that initialization via a function
should be valid however, so maybe I am back to I am doing it
wrong or potentially a GNAT bug.
I'm using GNAT 7.1.1
Here is my test program
****************************************************
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Finalization; use Ada.Finalization;
procedure Hello is
type Thing_1 is new Limited_Controlled with null record;
overriding
procedure Finalize(Self : in out Thing_1) is
begin
Put_Line("Finalize Thing_1");
end Finalize;
type Thing_2
(Other : not null access Thing_1)
is limited null record;
procedure Test_Coextension_1 is
The_Thing : Thing_2(new Thing_1);
begin
Put_Line("Coextenson directly initialized");
end Test_Coextension_1;
function Make_Thing_2 return Thing_2 is
begin
return (Other => new Thing_1);
end Make_Thing_2;
procedure Test_Coextension_2 is
The_Thing : Thing_2 := Make_Thing_2;
begin
Put_Line("Coextension initialized through build in place");
end Test_Coextension_2;
begin
Test_Coextension_1;
Test_Coextension_2;
Put_Line("Test Finished");
end Hello;
****************************************************
Any thoughts?
[1] Ada 2012 tc1 RM 3.10.2(14.4/3) - http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-10-2.html#I2301
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 15:59 Potential Coextension Bug in GNAT Jere
@ 2018-12-20 16:02 ` Jere
2018-12-20 16:56 ` Simon Wright
2018-12-20 17:58 ` Simon Wright
2 siblings, 0 replies; 8+ messages in thread
From: Jere @ 2018-12-20 16:02 UTC (permalink / raw)
On Thursday, December 20, 2018 at 10:59:02 AM UTC-5, Jere wrote:
> I was messing around and trying to learn coextensions and
> I came across some counter intuitive functionality. If I
> directly initialize one via an aggregate, it works fine.
> However, if I initialize through a constructing function,
> it seems to treat the access discriminant as a normal access
> type and finalizes it at the end of the program instead of
> when the object leaves scope. I don't fully understand them
> yet and there isn't much on them listed in the RM but one
> section (at least according to the index)[1]. That one
> section does indicate that initialization via a function
> should be valid however, so maybe I am back to I am doing it
> wrong or potentially a GNAT bug.
>
> I'm using GNAT 7.1.1
>
> Here is my test program
>
> ****************************************************
>
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Finalization; use Ada.Finalization;
>
> procedure Hello is
>
> type Thing_1 is new Limited_Controlled with null record;
>
> overriding
> procedure Finalize(Self : in out Thing_1) is
> begin
> Put_Line("Finalize Thing_1");
> end Finalize;
>
> type Thing_2
> (Other : not null access Thing_1)
> is limited null record;
>
> procedure Test_Coextension_1 is
> The_Thing : Thing_2(new Thing_1);
> begin
> Put_Line("Coextenson directly initialized");
> end Test_Coextension_1;
>
> function Make_Thing_2 return Thing_2 is
> begin
> return (Other => new Thing_1);
> end Make_Thing_2;
>
> procedure Test_Coextension_2 is
> The_Thing : Thing_2 := Make_Thing_2;
> begin
> Put_Line("Coextension initialized through build in place");
> end Test_Coextension_2;
>
> begin
> Test_Coextension_1;
> Test_Coextension_2;
> Put_Line("Test Finished");
> end Hello;
>
> ****************************************************
>
> Any thoughts?
>
> [1] Ada 2012 tc1 RM 3.10.2(14.4/3) - http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-10-2.html#I2301
Sorry, forgot to put the program output:
**************************************************
$gnatmake -o hello *.adb
gcc -c hello.adb
gnatbind -x hello.ali
gnatlink hello.ali -o hello
$hello
Coextenson directly initialized
Finalize Thing_1
Coextension initialized through build in place
Test Finished
Finalize Thing_1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 15:59 Potential Coextension Bug in GNAT Jere
2018-12-20 16:02 ` Jere
@ 2018-12-20 16:56 ` Simon Wright
2018-12-21 2:16 ` Randy Brukardt
2018-12-21 11:24 ` Jere
2018-12-20 17:58 ` Simon Wright
2 siblings, 2 replies; 8+ messages in thread
From: Simon Wright @ 2018-12-20 16:56 UTC (permalink / raw)
Jere <jhb.chat@gmail.com> writes:
> I was messing around and trying to learn coextensions and
> I came across some counter intuitive functionality. If I
> directly initialize one via an aggregate, it works fine.
> However, if I initialize through a constructing function,
> it seems to treat the access discriminant as a normal access
> type and finalizes it at the end of the program instead of
> when the object leaves scope.
Compiling with -gnatwa I see "warning: coextension will not be finalized
when its associated owner is deallocated or finalized", so GNAT clearly
meant to do it!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 15:59 Potential Coextension Bug in GNAT Jere
2018-12-20 16:02 ` Jere
2018-12-20 16:56 ` Simon Wright
@ 2018-12-20 17:58 ` Simon Wright
2018-12-21 2:25 ` Randy Brukardt
2 siblings, 1 reply; 8+ messages in thread
From: Simon Wright @ 2018-12-20 17:58 UTC (permalink / raw)
Jere <jhb.chat@gmail.com> writes:
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Finalization; use Ada.Finalization;
>
> procedure Hello is
>
> type Thing_1 is new Limited_Controlled with null record;
>
> overriding
> procedure Finalize(Self : in out Thing_1) is
> begin
> Put_Line("Finalize Thing_1");
> end Finalize;
>
> type Thing_2
> (Other : not null access Thing_1)
> is limited null record;
>
> procedure Test_Coextension_1 is
> The_Thing : Thing_2(new Thing_1);
This is a case of 14.1/3, an allocator used to define the discriminant
of an object,
> begin
> Put_Line("Coextenson directly initialized");
> end Test_Coextension_1;
>
> function Make_Thing_2 return Thing_2 is
> begin
> return (Other => new Thing_1);
I think GNAT thinks this is a case of 14.2/3, an allocator used to
define the constraint in a subtype_indication, though I'm hard put to it
to see the difference from the first case.
> end Make_Thing_2;
>
> procedure Test_Coextension_2 is
> The_Thing : Thing_2 := Make_Thing_2;
> begin
> Put_Line("Coextension initialized through build in place");
> end Test_Coextension_2;
>
> begin
> Test_Coextension_1;
> Test_Coextension_2;
> Put_Line("Test Finished");
> end Hello;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 16:56 ` Simon Wright
@ 2018-12-21 2:16 ` Randy Brukardt
2018-12-21 11:24 ` Jere
1 sibling, 0 replies; 8+ messages in thread
From: Randy Brukardt @ 2018-12-21 2:16 UTC (permalink / raw)
"Simon Wright" <simon@pushface.org> wrote in message
news:lyefacdtn8.fsf@pushface.org...
> Jere <jhb.chat@gmail.com> writes:
>
>> I was messing around and trying to learn coextensions and
>> I came across some counter intuitive functionality. If I
>> directly initialize one via an aggregate, it works fine.
>> However, if I initialize through a constructing function,
>> it seems to treat the access discriminant as a normal access
>> type and finalizes it at the end of the program instead of
>> when the object leaves scope.
>
> Compiling with -gnatwa I see "warning: coextension will not be finalized
> when its associated owner is deallocated or finalized", so GNAT clearly
> meant to do it!
This message is nonsense, because a coextension is effectively part of the
associated object. What they presumably mean to say is that the declaration
in question is *not* a coextension, thus it will not be finalized with the
owner.
Randy.
P.S. I hate coextensions. One of the least necessary complications of Ada.
(Janus/Ada gives you a "feature not implemented" message if you try to
create one.)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 17:58 ` Simon Wright
@ 2018-12-21 2:25 ` Randy Brukardt
2018-12-21 11:32 ` Jere
0 siblings, 1 reply; 8+ messages in thread
From: Randy Brukardt @ 2018-12-21 2:25 UTC (permalink / raw)
"Simon Wright" <simon@pushface.org> wrote in message
news:lya7l0dqrw.fsf@pushface.org...
> Jere <jhb.chat@gmail.com> writes:
>
>> with Ada.Text_IO; use Ada.Text_IO;
>> with Ada.Finalization; use Ada.Finalization;
>>
>> procedure Hello is
>>
>> type Thing_1 is new Limited_Controlled with null record;
>>
>> overriding
>> procedure Finalize(Self : in out Thing_1) is
>> begin
>> Put_Line("Finalize Thing_1");
>> end Finalize;
>>
>> type Thing_2
>> (Other : not null access Thing_1)
>> is limited null record;
>>
>> procedure Test_Coextension_1 is
>> The_Thing : Thing_2(new Thing_1);
>
> This is a case of 14.1/3, an allocator used to define the discriminant
> of an object,
Right, because 14.2/3 says "subtype_indication in any other context",
meaning that 14.1/3 applies in an object declaration.
>> begin
>> Put_Line("Coextenson directly initialized");
>> end Test_Coextension_1;
>>
>> function Make_Thing_2 return Thing_2 is
>> begin
>> return (Other => new Thing_1);
>
> I think GNAT thinks this is a case of 14.2/3, an allocator used to
> define the constraint in a subtype_indication, though I'm hard put to it
> to see the difference from the first case.
That doesn't make any sense, since 14.2/3 is talking about a syntactic
subtype_indication, and there is no subtype_indication in the above
aggregate. 14.2/3 would be talking about a case like:
function Make_Thing_3 return Thing_2 is
subtype Silly is Thing_2 (new Thing_1);
Some_Thing : Silly;
begin
return Some_Thing;
end Make_Thing_3;
This function does NOT define a coextension.
So it does look like a GNAT bug. There is the possibility that they are
associating the discriminant with the temporary object associated with the
allocator, and not the return object, but that seems unnecessarily
unfriendly of an interpretation. And it would be wrong for any type that
requires built-in-place (I didn't look at the actual declaration of the
type). I think the rules are supposed to prevent that interpretation, but
whether they really do is an interesting question that I have no interest in
exploring.
Randy.
P.S. Did I mention I hate coextensions?? They provide an endless opportunity
to puzzle over rules that really don't matter in the end (and most likely
aren't quite right). I suppose they've helped me keep employed running the
ARG. :-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-20 16:56 ` Simon Wright
2018-12-21 2:16 ` Randy Brukardt
@ 2018-12-21 11:24 ` Jere
1 sibling, 0 replies; 8+ messages in thread
From: Jere @ 2018-12-21 11:24 UTC (permalink / raw)
On Thursday, December 20, 2018 at 11:56:13 AM UTC-5, Simon Wright wrote:
> Jere writes:
>
> > I was messing around and trying to learn coextensions and
> > I came across some counter intuitive functionality. If I
> > directly initialize one via an aggregate, it works fine.
> > However, if I initialize through a constructing function,
> > it seems to treat the access discriminant as a normal access
> > type and finalizes it at the end of the program instead of
> > when the object leaves scope.
>
> Compiling with -gnatwa I see "warning: coextension will not be finalized
> when its associated owner is deallocated or finalized", so GNAT clearly
> meant to do it!
that's pretty interesting. The compiler I was using did not give
that warning when compiled with -gnatwa. You're right, that definitely
looks intentional.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Potential Coextension Bug in GNAT
2018-12-21 2:25 ` Randy Brukardt
@ 2018-12-21 11:32 ` Jere
0 siblings, 0 replies; 8+ messages in thread
From: Jere @ 2018-12-21 11:32 UTC (permalink / raw)
On Thursday, December 20, 2018 at 9:25:42 PM UTC-5, Randy Brukardt wrote:
> <SNIPPED>
>
> So it does look like a GNAT bug. There is the possibility that they are
> associating the discriminant with the temporary object associated with the
> allocator, and not the return object, but that seems unnecessarily
> unfriendly of an interpretation. And it would be wrong for any type that
> requires built-in-place (I didn't look at the actual declaration of the
> type). I think the rules are supposed to prevent that interpretation, but
> whether they really do is an interesting question that I have no interest in
> exploring.
Ok, that makes me feel better. I was concerned I was misinterpreting the
RM about the function return (for build in place). The type was limited,
which I believe requires it to be build in place.
>
> P.S. Did I mention I hate coextensions?? They provide an endless opportunity
> to puzzle over rules that really don't matter in the end (and most likely
> aren't quite right). I suppose they've helped me keep employed running the
> ARG. :-)
Overall, they aren't super useful and are not very intuitive. I don't know
the history for why they were added to the language though. I will say
they do provide one thing to Ada that no other feature in the language
seems to, so there is that. But I don't know the cost versus reward of them.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-12-21 11:32 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-20 15:59 Potential Coextension Bug in GNAT Jere
2018-12-20 16:02 ` Jere
2018-12-20 16:56 ` Simon Wright
2018-12-21 2:16 ` Randy Brukardt
2018-12-21 11:24 ` Jere
2018-12-20 17:58 ` Simon Wright
2018-12-21 2:25 ` Randy Brukardt
2018-12-21 11:32 ` Jere
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox