Version 1.1 of 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);
--
--
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);
--
--
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;
--
--
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