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

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

!standard 13.1(15.2/2)          09-11-03 AI05-0192-1/01
!standard 13.13.2(36/2)
!standard 13.13.2(50/2)
!class ramification 09-11-03
!status work item 09-11-03
!status received 09-05-11
!priority Low
!difficulty Easy
!qualifier Omission
!subject Behavior of 'Input for types with constrained first subtypes
!summary
The result of 'Input is constrained if the type is composite and the first subtype is constrained.
!question
Consider:
type T1 (D : Natural) is ... ; type T2 is new T1 (123);
X : T1 := T1 (T2'Input (...));
Is the result of T2'Input constrained? If so, it must raise Constraint_Error is the discriminant is not 123.
13.13.2(50/2) says that it is, but 13.13.2(25/2) says that 13.1(15.2/2) applies - the aspect is derived, which would make the subtype unconstrained.
Which interpretation is correct?
Another question occurs presuming that the attribute is constrained. Is an implementation required, allowed, or forbidden to perform the constraint check as soon as the discriminant value is read from the stream? (Yes.) Would it be legal to defer the check until the end? (Yes.)
!recommendation
(See summary.)
!discussion
In researching this question, your editor looked at the reason 13.1(15.2/2) exists. AI95-00444-1 says that it was added to "specify the parameter types" of inherited attributes. Why this is needed is not clear; 13.13.2(50/2) defines appropriate types.
I was told to write a ramification, but given that this contradicts an intentional ARG decision, I think that is inappropriate. It seems to me that the rule 13.1(15.2/2) is just plain wrong, and needs to be changed. The reason is that if the attribute is available but the fact that it is inherited isn't visible (as could happen for a private type/full view combination), we might end up with different constraints on the attribute depending on its view (even though the implementation cannot vary by view). That can't possibly be good.
But I'm not sure if there would be some problems if the rule at 13.1(15.2/2) was dropped. Would the inherited subprogram assume the wrong constraints?
So it is important to find out whether Pascal, Tucker, and Randy were insane at the time of AI95-00444-1. I recommend that we simply give this AI back to Steve Baird to do the needed research.
On the second question, 13.13.2(36/2) applies, and is very clear. It says "at which point" the checks are made is unspecified. So long as the exception raised by the checks is handled by the proper handler (which is required by the imfamous 11.6), the implementation is correct.
One could argue that the wording of 13.13.2(36/2) is so vague that almost anything is allowed. But that is the intent: the wording specifically says that the number of stream elements read cannot be predicted. So the intent is clearly that pretty much anything sensible goes.
We could add an AARM note to the effect that we meant what we said, but that seems silly.
!ACATS Test
!appendix

From: Steve Baird
Sent: Monday, May 11, 2009  4:04 PM

A question was raised at AdaCore about the Input attribute of an untagged derived type with a constrained first subtype, as in

    type T1 (D : Natural) is ... ;
    type T2 is new T1 (123);

    X : T1 := T1 (T2'Input (...));

Question #1:
   In the above example, should Constraint_Error be raised if the
   discriminant value read from the stream is not equal to 123?

The RM appears to contradict itself with respect to the definition of the result subtype of T2'Input.

The more specific (and therefore presumably correct) applicable passage is 13.13.2(50/2), which says

     In the parameter_and_result_profiles for the stream-oriented
     attributes, the subtype of the Item parameter is the base subtype of
     T if T is a scalar type, and the first subtype otherwise. The same
     rule applies to the result of the Input attribute.

This suggests that the result subtype is constrained and that therefore Constraint_Error should be raised. Note that the changes
AI05-007 makes in this area have no effect in the non-scalar case.

The opposing argument is based on the following chain:
    13.13.2(25/2): "For an untagged derived type, the Output
      (resp. Input) attribute is inherited according to the rules
      given in 13.1 ..."
    13.1(15.2/2): "When an aspect that is a subprogram is inherited, the
      derived type inherits the aspect in the same way that a derived
      type inherits a user-defined primitive subprogram from its parent
     (see 3.4)."
    3.4(19): "If the declaration of the derived type has neither a
      known_discriminant_part nor a record_extension_part, then the
      corresponding subtype has a constraint that corresponds (as defined
      above for the first subtype of the derived type) to that of the
      given subtype."

This suggests that the result subtype is unconstrained. I think an AARM note resolving this apparent contradiction is all that is needed.

Question #2:
   Assuming that Constraint_Error is to be raised, is an implementation
   required, allowed, or forbidden to perform the constraint
   check as soon as the discriminant value is read from the stream?
   Would it be legal to defer the check until the end, effectively
   implementing T2'Input as something like

      function T2'Input (...) return T2 is
      begin
          return T2 (T1'Input (...));
      end T2'Input;

   ? How about an early check something like

      function T2'Input (...) return T2 is
      begin
          if Integer'Input (...) /= 123 then
               raise Constraint_Error;
          end if;
          declare
              Result : T2;
          begin
              T2'Read (Result);
              return Result;
          end;
      end T2'Input;
    ? Does any of this depend on 11.6 ?

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

From: Brad Moore
Sent: Tuesday, May 12, 2009  11:19 PM

< Question #2:
<   Assuming that Constraint_Error is to be raised, is an implementation
<   required, allowed, or forbidden to perform the constraint
<   check as soon as the discriminant value is read from the stream?
<   Would it be legal to defer the check until the end, ... ? 

I would say that 13.13.2(36/2) seems to provide the answer to this question. It states; "It is unspecified at which point and in which order these checks are  performed. In particular, if Constraint_Error is raised due to the  failure of one of these check
s, it is unspecified how many stream  elements have been read from the stream."

As to the first question, I would think people would expect the constraint error to be raised.

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

From: Steve Baird
Sent: Wednesday, May 13, 2009  5:36 PM

> I would say that 13.13.2(36/2) seems to provide the answer to this 
> question. It states; "It is unspecified at which point and in which 
> order these checks are  performed. In particular, if Constraint_Error 
> is raised due to the  failure of one of these checks, it is 
> unspecified how many stream  elements have been read from the stream."

I tend to agree with you.
The question here is whether the freedom you described extends across a call boundary. In 13.1(15.2/2), presumably the phrase "in the same way" means that 3.4(27/2) defines the dynamic semantics of a call to

   My_Untagged_Derived_Type'Inherited_Streaming_Attribute.

> As to the first question, I would think people would expect the 
> constraint error to be raised.

Again, I agree with you.
I still think there is enough of an apparent contradiction to justify an AARM note.

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

Questions? Ask the ACAA Technical Agent