CVS difference for ais/ai-00344.txt
--- ais/ai-00344.txt 2004/10/05 22:49:15 1.10
+++ ais/ai-00344.txt 2004/11/14 06:37:14 1.11
@@ -1,4 +1,4 @@
-!standard 3.09 (04) 04-09-20 AI95-00344/06
+!standard 3.09 (04) 04-11-07 AI95-00344/07
!standard 3.09 (07)
!standard 3.09 (12)
!standard 3.09.01 (03)
@@ -22,7 +22,7 @@
Type extensions are allowed in scopes more nested than their
parent type. Checks are performed on function return, on streaming, and
on allocators to ensure that objects of such a type extension
-do not "escape" to a less nested environment.
+do not escape to a less nested environment.
!problem
@@ -30,7 +30,7 @@
to instantiate certain generics in a local scope, if those generics
internally use extension from some kind of standard library-level type,
such as a storage pool, or a controlled type, or a stream. Such
-restrictions can "snowball," meaning that many generics in a system may
+restrictions can snowball, meaning that many generics in a system may
only permit library-level instantiations.
!proposal
@@ -42,7 +42,7 @@
Add accessibility checks on class-wide allocators, return statements, and
T'Class'Input/Output.
-Require that the type "Tag" include sufficient information to distinguish
+Require that the type Tag include sufficient information to distinguish
all descendants of a given ancestor type.
!wording
@@ -69,8 +69,8 @@
that each descendant of a given type have a unique tag. Hence, for
types declared in shared generic bodies where an ancestor comes from
outside the generic, or for types declared at a deeper level than an
- ancestor, the tag needs to be augmented with some kind of "static
- link," "global display," or "instance descriptor" pointer. This
+ ancestor, the tag needs to be augmented with some kind of static
+ link, global display, or instance descriptor pointer. This
implies that type Tag may need to be two words, the second of which
is normally null, but in these identified special cases needs to
include a static link or equivalent. Within an object of one of
@@ -100,7 +100,7 @@
the identified ancestor. Tag_Error is raised if External is not the
external tag for such a type.
- The function Is_Descendant_At_Same_Level returns True if Descendant tag
+ The function Is_Descendant_At_Same_Level returns True if the Descendant tag
identifies a type that is both a descendant of the type identified
by Ancestor and at the same accessibility level. If not, it returns False.
@@ -140,7 +140,7 @@
... If the designated type of the type of the allocator is class-wide, then
a check is made that the accessibility level of the type identified by
the tag of the value of the qualified_expression is not deeper than that of
- the type of the allocator. Constraint_Error is raised if this check fails.
+ the type of the allocator. Program_Error is raised if this check fails.
Add after 6.5(20):
@@ -180,18 +180,18 @@
For allocators, we disallow creating an object in a collection whose
access type outlives the type identified by the object's tag.
-Similarly, for function return, we disallow returning a classwide object
+Similarly, for function return, we disallow returning a class-wide object
from a function if the tag identifies a type declared at a deeper level than
the function. For similar reasons, we preclude T'Class'Input returning
an object whose tag identifies a type that is declared at a deeper level
than T. For symmetry, and to prevent writing something that cannot
later be meaningfully read, we preclude T'Class'Output writing out an
-item whose tag identifies a type of a deeper level than T.
+item whose tag identifies a type at a deeper level than T.
To implement tag checks needed to ensure that all dynamically tagged
controlling operands come from the same tagged type, we place additional
requirements on the uniqueness of run-time tags. We considered defining
-a separate type called "extended tag." However, this would add user
+a separate type called Extended_Tag. However, this would add user
complexity, and would make existing user tests for tag equality using
the preexisting tag type no longer sufficient to ensure that the
tag check would succeed.
@@ -221,7 +221,7 @@
When a type is extended in a more nested scope, the dispatching operations
may need access to data declared in this nested scope. This will generally
require a static link or global display. However, the caller of such
-a dispatching operation is generally "unaware" that they are calling
+a dispatching operation is generally unaware that they are calling
such a nested dispatching operation. This means that the dispatching
operation must deal with the static link or global display internally,
using information that the caller passes in.
@@ -236,12 +236,12 @@
The type Ada.Tags.Tag would be two words, made up of the pointer to the
dispatch table, as now, plus a second word that would be null for
-the "normal" case, but would hold the static link, global display, or
+the normal case, but would hold the static link, global display, or
instance descriptor for nested type extensions.
To avoid distributed overhead, we would suggest that the tag check
required when there are multiple controlling operands only check the
-"first word" of the now two-word tag at the call site. Then an
+first word of the now two-word tag at the call site. Then an
additional check on the second word needs to be performed *after* the
dispatch only if you arrive in an operation which actually makes use of
such a static link to make sure the static links or displays are the
@@ -253,10 +253,10 @@
would only be incurred when reaching such an operation on a nested type,
meaning it is not a distributed overhead.
-Note that some implementations may create "wrappers" for dispatching
+Note that some implementations may create wrappers for dispatching
operations of nested extensions to fetch the static link/display pointer
-and then call the "real" body with the static link/display in the
-"normal" register or per-task display used for that. This wrapper would
+and then call the real body with the static link/display in the
+normal register or per-task display used for that. This wrapper would
be the natural place to perform this additional check.
!example
@@ -288,32 +288,32 @@
procedure Back is
type TT is new T with null record;
procedure Op (Obj : in out TT);
- O : aliased TT;
+ OTT : aliased TT;
function Get_It return T'Class is
begin
- return T'Class(O); -- (4)
+ return T'Class(OTT); -- (4)
end Get_It;
procedure Op (Obj : in out TT) is
begin
... -- (5)
end Op;
begin
- Do_Something (O); -- (6)
+ Do_Something (OTT); -- (6)
Do_Something (Get_It); -- (7)
end Back;
-Type TT is more nested than it's parent type. The call at (6) is legal and needs
-no run-time check, because Do_Something must necessarily return before O and TT
-cease to exist. The dispatching call at (2) operates normally, so the body of
-the overriding routine at (5) is executed, not the original routine at (1).
-However, the allocator at (3) fails it's accessibility check and raises
+Type TT is more nested than its parent type. The call at (6) is legal and
+needs no run-time check, because Do_Something must necessarily return before
+OTT and TT cease to exist. The dispatching call at (2) operates normally, so
+the body of the overriding routine at (5) is executed, not the original routine
+at (1). However, the allocator at (3) fails its accessibility check and raises
Constraint_Error, as it would create an object that could outlive its type.
The return statement at (4) does not fail an accessibility check, because the
object has the same accessibility as the function. Only a type nested within
a function would fail an accessibility check. This makes sense, since the
-function Get_It can be used in similar ways to the object O, as illustrated by
-the call at (7). It would be odd if they behaved differently.
+function Get_It can be used in similar ways to the object OTT, as illustrated
+by the call at (7). It would be odd if they behaved differently.
!corrigendum 03.09(04)
@@ -364,7 +364,7 @@
the identified ancestor. Tag_Error is raised if External is not the
external tag for such a type.
-The function Is_Descendant_At_Same_Level returns True if Descendant tag
+The function Is_Descendant_At_Same_Level returns True if the Descendant tag
identifies a type that is both a descendant of the type identified
by Ancestor and at the same accessibility level. If not, it returns False.
@@ -423,7 +423,7 @@
designated type of the type of the @fa<allocator> is class-wide, then
a check is made that the accessibility level of the type identified by
the tag of the value of the @fa<qualified_expression> is not deeper than that
-of the type of the allocator. Constraint_Error is raised if this check fails.
+of the type of the allocator. Program_Error is raised if this check fails.
!corrigendum 06.05(20)
@@ -438,31 +438,33 @@
!corrigendum 13.13.2(31)
@drepl
-@xindent<First writes the external tag of Item to Stream (by calling
-String'Output(Tags.External_Tag(Item'Tag) -- see 3.9) and then dispatches to
-the subprogram denoted by the Output attribute of the specific type identified
-by the tag.>
+@xindent<First writes the external tag of @i<Item> to @i<Stream> (by calling
+String'Output(Tags.External_Tag(@i<Item>'Tag) -- see 3.9) and then dispatches
+to the subprogram denoted by the Output attribute of the specific type
+identified by the tag.>
@dby
-@xindent<First writes the external tag of Item to Stream (by calling
-String'Output(Tags.External_Tag(Item'Tag) -- see 3.9) and then dispatches to
-the subprogram denoted by the Output attribute of the specific type identified
-by the tag. Tag_Error is raised if the tag of Item identifies a type declared
-at an accessibility level deeper than that of S.>
+@xindent<First writes the external tag of @i<Item> to @i<Stream> (by calling
+String'Output(Tags.External_Tag(@i<Item>'Tag) -- see 3.9) and then dispatches
+to the subprogram denoted by the Output attribute of the specific type
+identified by the tag. Tag_Error is raised if the tag of Item identifies a
+type declared at an accessibility level deeper than that of S.>
!corrigendum 13.13.2(34)
@drepl
-@xindent<First reads the external tag from Stream and determines the
-corresponding internal tag (by calling Tags.Internal_Tag(String'Input(Stream))
+@xindent<First reads the external tag from @i<Stream> and determines the
+corresponding internal tag (by calling
+Tags.Internal_Tag(String'Input(@i<Stream>))
-- see 3.9) and then dispatches to the subprogram denoted by the Input
attribute of the specific type identified by the internal tag; returns that
result.>
@dby
-@xindent<First reads the external tag from Stream and determines the
+@xindent<First reads the external tag from @i<Stream> and determines the
corresponding internal tag (by calling
-Tags.Descendant_Tag(String'Input(Stream), S'Tag) which might raise Tag_Error --
-see 3.9) and then dispatches to the subprogram denoted by the Input attribute
-of the specific type identified by the internal tag; returns that result.>
+Tags.Descendant_Tag(String'Input(@i<Stream>), S'Tag) which might raise
+Tag_Error -- see 3.9) and then dispatches to the subprogram denoted by the
+Input attribute of the specific type identified by the internal tag; returns
+that result.>
!ACATS test
@@ -2997,6 +2999,53 @@
In any case, I don't think the RM wording is that much harrier
if we only spell out the implementation implications in the AARM
(see version 3 of 3.9(4)).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, November 12, 2004 7:56 PM
+
+AI-251 contains the following:
+
+ If a type declaration names an interface type in an interface_list,
+ then the accessibility level of the declared type shall not be
+ statically deeper than that of the interface type; also, the declared
+ type shall not be declared in a generic body if the interface type is
+ declared outside that body.
+
+This looks suspiciously like 3.9.1(3-4), which was (mostly) repealed by
+AI-344. AI-344 does not mention interface types.
+
+Thinking about interfaces makes my head hurt. Thinking about accessibility
+makes my head hurt. Thinking about both at the same time seems to be beyond
+my threshold of pain. :-) Thus, I really don't know if there is any problem
+here other than the one that we decided to remove with AI-344. Certainly, we
+hardly want to reintroduce the accessibility checks for interfaces that we
+just removed for tagged types.
+
+Presuming we did want to relax the rule, we do need to be careful to keep
+the generic body part of the rule (else we'd have the contract issues with
+shall-be-overridden routines). It seems to me that the new 3.9.1(4) applies
+to anything derived from an interface type (which is tagged by definition),
+including another interface type:
+
+ Within the body of a generic unit, or the body of any of its descendant
+ library units, a tagged type shall not be declared as a descendant
+ of a formal type declared within the formal part of the generic unit.
+
+The formal types clearly include formal interface types; and "a tagged type"
+includes both interfaces and concrete types derived from interfaces.
+
+So, I conclude that the accessibility check paragraph for interfaces
+probably should be deleted. Is there something that I've missed?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, November 12, 2004 9:27 PM
+
+I agree with your analysis. The accessibility check should be
+eliminated.
****************************************************************
Questions? Ask the ACAA Technical Agent