Version 1.1 of ais/ai-00279.txt

Unformatted version of ais/ai-00279.txt version 1.1
Other versions for file ais/ai-00279.txt

!standard 13.13.02 (34)          01-12-21 AI95-00279/01
!class binding interpretation 01-12-21
!status work item 01-12-21
!status received 01-11-08
!qualifier Omission
!priority Medium
!difficulty Medium
!subject Tag read by of T'Class'Input
!summary
If the tag identified by T'Class'Input identifies a type:
-- that is the tag of some type not covered by T'Class, Constraint_Error
is raised;
-- that is the tag of an abstract type, Constraint_Error is raised; -- that is the tag of a type whose freezing point has not yet been
elaborated, a bounded error occurs - either the call works normally, or Program_Error is raised.
!question
T'Class'Input reads in a string, maps it to a tag by calling Tags.Internal_Tag, and dispatches accordingly.
What happens if the the call to Tags.Internal_Tag yields either
a) the tag of some type not covered by T'Class
or
b) the tag of an abstract type
or
c) the tag of a type whose freezing point has not
yet been elaborated (e.g. a type with a not-yet-elaborated component subtype)?
!recommendation
(See summary.)
!wording
(See corrigendum.)
!discussion
The exact wording of 13.13.2(34) is "...dispatches to the subprogram denoted by the Input attribute of the specific type identified by the internal tag; returns that result.". Reading this strictly, we would expect the appropriate 'Input to be called (by dispatching), followed by a conversion to the return type. That is, somewhere this is code like:
return T'Class(Call_by_Tag (Tags.Internal_Tag(...), 'Input(Stream));
(where Call_by_Tag is a magic routine that dispatches to the appropriate routine identified by the tag in its first parameter).
If the tag dispatched on is not covered by T, then this final conversion would raise Constraint_Error. Therefore, we simply confirm the existing language by saying that Constraint_Error is raised in this case. However, there is no benefit in insisting that the call to the 'Input routine is actually made, so we just clarify this to just say that Constraint_Error is raised.
If the tag dispatched on is an abstract type, then the appropriate 'Input is called. The language says that this 'Input operation exists, but that it cannot be called because it is not available. (See AI-195 for the definition of "available".)
We certainly cannot allow a non-available routine to be dispatched to. Thus, there must be a runtime check for this case, and an exception raised. We choose to raise Constraint_Error to be similar to the previous case.
If the tag dispatched on is for a type that has not yet been frozen, we could have an access-before-elaboration problem. If the approriate 'Input is user-defined, the body of the 'Input routine could not yet be frozen (as a body is a freezing point), so that any normal call to this routine should raise Program_Error. For the default implementation for 'Input, it is unclear whether the overhead of checking for access-before-elaboration is worthwhile. This overhead would be required on all uses of the Input attribute, in order to handle a very unlikely case. Therefore, we define this case to be a bounded error, requiring either the attribute to work as defined by the RM, or raising Program_Error. This allows implementations to only check for access-before-elaboration in default implementations of Input where there would might be a problem if the routine is called before the type is frozen.
!corrigendum 13.13.02(34)
Replace the paragraph:
First reads the external tag from Stream and determines the corresponding internal tag (by calling Tags.Internal_Tag(String'Input(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.
by:
First reads the external tag from Stream and determines the corresponding internal tag (by calling Tags.Internal_Tag(String'Input(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.
[Note: I didn't provide wording, since I'm uncertain that I have the "correct" answer here. - ED]
!ACATS test
A C-Test could be written to test these cases.
!appendix

From: Steve Baird
Date: Thursday, November 08, 2001   8:54 PM

T'Class'Input reads in a string, maps it to a tag,
and dispatches accordingly.

What happens if the the call to Tags.Internal_Tag yields either
   a) the tag of some type not covered by T'Class
or
   b) the tag of an abstract type
or
   c) the tag of a type whose freezing point has not
      yet been elaborated (e.g. a type with a
      not-yet-elaborated component subtype).
?

Is this erroneous? Must Program_Error be raised?

****************************************************************

From: Randy Brukardt
Date: Wednesday, November 14, 2001   7:26 PM

> T'Class'Input reads in a string, maps it to a tag,
> and dispatches accordingly.
>
> What happens if the the call to Tags.Internal_Tag
> yields either
>    a) the tag of some type not covered by T'Class

The exact wording of 13.13.2(34) is "...dispatches to the subprogram denoted
by the Input attribute of the specific type identified by the internal tag;
returns that result.". Reading this strictly, I would expect the appropriate
'Input to be called, then Constraint_Error to be raised because it isn't
possible to convert the result to the return type. That is, somewhere this
is code like:

    return T'Class(Call_by_Tag (Tags.Internal_Tag(...), 'Input(....));

But we may want to change that. Note that I already pointed out that this
isn't clearly defined in my (old) write-up of AI-260 ('Tag_Read).

> or
>    b) the tag of an abstract type

Here again, it is clear what happens: if the abstract type is Abstr,
Abstr'Input is called. Note that Abstr'Input is defined. AI-195 says that it
exists, but cannot be called, because it is not "available".

So we seem to have a case where a routine that is not "available" can be
dispatched to.

> or
>    c) the tag of a type whose freezing point has not
>       yet been elaborated (e.g. a type with a
>       not-yet-elaborated component subtype).
> ?

Sigh. If the 'Input is user-defined, it couldn't have been elaborated yet,
so Program_Error must be raised. But are predefined 'Input elaborated? (I
hope not - we don't need the overhead). If not, then we have an ugly and
highly unlikely case. Probably it is best to just declare it erroneous, as
any check is going to be expensive and distributed.

> Is this erroneous? Must Program_Error be raised?

The answers to these questions probably are all different. I think (a)
should be Constraint_Error, and in any case, should be the same as whatever
AI-260 says happens for 'Tag_Read.

(b) is a special case which will have to raise some exception; probably
Constraint_Error or Program_Error.

(c) seems best to be erroneous, because the check is going to occur on every
use of a stream attribute, and this is very rare. But when it can be
checked, it should raise Program_Error (as it is an
access-before-elaboration error).

In any case, I don't think this new issue should be used to prevent AI-195
from being completed. That AI already has too many issues in it, and if we
stick every stream issue that we discover (and I expect our grandchildren
will still be discovering problems with streams) into it, we'll never finish
it and fix many important stream problems.

Besides, issue (a) was already discussed in the context of AI-260, and it
would make just as much sense to put this issue there. Or open a new AI.

****************************************************************

Questions? Ask the ACAA Technical Agent