comp.lang.ada
 help / color / mirror / Atom feed
* 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