Version 1.1 of ai05s/ai05-0234-1.txt

Unformatted version of ai05s/ai05-0234-1.txt version 1.1
Other versions for file ai05s/ai05-0234-1.txt

!standard 7.6(17.1/3)          10-11-15 AI05-0234-1/00
!class binding interpretation 10-11-15
!status work item 10-11-15
!status received 10-10-31
!priority Low
!difficulty Hard
!qualifier Omission
!subject Hole in AI05-0051-1
!summary
!question
There remains a problem not covered by AI05-0051-1. Consider the following:
with Text_IO; procedure Cw_Alloc is
type Root is tagged null record; type Ref is access Root'Class;
type Extension (Discrim : access Integer) is new Root with null record;
function Bad_News return Ref is Local_Int : aliased Integer := 123; Local_Ext : aliased Extension (Discrim => Local_Int'access); type Local_Ref is access all Root'Class; for Local_Ref'Storage_Size use 0; Local_Ptr : Local_Ref := Local_Ext'access; begin return new Root'Class'(Local_Ptr.all); -- allocator should fail, but RM 4.8(10) doesn't capture this -- correctly (with or without the changes of AI05-0051) end Bad_News;
Ptr : Ref := Bad_News;
procedure Do_Nothing is begin null; end Do_Nothing; begin Text_IO.Put_Line ("*** Test failed - an exception should have been raised");
Text_IO.Put_Line (" Ptr.Discrim.all =" & Integer'Image (Extension (Ptr.all).Discrim.all));
Do_Nothing;
Text_IO.Put_Line (" Ptr.Discrim.all =" & Integer'Image (Extension (Ptr.all).Discrim.all)); end Cw_Alloc;
!wording
!discussion
!ACATS Test
From: Steve Baird Sent: Tuesday, November 2, 2010 8:08 PM
At the recent ARG meeting in Fairfax, we approved AI05-0051 with the understanding that there remained a known dangling-reference problem involving allocators which still needs to be addressed.
The following example illustrates the problem:
with Text_IO; procedure Cw_Alloc is
type Root is tagged null record; type Ref is access Root'Class;
type Extension (Discrim : access Integer) is new Root with null record;
function Bad_News return Ref is Local_Int : aliased Integer := 123; Local_Ext : aliased Extension (Discrim => Local_Int'access); type Local_Ref is access all Root'Class; for Local_Ref'Storage_Size use 0; Local_Ptr : Local_Ref := Local_Ext'access; begin return new Root'Class'(Local_Ptr.all); -- allocator should fail, but RM 4.8(10) doesn't capture this -- correctly (with or without the changes of AI05-0051) end Bad_News;
Ptr : Ref := Bad_News;
procedure Do_Nothing is begin null; end Do_Nothing; begin Text_IO.Put_Line ("*** Test failed - an exception should have been raised");
Text_IO.Put_Line (" Ptr.Discrim.all =" & Integer'Image (Extension (Ptr.all).Discrim.all));
Do_Nothing;
Text_IO.Put_Line (" Ptr.Discrim.all =" & Integer'Image (Extension (Ptr.all).Discrim.all)); end Cw_Alloc;
Using the Gnat compiler (version 6.3.2) on x86_64 Linux, the following command
gnatmake cw_alloc.adb -gnat05
produces an executable whose output is
*** Test failed - an exception should have been raised
Ptr.Discrim.all = 123 Ptr.Discrim.all = 0
Note that the call to Do_Nothing caused the value of Ptr.Discrim.all to change from 123 to 0.
This is not a compiler bug - the Gnat compiler is, as far as I know, correctly implementing all of the checks that the language definition requires for this example.
The language definition is missing a check in this case.
****************************************************************
From: Tucker Taft Sent: Tuesday, November 2, 2010 9:36 PM
Do we know whether the same problem might exist for the return statement? I think there is some possibility of that.
****************************************************************
From: Steve Baird Sent: Tuesday, November 2, 2010 9:50 PM
I think you are right; good point. I'll try to flesh this one out tomorrow, but I see no reason that we won't run into the same problem.
****************************************************************
From: Steve Baird Sent: Friday, November 5, 2010 12:33 PM
You are right. Consider the following variation on the original example:
with Text_IO; procedure Cw_Return is
type Root is tagged null record; type Extension (Discrim : access Integer) is new Root with null record;
function Bad_News return Root'Class is Local_Int : aliased Integer := 123; Local_Ext : aliased Extension (Discrim => Local_Int'access); type Local_Ref is access all Root'Class; for Local_Ref'Storage_Size use 0; Local_Ptr : Local_Ref := Local_Ext'access; begin return Local_Ptr.all; -- return should fail, but RM 6.5(21) doesn't capture this -- correctly (with or without the changes of AI05-0051) end Bad_News;
Obj : Root'Class := Bad_News;
begin Text_IO.Put_Line ("*** Test failed - an exception should have been raised");
Text_IO.Put_Line (" Obj.Discrim.all =" & Integer'Image (Extension (Obj).Discrim.all)); end Cw_Return;
Compiled and executed as described previously, resulting output is
*** Test failed - an exception should have been raised
Obj.Discrim.all = 32767
As before, this is not a compiler bug; this is a language definition problem.
****************************************************************

Questions? Ask the ACAA Technical Agent